fix for exiting internal threads

This commit is contained in:
Cary Sandvig 2000-10-10 18:02:55 +00:00
parent 846566100f
commit b2c8a4a204
6 changed files with 97 additions and 14 deletions

View File

@ -29,6 +29,7 @@ static byte* scratch_buffer;
static byte* fetch_buffer; static byte* fetch_buffer;
static int want_buffers = 0, have_buffers = 0; static int want_buffers = 0, have_buffers = 0;
static bool initializing = true; static bool initializing = true;
static bool stop_mixing = false;
static int output_fd; static int output_fd;
static thread* update_thread; static thread* update_thread;
static int sample_size = sizeof(short); static int sample_size = sizeof(short);
@ -158,35 +159,35 @@ static void update_linux(void) {
} }
} }
static void internal_update(void*) { static void* internal_update(void*) {
if ((output_fd = open(audio_device->c_str(), O_WRONLY, 0)) == -1) { if ((output_fd = open(audio_device->c_str(), O_WRONLY, 0)) == -1) {
audio_cat->error() << "could not open '" << audio_device << "'" << endl; audio_cat->error() << "could not open '" << audio_device << "'" << endl;
return; return (void*)0L;
} }
// this one I don't know about // this one I don't know about
int fragsize = 0x0004000c; int fragsize = 0x0004000c;
if (ioctl(output_fd, SNDCTL_DSP_SETFRAGMENT, &fragsize) == -1) { if (ioctl(output_fd, SNDCTL_DSP_SETFRAGMENT, &fragsize) == -1) {
audio_cat->error() << "faied to set fragment size" << endl; audio_cat->error() << "faied to set fragment size" << endl;
return; return (void*)0L;
} }
// for now signed, 16-bit, little endian // for now signed, 16-bit, little endian
int format = AFMT_S16_LE; int format = AFMT_S16_LE;
if (ioctl(output_fd, SNDCTL_DSP_SETFMT, &format) == -1) { if (ioctl(output_fd, SNDCTL_DSP_SETFMT, &format) == -1) {
audio_cat->error() << "failed to set format on the dsp" << endl; audio_cat->error() << "failed to set format on the dsp" << endl;
return; return (void*)0L;
} }
// set stereo // set stereo
int stereo = 1; int stereo = 1;
if (ioctl(output_fd, SNDCTL_DSP_STEREO, &stereo) == -1) { if (ioctl(output_fd, SNDCTL_DSP_STEREO, &stereo) == -1) {
audio_cat->error() << "failed to set stereo on the dsp" << endl; audio_cat->error() << "failed to set stereo on the dsp" << endl;
return; return (void*)0L;
} }
// set the frequency // set the frequency
if (ioctl(output_fd, SNDCTL_DSP_SPEED, &audio_mix_freq) == -1) { if (ioctl(output_fd, SNDCTL_DSP_SPEED, &audio_mix_freq) == -1) {
audio_cat->error() << "failed to set frequency on the dsp" << endl; audio_cat->error() << "failed to set frequency on the dsp" << endl;
return; return (void*)0L;
} }
while (1) { while (!stop_mixing) {
if (have_buffers == 0) { if (have_buffers == 0) {
ipc_traits::sleep(0, audio_auto_update_delay); ipc_traits::sleep(0, audio_auto_update_delay);
} else { } else {
@ -199,6 +200,20 @@ static void internal_update(void*) {
} }
} }
} }
delete [] buffer1;
delete [] buffer2;
delete [] scratch_buffer;
delete [] fetch_buffer;
delete [] zero_buffer;
stop_mixing = false;
audio_cat->debug() << "exiting internal thread" << endl;
return (void*)0L;
}
static void shutdown_linux(void) {
stop_mixing = true;
while (stop_mixing);
audio_cat->debug() << "I believe the internal thread has exited" << endl;
} }
static void initialize(void) { static void initialize(void) {
@ -220,12 +235,14 @@ static void initialize(void) {
want_buffers = 2; want_buffers = 2;
have_buffers = 0; have_buffers = 0;
initializing = true; initializing = true;
stop_mixing = false;
audio_cat->info() << "spawning internal update thread" << endl; audio_cat->info() << "spawning internal update thread" << endl;
update_thread = thread::create(internal_update, (void*)0L, update_thread = thread::create(internal_update, (void*)0L,
thread::PRIORITY_NORMAL); thread::PRIORITY_NORMAL);
AudioManager::set_update_func(update_linux); AudioManager::set_update_func(update_linux);
AudioManager::set_shutdown_func(shutdown_linux);
have_initialized = true; have_initialized = true;
} }

View File

@ -41,6 +41,15 @@ INLINE void AudioManager::spawn_update(void) {
get_ptr()->ns_spawn_update(); get_ptr()->ns_spawn_update();
} }
////////////////////////////////////////////////////////////////////
// Function: AudioManager::shutdown
// Access: Public, Static
// Description: kill any internal threads, free any internal data
////////////////////////////////////////////////////////////////////
INLINE void AudioManager::shutdown(void) {
get_ptr()->ns_shutdown();
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AudioManager::set_volume (sample) // Function: AudioManager::set_volume (sample)
// Access: Public, Static // Access: Public, Static
@ -66,4 +75,4 @@ INLINE void AudioManager::set_volume(AudioMusic* music, int v) {
// directly; there's only supposed to be one AudioManager // directly; there's only supposed to be one AudioManager
// in the universe and it constructs itself. // in the universe and it constructs itself.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE AudioManager::AudioManager(void) : _spawned((thread*)0L) {} INLINE AudioManager::AudioManager(void) {}

View File

@ -9,7 +9,11 @@
AudioManager* AudioManager::_global_ptr = (AudioManager*)0L; AudioManager* AudioManager::_global_ptr = (AudioManager*)0L;
AudioManager::UpdateFunc* AudioManager::_update_func = AudioManager::UpdateFunc* AudioManager::_update_func =
(AudioManager::UpdateFunc*)0L; (AudioManager::UpdateFunc*)0L;
AudioManager::ShutdownFunc* AudioManager::_shutdown_func =
(AudioManager::ShutdownFunc*)0L;
mutex AudioManager::_manager_mutex; mutex AudioManager::_manager_mutex;
bool* AudioManager::_quit = (bool*)0L;
thread* AudioManager::_spawned = (thread*)0L;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AudioManager::set_update_func // Function: AudioManager::set_update_func
@ -24,6 +28,21 @@ void AudioManager::set_update_func(AudioManager::UpdateFunc* func) {
_update_func = func; _update_func = func;
} }
////////////////////////////////////////////////////////////////////
// Function: AudioManager::set_shutdown_func
// Access: Public, Static
// Description: register a function that will shutdown the internal
// audio state
////////////////////////////////////////////////////////////////////
void AudioManager::set_shutdown_func(AudioManager::ShutdownFunc* func) {
if (_shutdown_func != (AudioManager::ShutdownFunc*)0L)
audio_cat->error() << "There maybe be more then one audio driver installed"
<< endl;
_shutdown_func = func;
if (_quit == (bool*)0L)
_quit = new bool(false);
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AudioManager::get_ptr // Function: AudioManager::get_ptr
// Access: Private, Static // Access: Private, Static
@ -59,11 +78,15 @@ void AudioManager::ns_play(AudioMusic* music) {
// Access: static // Access: static
// Description: the thread function to call update forever. // Description: the thread function to call update forever.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void AudioManager::spawned_update(void*) { void* AudioManager::spawned_update(void* data) {
while (1) { bool* flag = (bool*)data;
while (! (*flag)) {
AudioManager::update(); AudioManager::update();
ipc_traits::sleep(0, audio_auto_update_delay); ipc_traits::sleep(0, audio_auto_update_delay);
} }
*flag = false;
audio_cat->debug() << "exiting update thread" << endl;
return (void*)0L;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -90,6 +113,28 @@ void AudioManager::ns_set_volume(AudioMusic* music, int v) {
// Description: spawn a thread that calls update every so often // Description: spawn a thread that calls update every so often
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void AudioManager::ns_spawn_update(void) { void AudioManager::ns_spawn_update(void) {
_spawned = thread::create(spawned_update, (void*)0L, if (_spawned == (thread*)0L) {
thread::PRIORITY_NORMAL); if (_quit == (bool*)0L)
_quit = new bool(false);
*_quit = false;
_spawned = thread::create(spawned_update, _quit, thread::PRIORITY_NORMAL);
} else {
audio_cat->error() << "tried to spawn 2 update threads" << endl;
}
}
////////////////////////////////////////////////////////////////////
// Function: AudioManager::ns_shutdown
// Access: Private
// Description: non-static implementation of shutdown stuff
////////////////////////////////////////////////////////////////////
void AudioManager::ns_shutdown(void) {
if (_quit != (bool*)0L)
*_quit = true;
if (_shutdown_func != (ShutdownFunc*)0L)
(*_shutdown_func)();
if (_spawned != (thread*)0L)
while (*_quit);
audio_cat->debug() << "update thread has shutdown" << endl;
delete _quit;
} }

View File

@ -20,24 +20,30 @@ private:
void ns_play(AudioSample*); void ns_play(AudioSample*);
void ns_play(AudioMusic*); void ns_play(AudioMusic*);
void ns_spawn_update(void); void ns_spawn_update(void);
void ns_shutdown(void);
void ns_set_volume(AudioSample*, int); void ns_set_volume(AudioSample*, int);
void ns_set_volume(AudioMusic*, int); void ns_set_volume(AudioMusic*, int);
static AudioManager* get_ptr(void); static AudioManager* get_ptr(void);
static void spawned_update(void*); static void* spawned_update(void*);
typedef void UpdateFunc(void); typedef void UpdateFunc(void);
typedef void ShutdownFunc(void);
static AudioManager* _global_ptr; static AudioManager* _global_ptr;
static UpdateFunc* _update_func; static UpdateFunc* _update_func;
static ShutdownFunc* _shutdown_func;
static mutex _manager_mutex; static mutex _manager_mutex;
thread* _spawned; static bool* _quit;
static thread* _spawned;
public: public:
static void set_update_func(UpdateFunc*); static void set_update_func(UpdateFunc*);
static void set_shutdown_func(ShutdownFunc*);
INLINE static void play(AudioSample*); INLINE static void play(AudioSample*);
INLINE static void play(AudioMusic*); INLINE static void play(AudioMusic*);
INLINE static void update(void); INLINE static void update(void);
INLINE static void spawn_update(void); INLINE static void spawn_update(void);
INLINE static void shutdown(void);
INLINE static void set_volume(AudioSample*, int); INLINE static void set_volume(AudioSample*, int);
INLINE static void set_volume(AudioMusic*, int); INLINE static void set_volume(AudioMusic*, int);
}; };

View File

@ -657,6 +657,10 @@ void WinMusic::destroy(AudioTraits::MusicClass* music) {
WinPlaying::~WinPlaying(void) { WinPlaying::~WinPlaying(void) {
} }
AudioTraits::PlayingClass::PlayingStatus WinPlaying::status(void) {
return AudioTraits::PlayingClass::BAD;
}
WinPlayer* WinPlayer::_global_instance = (WinPlayer*)0L; WinPlayer* WinPlayer::_global_instance = (WinPlayer*)0L;
WinPlayer::~WinPlayer(void) { WinPlayer::~WinPlayer(void) {

View File

@ -69,6 +69,8 @@ class EXPCL_PANDA WinPlaying : public AudioTraits::PlayingClass {
public: public:
INLINE WinPlaying(void); INLINE WinPlaying(void);
~WinPlaying(void); ~WinPlaying(void);
virtual AudioTraits::PlayingClass::PlayingStatus status(void);
}; };
class EXPCL_PANDA WinPlayer : public AudioTraits::PlayerClass { class EXPCL_PANDA WinPlayer : public AudioTraits::PlayerClass {