mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-27 15:25:54 -04:00
fix for exiting internal threads
This commit is contained in:
parent
846566100f
commit
b2c8a4a204
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user