Browse Source

protecting openal against multithreaded access too

David Rose 14 years ago
parent
commit
17611c2d20

+ 33 - 0
panda/src/audiotraits/openalAudioManager.cxx

@@ -25,11 +25,13 @@
 #include "openalAudioSound.h"
 #include "openalAudioSound.h"
 #include "virtualFileSystem.h"
 #include "virtualFileSystem.h"
 #include "movieAudio.h"
 #include "movieAudio.h"
+#include "reMutexHolder.h"
 
 
 #include <algorithm>
 #include <algorithm>
 
 
 TypeHandle OpenALAudioManager::_type_handle;
 TypeHandle OpenALAudioManager::_type_handle;
 
 
+ReMutex OpenALAudioManager::_lock;
 int OpenALAudioManager::_active_managers = 0;
 int OpenALAudioManager::_active_managers = 0;
 bool OpenALAudioManager::_openal_active = false;
 bool OpenALAudioManager::_openal_active = false;
 ALCdevice* OpenALAudioManager::_device = NULL;
 ALCdevice* OpenALAudioManager::_device = NULL;
@@ -78,6 +80,7 @@ AudioManager *Create_OpenALAudioManager() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 OpenALAudioManager::
 OpenALAudioManager::
 OpenALAudioManager() {
 OpenALAudioManager() {
+  ReMutexHolder holder(_lock);
   if (_managers == (Managers *)NULL) {
   if (_managers == (Managers *)NULL) {
     _managers = new Managers;
     _managers = new Managers;
     _al_sources = new SourceCache;
     _al_sources = new SourceCache;
@@ -164,6 +167,7 @@ OpenALAudioManager() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 OpenALAudioManager::
 OpenALAudioManager::
 ~OpenALAudioManager() {
 ~OpenALAudioManager() {
+  ReMutexHolder holder(_lock);
   nassertv(_managers != (Managers *)NULL);
   nassertv(_managers != (Managers *)NULL);
   Managers::iterator mi = _managers->find(this);
   Managers::iterator mi = _managers->find(this);
   nassertv(mi != _managers->end());
   nassertv(mi != _managers->end());
@@ -182,6 +186,7 @@ OpenALAudioManager::
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 shutdown() {
 shutdown() {
+  ReMutexHolder holder(_lock);
   if (_managers != (Managers *)NULL) {
   if (_managers != (Managers *)NULL) {
     Managers::iterator mi;
     Managers::iterator mi;
     for (mi = _managers->begin(); mi != _managers->end(); ++mi) {
     for (mi = _managers->begin(); mi != _managers->end(); ++mi) {
@@ -226,6 +231,7 @@ make_current() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool OpenALAudioManager::
 bool OpenALAudioManager::
 can_use_audio(MovieAudioCursor *source) {
 can_use_audio(MovieAudioCursor *source) {
+  ReMutexHolder holder(_lock);
   int channels = source->audio_channels();
   int channels = source->audio_channels();
   if ((channels != 1)&&(channels != 2)) {
   if ((channels != 1)&&(channels != 2)) {
     audio_error("Currently, only mono and stereo are supported.");
     audio_error("Currently, only mono and stereo are supported.");
@@ -244,6 +250,7 @@ can_use_audio(MovieAudioCursor *source) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool OpenALAudioManager::
 bool OpenALAudioManager::
 should_load_audio(MovieAudioCursor *source, int mode) {
 should_load_audio(MovieAudioCursor *source, int mode) {
+  ReMutexHolder holder(_lock);
   if (mode == SM_stream) {
   if (mode == SM_stream) {
     // If the user asked for streaming, give him streaming.
     // If the user asked for streaming, give him streaming.
     return false;
     return false;
@@ -280,6 +287,7 @@ should_load_audio(MovieAudioCursor *source, int mode) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 OpenALAudioManager::SoundData *OpenALAudioManager::
 OpenALAudioManager::SoundData *OpenALAudioManager::
 get_sound_data(MovieAudio *movie, int mode) {
 get_sound_data(MovieAudio *movie, int mode) {
+  ReMutexHolder holder(_lock);
   const Filename &path = movie->get_filename();
   const Filename &path = movie->get_filename();
   
   
   // Search for an already-cached sample or an already-opened stream.
   // Search for an already-cached sample or an already-opened stream.
@@ -370,6 +378,7 @@ get_sound_data(MovieAudio *movie, int mode) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 PT(AudioSound) OpenALAudioManager::
 PT(AudioSound) OpenALAudioManager::
 get_sound(MovieAudio *sound, bool positional, int mode) {
 get_sound(MovieAudio *sound, bool positional, int mode) {
+  ReMutexHolder holder(_lock);
   if(!is_valid()) {
   if(!is_valid()) {
     return get_null_sound();
     return get_null_sound();
   }
   }
@@ -388,6 +397,7 @@ get_sound(MovieAudio *sound, bool positional, int mode) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 PT(AudioSound) OpenALAudioManager::
 PT(AudioSound) OpenALAudioManager::
 get_sound(const string &file_name, bool positional, int mode) {
 get_sound(const string &file_name, bool positional, int mode) {
+  ReMutexHolder holder(_lock);
   if(!is_valid()) {
   if(!is_valid()) {
     return get_null_sound();
     return get_null_sound();
   }
   }
@@ -420,6 +430,7 @@ get_sound(const string &file_name, bool positional, int mode) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 uncache_sound(const string& file_name) {
 uncache_sound(const string& file_name) {
+  ReMutexHolder holder(_lock);
   assert(is_valid());
   assert(is_valid());
   Filename path = file_name;
   Filename path = file_name;
   
   
@@ -444,6 +455,7 @@ uncache_sound(const string& file_name) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 clear_cache() {
 clear_cache() {
+  ReMutexHolder holder(_lock);
   discard_excess_cache(0);
   discard_excess_cache(0);
 }
 }
 
 
@@ -454,6 +466,7 @@ clear_cache() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 set_cache_limit(unsigned int count) {
 set_cache_limit(unsigned int count) {
+  ReMutexHolder holder(_lock);
   _cache_limit=count;
   _cache_limit=count;
   discard_excess_cache(count);
   discard_excess_cache(count);
 }
 }
@@ -475,6 +488,7 @@ get_cache_limit() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 release_sound(OpenALAudioSound* audioSound) {
 release_sound(OpenALAudioSound* audioSound) {
+  ReMutexHolder holder(_lock);
   AllSounds::iterator ai = _all_sounds.find(audioSound);
   AllSounds::iterator ai = _all_sounds.find(audioSound);
   if (ai != _all_sounds.end()) {
   if (ai != _all_sounds.end()) {
     _all_sounds.erase(ai);
     _all_sounds.erase(ai);
@@ -488,6 +502,7 @@ release_sound(OpenALAudioSound* audioSound) {
 //        Sets listener gain
 //        Sets listener gain
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::set_volume(PN_stdfloat volume) {
 void OpenALAudioManager::set_volume(PN_stdfloat volume) {
+  ReMutexHolder holder(_lock);
   if (_volume!=volume) {
   if (_volume!=volume) {
     _volume = volume;
     _volume = volume;
 
 
@@ -526,6 +541,7 @@ get_volume() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 set_play_rate(PN_stdfloat play_rate) {
 set_play_rate(PN_stdfloat play_rate) {
+  ReMutexHolder holder(_lock);
   if (_play_rate!=play_rate) {
   if (_play_rate!=play_rate) {
     _play_rate = play_rate;
     _play_rate = play_rate;
     // Tell our AudioSounds to adjust:
     // Tell our AudioSounds to adjust:
@@ -554,6 +570,7 @@ get_play_rate() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 set_active(bool active) {
 set_active(bool active) {
+  ReMutexHolder holder(_lock);
   if (_active!=active) {
   if (_active!=active) {
     _active=active;
     _active=active;
     // Tell our AudioSounds to adjust:
     // Tell our AudioSounds to adjust:
@@ -591,6 +608,7 @@ get_active() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 audio_3d_set_listener_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz, PN_stdfloat vx, PN_stdfloat vy, PN_stdfloat vz, PN_stdfloat fx, PN_stdfloat fy, PN_stdfloat fz, PN_stdfloat ux, PN_stdfloat uy, PN_stdfloat uz) {
 audio_3d_set_listener_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz, PN_stdfloat vx, PN_stdfloat vy, PN_stdfloat vz, PN_stdfloat fx, PN_stdfloat fy, PN_stdfloat fz, PN_stdfloat ux, PN_stdfloat uy, PN_stdfloat uz) {
+  ReMutexHolder holder(_lock);
   _position[0] = px;
   _position[0] = px;
   _position[1] = pz;
   _position[1] = pz;
   _position[2] = -py; 
   _position[2] = -py; 
@@ -626,6 +644,7 @@ audio_3d_set_listener_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 audio_3d_get_listener_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat *pz, PN_stdfloat *vx, PN_stdfloat *vy, PN_stdfloat *vz, PN_stdfloat *fx, PN_stdfloat *fy, PN_stdfloat *fz, PN_stdfloat *ux, PN_stdfloat *uy, PN_stdfloat *uz) {
 audio_3d_get_listener_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat *pz, PN_stdfloat *vx, PN_stdfloat *vy, PN_stdfloat *vz, PN_stdfloat *fx, PN_stdfloat *fy, PN_stdfloat *fz, PN_stdfloat *ux, PN_stdfloat *uy, PN_stdfloat *uz) {
+  ReMutexHolder holder(_lock);
   *px = _position[0];
   *px = _position[0];
   *py = -_position[2];
   *py = -_position[2];
   *pz = _position[1];
   *pz = _position[1];
@@ -655,6 +674,7 @@ audio_3d_get_listener_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat *
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 audio_3d_set_distance_factor(PN_stdfloat factor) {
 audio_3d_set_distance_factor(PN_stdfloat factor) {
+  ReMutexHolder holder(_lock);
   _distance_factor = factor;
   _distance_factor = factor;
 
 
   make_current();
   make_current();
@@ -698,6 +718,7 @@ audio_3d_get_distance_factor() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 audio_3d_set_doppler_factor(PN_stdfloat factor) {
 audio_3d_set_doppler_factor(PN_stdfloat factor) {
+  ReMutexHolder holder(_lock);
   _doppler_factor = factor;
   _doppler_factor = factor;
 
 
   make_current();
   make_current();
@@ -725,6 +746,7 @@ audio_3d_get_doppler_factor() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 audio_3d_set_drop_off_factor(PN_stdfloat factor) {
 audio_3d_set_drop_off_factor(PN_stdfloat factor) {
+  ReMutexHolder holder(_lock);
   _drop_off_factor = factor;
   _drop_off_factor = factor;
 
 
   AllSounds::iterator i=_all_sounds.begin();
   AllSounds::iterator i=_all_sounds.begin();
@@ -753,6 +775,7 @@ audio_3d_get_drop_off_factor() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 starting_sound(OpenALAudioSound* audio) {
 starting_sound(OpenALAudioSound* audio) {
+  ReMutexHolder holder(_lock);
   ALuint source=0;
   ALuint source=0;
   
   
   // If the sound already has a source, we don't need to do anything.
   // If the sound already has a source, we don't need to do anything.
@@ -801,6 +824,7 @@ starting_sound(OpenALAudioSound* audio) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 stopping_sound(OpenALAudioSound* audio) {
 stopping_sound(OpenALAudioSound* audio) {
+  ReMutexHolder holder(_lock);
   if (audio->_source) {
   if (audio->_source) {
     _al_sources->insert(audio->_source);
     _al_sources->insert(audio->_source);
     audio->_source = 0;
     audio->_source = 0;
@@ -815,6 +839,7 @@ stopping_sound(OpenALAudioSound* audio) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 set_concurrent_sound_limit(unsigned int limit) {
 set_concurrent_sound_limit(unsigned int limit) {
+  ReMutexHolder holder(_lock);
   _concurrent_sound_limit = limit;
   _concurrent_sound_limit = limit;
   reduce_sounds_playing_to(_concurrent_sound_limit);
   reduce_sounds_playing_to(_concurrent_sound_limit);
 }
 }
@@ -836,6 +861,7 @@ get_concurrent_sound_limit() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 reduce_sounds_playing_to(unsigned int count) {
 reduce_sounds_playing_to(unsigned int count) {
+  ReMutexHolder holder(_lock);
   // first give all sounds that have finished a chance to stop, so that these get stopped first
   // first give all sounds that have finished a chance to stop, so that these get stopped first
   update();
   update();
 
 
@@ -861,6 +887,7 @@ reduce_sounds_playing_to(unsigned int count) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 stop_all_sounds() {
 stop_all_sounds() {
+  ReMutexHolder holder(_lock);
   reduce_sounds_playing_to(0);
   reduce_sounds_playing_to(0);
 }
 }
 
 
@@ -871,6 +898,7 @@ stop_all_sounds() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 update() {
 update() {
+  ReMutexHolder holder(_lock);
 
 
   // See if any of our playing sounds have ended
   // See if any of our playing sounds have ended
   // we must first collect a seperate list of finished sounds and then
   // we must first collect a seperate list of finished sounds and then
@@ -910,6 +938,7 @@ update() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 cleanup() {
 cleanup() {
+  ReMutexHolder holder(_lock);
   if (!_cleanup_required) {
   if (!_cleanup_required) {
     return;
     return;
   }
   }
@@ -991,6 +1020,7 @@ SoundData() :
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 OpenALAudioManager::SoundData::
 OpenALAudioManager::SoundData::
 ~SoundData() {
 ~SoundData() {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   if (_sample != 0) {
   if (_sample != 0) {
     if (_manager->_is_valid) {
     if (_manager->_is_valid) {
       _manager->make_current();
       _manager->make_current();
@@ -1009,6 +1039,7 @@ OpenALAudioManager::SoundData::
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 increment_client_count(SoundData *sd) {
 increment_client_count(SoundData *sd) {
+  ReMutexHolder holder(_lock);
   sd->_client_count += 1;
   sd->_client_count += 1;
   audio_debug("Incrementing: " << sd->_movie->get_filename().get_basename() << " " << sd->_client_count);
   audio_debug("Incrementing: " << sd->_movie->get_filename().get_basename() << " " << sd->_client_count);
   if (sd->_client_count == 1) {
   if (sd->_client_count == 1) {
@@ -1031,6 +1062,7 @@ increment_client_count(SoundData *sd) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 decrement_client_count(SoundData *sd) {
 decrement_client_count(SoundData *sd) {
+  ReMutexHolder holder(_lock);
   sd->_client_count -= 1;
   sd->_client_count -= 1;
   audio_debug("Decrementing: " << sd->_movie->get_filename().get_basename() << " " << sd->_client_count);
   audio_debug("Decrementing: " << sd->_movie->get_filename().get_basename() << " " << sd->_client_count);
   if (sd->_client_count == 0) {
   if (sd->_client_count == 0) {
@@ -1055,6 +1087,7 @@ decrement_client_count(SoundData *sd) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioManager::
 void OpenALAudioManager::
 discard_excess_cache(int sample_limit) {
 discard_excess_cache(int sample_limit) {
+  ReMutexHolder holder(_lock);
   int stream_limit = 5;
   int stream_limit = 5;
 
 
   while (((int)_expiring_samples.size()) > sample_limit) {
   while (((int)_expiring_samples.size()) > sample_limit) {

+ 3 - 0
panda/src/audiotraits/openalAudioManager.h

@@ -25,6 +25,7 @@
 #include "pmap.h"
 #include "pmap.h"
 #include "pset.h"
 #include "pset.h"
 #include "movieAudioCursor.h"
 #include "movieAudioCursor.h"
+#include "reMutex.h"
 
 
 // OSX uses the OpenAL framework
 // OSX uses the OpenAL framework
 #ifdef IS_OSX
 #ifdef IS_OSX
@@ -135,6 +136,8 @@ private:
   void cleanup();
   void cleanup();
   
   
 private:
 private:
+  // This global lock protects all access to OpenAL library interfaces.
+  static ReMutex _lock;
 
 
   // An expiration queue is a list of SoundData
   // An expiration queue is a list of SoundData
   // that are no longer being used.  They are kept
   // that are no longer being used.  They are kept

+ 27 - 0
panda/src/audiotraits/openalAudioSound.cxx

@@ -74,6 +74,8 @@ OpenALAudioSound(OpenALAudioManager* manager,
   _velocity[1] = 0.0f;
   _velocity[1] = 0.0f;
   _velocity[2] = 0.0f;
   _velocity[2] = 0.0f;
 
 
+  ReMutexHolder holder(OpenALAudioManager::_lock);
+
   require_sound_data();
   require_sound_data();
   if (_manager == NULL) {
   if (_manager == NULL) {
     return;
     return;
@@ -107,6 +109,7 @@ OpenALAudioSound::
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 cleanup() {
 cleanup() {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   if (_manager == 0) {
   if (_manager == 0) {
     return;
     return;
   }
   }
@@ -128,6 +131,7 @@ cleanup() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 play() {
 play() {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   if (_manager == 0) return;
   if (_manager == 0) return;
 
 
   PN_stdfloat px,py,pz,vx,vy,vz;
   PN_stdfloat px,py,pz,vx,vy,vz;
@@ -202,6 +206,7 @@ play() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 stop() {
 stop() {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   if (_manager==0) return;
   if (_manager==0) return;
 
 
   if (_source) {
   if (_source) {
@@ -233,6 +238,7 @@ stop() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 finished() {
 finished() {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   stop();
   stop();
   _current_time = _length;
   _current_time = _length;
   if (!_finished_event.empty()) {
   if (!_finished_event.empty()) {
@@ -247,6 +253,7 @@ finished() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 set_loop(bool loop) {
 set_loop(bool loop) {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   set_loop_count((loop)?0:1);
   set_loop_count((loop)?0:1);
 }
 }
 
 
@@ -267,6 +274,7 @@ get_loop() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 set_loop_count(unsigned long loop_count) {
 set_loop_count(unsigned long loop_count) {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   if (_manager==0) return;
   if (_manager==0) return;
   
   
   if (loop_count >= 1000000000) {
   if (loop_count >= 1000000000) {
@@ -298,6 +306,7 @@ get_loop_count() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 restart_stalled_audio() {
 restart_stalled_audio() {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   ALenum status;
   ALenum status;
   if (_stream_queued.size() == 0) {
   if (_stream_queued.size() == 0) {
     return;
     return;
@@ -316,6 +325,7 @@ restart_stalled_audio() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 queue_buffer(ALuint buffer, int samples, int loop_index, double time_offset) {
 queue_buffer(ALuint buffer, int samples, int loop_index, double time_offset) {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   // Now push the buffer into the stream queue.
   // Now push the buffer into the stream queue.
   alGetError();
   alGetError();
   alSourceQueueBuffers(_source,1,&buffer);
   alSourceQueueBuffers(_source,1,&buffer);
@@ -340,6 +350,7 @@ queue_buffer(ALuint buffer, int samples, int loop_index, double time_offset) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 ALuint OpenALAudioSound::
 ALuint OpenALAudioSound::
 make_buffer(int samples, int channels, int rate, unsigned char *data) {
 make_buffer(int samples, int channels, int rate, unsigned char *data) {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   
   
   // Allocate a buffer to hold the data.
   // Allocate a buffer to hold the data.
   alGetError();
   alGetError();
@@ -373,6 +384,7 @@ make_buffer(int samples, int channels, int rate, unsigned char *data) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 int OpenALAudioSound::
 int OpenALAudioSound::
 read_stream_data(int bytelen, unsigned char *buffer) {
 read_stream_data(int bytelen, unsigned char *buffer) {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
 
 
   MovieAudioCursor *cursor = _sd->_stream;
   MovieAudioCursor *cursor = _sd->_stream;
   double length = cursor->length();
   double length = cursor->length();
@@ -427,6 +439,7 @@ read_stream_data(int bytelen, unsigned char *buffer) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 correct_calibrated_clock(double rtc, double t) {
 correct_calibrated_clock(double rtc, double t) {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   double cc = (rtc - _calibrated_clock_base) * _calibrated_clock_scale;
   double cc = (rtc - _calibrated_clock_base) * _calibrated_clock_scale;
   double diff = cc-t;
   double diff = cc-t;
   _calibrated_clock_decavg = (_calibrated_clock_decavg * 0.95) + (diff * 0.05);
   _calibrated_clock_decavg = (_calibrated_clock_decavg * 0.95) + (diff * 0.05);
@@ -459,6 +472,7 @@ correct_calibrated_clock(double rtc, double t) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 pull_used_buffers() {
 pull_used_buffers() {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   while (_stream_queued.size()) {
   while (_stream_queued.size()) {
     ALuint buffer = 0;
     ALuint buffer = 0;
     alGetError();
     alGetError();
@@ -493,6 +507,7 @@ pull_used_buffers() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 push_fresh_buffers() {
 push_fresh_buffers() {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   static unsigned char data[65536];
   static unsigned char data[65536];
   
   
   if (_sd->_sample) {
   if (_sd->_sample) {
@@ -536,6 +551,7 @@ push_fresh_buffers() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 set_time(PN_stdfloat time) {
 set_time(PN_stdfloat time) {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   _start_time = time;
   _start_time = time;
 }
 }
 
 
@@ -546,6 +562,7 @@ set_time(PN_stdfloat time) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 PN_stdfloat OpenALAudioSound::
 PN_stdfloat OpenALAudioSound::
 get_time() const {
 get_time() const {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   if (_manager == 0) {
   if (_manager == 0) {
     return 0.0;
     return 0.0;
   }
   }
@@ -559,6 +576,7 @@ get_time() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 cache_time(double rtc) {
 cache_time(double rtc) {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   assert(_source != 0);
   assert(_source != 0);
   double t=get_calibrated_clock(rtc);
   double t=get_calibrated_clock(rtc);
   double max = _length * _playing_loops;
   double max = _length * _playing_loops;
@@ -577,6 +595,7 @@ cache_time(double rtc) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 set_volume(PN_stdfloat volume) {
 set_volume(PN_stdfloat volume) {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   _volume=volume;
   _volume=volume;
 
 
   if (_source) {
   if (_source) {
@@ -630,6 +649,7 @@ get_balance() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 set_play_rate(PN_stdfloat play_rate) {
 set_play_rate(PN_stdfloat play_rate) {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   _play_rate = play_rate;
   _play_rate = play_rate;
   if (_source) {
   if (_source) {
     alSourcef(_source, AL_PITCH, play_rate);
     alSourcef(_source, AL_PITCH, play_rate);
@@ -674,6 +694,7 @@ length() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 set_3d_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz, PN_stdfloat vx, PN_stdfloat vy, PN_stdfloat vz) {
 set_3d_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz, PN_stdfloat vx, PN_stdfloat vy, PN_stdfloat vz) {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   _location[0] = px;
   _location[0] = px;
   _location[1] = pz;
   _location[1] = pz;
   _location[2] = -py; 
   _location[2] = -py; 
@@ -701,6 +722,7 @@ set_3d_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz, PN_stdfloat vx
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 get_3d_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat *pz, PN_stdfloat *vx, PN_stdfloat *vy, PN_stdfloat *vz) {
 get_3d_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat *pz, PN_stdfloat *vx, PN_stdfloat *vy, PN_stdfloat *vz) {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   *px = _location[0];
   *px = _location[0];
   *py = -_location[2];
   *py = -_location[2];
   *pz = _location[1];
   *pz = _location[1];
@@ -718,6 +740,7 @@ get_3d_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat *pz, PN_stdfloat
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 set_3d_min_distance(PN_stdfloat dist) {
 set_3d_min_distance(PN_stdfloat dist) {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   _min_dist = dist;
   _min_dist = dist;
 
 
   if (_source) {
   if (_source) {
@@ -746,6 +769,7 @@ get_3d_min_distance() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 set_3d_max_distance(PN_stdfloat dist) {
 set_3d_max_distance(PN_stdfloat dist) {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   _max_dist = dist;
   _max_dist = dist;
 
 
   if (_source) {
   if (_source) {
@@ -775,6 +799,7 @@ get_3d_max_distance() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 set_3d_drop_off_factor(PN_stdfloat factor) {
 set_3d_drop_off_factor(PN_stdfloat factor) {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   _drop_off_factor = factor;
   _drop_off_factor = factor;
 
 
   if (_source) {
   if (_source) {
@@ -807,6 +832,7 @@ get_3d_drop_off_factor() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void OpenALAudioSound::
 void OpenALAudioSound::
 set_active(bool active) {
 set_active(bool active) {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   if (_active!=active) {
   if (_active!=active) {
     _active=active;
     _active=active;
     if (_active) {
     if (_active) {
@@ -880,6 +906,7 @@ get_name() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 AudioSound::SoundStatus OpenALAudioSound::
 AudioSound::SoundStatus OpenALAudioSound::
 status() const {
 status() const {
+  ReMutexHolder holder(OpenALAudioManager::_lock);
   if (_source==0) {
   if (_source==0) {
     return AudioSound::READY;
     return AudioSound::READY;
   }
   }