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 int want_buffers = 0, have_buffers = 0;
static bool initializing = true;
static bool stop_mixing = false;
static int output_fd;
static thread* update_thread;
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) {
audio_cat->error() << "could not open '" << audio_device << "'" << endl;
return;
return (void*)0L;
}
// this one I don't know about
int fragsize = 0x0004000c;
if (ioctl(output_fd, SNDCTL_DSP_SETFRAGMENT, &fragsize) == -1) {
audio_cat->error() << "faied to set fragment size" << endl;
return;
return (void*)0L;
}
// for now signed, 16-bit, little endian
int format = AFMT_S16_LE;
if (ioctl(output_fd, SNDCTL_DSP_SETFMT, &format) == -1) {
audio_cat->error() << "failed to set format on the dsp" << endl;
return;
return (void*)0L;
}
// set stereo
int stereo = 1;
if (ioctl(output_fd, SNDCTL_DSP_STEREO, &stereo) == -1) {
audio_cat->error() << "failed to set stereo on the dsp" << endl;
return;
return (void*)0L;
}
// set the frequency
if (ioctl(output_fd, SNDCTL_DSP_SPEED, &audio_mix_freq) == -1) {
audio_cat->error() << "failed to set frequency on the dsp" << endl;
return;
return (void*)0L;
}
while (1) {
while (!stop_mixing) {
if (have_buffers == 0) {
ipc_traits::sleep(0, audio_auto_update_delay);
} 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) {
@ -220,12 +235,14 @@ static void initialize(void) {
want_buffers = 2;
have_buffers = 0;
initializing = true;
stop_mixing = false;
audio_cat->info() << "spawning internal update thread" << endl;
update_thread = thread::create(internal_update, (void*)0L,
thread::PRIORITY_NORMAL);
AudioManager::set_update_func(update_linux);
AudioManager::set_shutdown_func(shutdown_linux);
have_initialized = true;
}

View File

@ -41,6 +41,15 @@ INLINE void AudioManager::spawn_update(void) {
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)
// 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
// 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::UpdateFunc* AudioManager::_update_func =
(AudioManager::UpdateFunc*)0L;
AudioManager::ShutdownFunc* AudioManager::_shutdown_func =
(AudioManager::ShutdownFunc*)0L;
mutex AudioManager::_manager_mutex;
bool* AudioManager::_quit = (bool*)0L;
thread* AudioManager::_spawned = (thread*)0L;
////////////////////////////////////////////////////////////////////
// Function: AudioManager::set_update_func
@ -24,6 +28,21 @@ void AudioManager::set_update_func(AudioManager::UpdateFunc* 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
// Access: Private, Static
@ -59,11 +78,15 @@ void AudioManager::ns_play(AudioMusic* music) {
// Access: static
// Description: the thread function to call update forever.
////////////////////////////////////////////////////////////////////
void AudioManager::spawned_update(void*) {
while (1) {
void* AudioManager::spawned_update(void* data) {
bool* flag = (bool*)data;
while (! (*flag)) {
AudioManager::update();
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
////////////////////////////////////////////////////////////////////
void AudioManager::ns_spawn_update(void) {
_spawned = thread::create(spawned_update, (void*)0L,
thread::PRIORITY_NORMAL);
if (_spawned == (thread*)0L) {
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(AudioMusic*);
void ns_spawn_update(void);
void ns_shutdown(void);
void ns_set_volume(AudioSample*, int);
void ns_set_volume(AudioMusic*, int);
static AudioManager* get_ptr(void);
static void spawned_update(void*);
static void* spawned_update(void*);
typedef void UpdateFunc(void);
typedef void ShutdownFunc(void);
static AudioManager* _global_ptr;
static UpdateFunc* _update_func;
static ShutdownFunc* _shutdown_func;
static mutex _manager_mutex;
thread* _spawned;
static bool* _quit;
static thread* _spawned;
public:
static void set_update_func(UpdateFunc*);
static void set_shutdown_func(ShutdownFunc*);
INLINE static void play(AudioSample*);
INLINE static void play(AudioMusic*);
INLINE static void 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(AudioMusic*, int);
};

View File

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

View File

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