Reverted BX_THREAD_KILL() changes in the lowlevel sound code. Now using control

variables again to let the threads end normally. Re-implenented the method
closewaveoutput() for some modules, move the destructor code to it and call it
after leaving the mixer thread. This fixes a deadlock in the "soundwin" module
if Bochs is compiled with plugin support.
This commit is contained in:
Volker Ruppert 2017-06-02 16:56:58 +00:00
parent 726e39f854
commit bdd8875692
8 changed files with 36 additions and 33 deletions

View File

@ -135,15 +135,6 @@ bx_soundlow_waveout_alsa_c::bx_soundlow_waveout_alsa_c()
alsa_waveout.buffer = NULL;
}
bx_soundlow_waveout_alsa_c::~bx_soundlow_waveout_alsa_c()
{
if (alsa_waveout.handle != NULL) {
snd_pcm_drain(alsa_waveout.handle);
snd_pcm_close(alsa_waveout.handle);
alsa_waveout.handle = NULL;
}
}
int bx_soundlow_waveout_alsa_c::openwaveoutput(const char *wavedev)
{
set_pcm_params(&real_pcm_param);
@ -181,6 +172,16 @@ int bx_soundlow_waveout_alsa_c::output(int length, Bit8u data[])
return BX_SOUNDLOW_OK;
}
int bx_soundlow_waveout_alsa_c::closewaveoutput()
{
if (alsa_waveout.handle != NULL) {
snd_pcm_drain(alsa_waveout.handle);
snd_pcm_close(alsa_waveout.handle);
alsa_waveout.handle = NULL;
}
return BX_SOUNDLOW_OK;
}
// bx_soundlow_wavein_alsa_c class implementation
bx_soundlow_wavein_alsa_c::bx_soundlow_wavein_alsa_c()

View File

@ -38,12 +38,13 @@ typedef struct {
class bx_soundlow_waveout_alsa_c : public bx_soundlow_waveout_c {
public:
bx_soundlow_waveout_alsa_c();
virtual ~bx_soundlow_waveout_alsa_c();
virtual ~bx_soundlow_waveout_alsa_c() {}
virtual int openwaveoutput(const char *wavedev);
virtual int set_pcm_params(bx_pcm_param_t *param);
virtual int get_packetsize();
virtual int output(int length, Bit8u data[]);
virtual int closewaveoutput();
private:
alsa_pcm_t alsa_waveout;
};

View File

@ -62,11 +62,6 @@ bx_soundlow_waveout_file_c::bx_soundlow_waveout_file_c()
type = BX_SOUNDFILE_RAW;
}
bx_soundlow_waveout_file_c::~bx_soundlow_waveout_file_c()
{
closewaveoutput();
}
void bx_soundlow_waveout_file_c::initwavfile()
{
Bit8u waveheader[44] =

View File

@ -26,7 +26,7 @@
class bx_soundlow_waveout_file_c : public bx_soundlow_waveout_c {
public:
bx_soundlow_waveout_file_c();
virtual ~bx_soundlow_waveout_file_c();
virtual ~bx_soundlow_waveout_file_c() {}
virtual int openwaveoutput(const char *wavedev);
virtual int set_pcm_params(bx_pcm_param_t *param);

View File

@ -197,8 +197,7 @@ BX_MUTEX(mixer_mutex);
BX_THREAD_FUNC(resampler_thread, indata)
{
bx_soundlow_waveout_c *waveout = (bx_soundlow_waveout_c*)indata;
waveout->resampler_running();
while (1) {
while (waveout->resampler_running()) {
BX_LOCK(resampler_mutex);
audio_buffer_t *curbuffer = audio_buffers[0]->get_buffer();
BX_UNLOCK(resampler_mutex);
@ -220,8 +219,7 @@ BX_THREAD_FUNC(mixer_thread, indata)
bx_soundlow_waveout_c *waveout = (bx_soundlow_waveout_c*)indata;
Bit8u *mixbuffer = new Bit8u[BX_SOUNDLOW_WAVEPACKETSIZE];
waveout->mixer_running();
while (1) {
while (waveout->mixer_running()) {
len = waveout->get_packetsize();
memset(mixbuffer, 0, len);
if (waveout->mixer_common(mixbuffer, len)) {
@ -231,6 +229,7 @@ BX_THREAD_FUNC(mixer_thread, indata)
}
}
delete [] mixbuffer;
waveout->closewaveoutput();
BX_THREAD_EXIT;
}
@ -263,11 +262,13 @@ bx_soundlow_waveout_c::~bx_soundlow_waveout_c()
#endif
unregister_wave_callback(pcm_callback_id);
if (res_thread_start) {
BX_THREAD_KILL(res_thread_var);
res_thread_start = 0;
BX_MSLEEP(20);
BX_FINI_MUTEX(resampler_mutex);
}
if (mix_thread_start) {
BX_THREAD_KILL(mix_thread_var);
mix_thread_start = 0;
BX_MSLEEP(25);
BX_FINI_MUTEX(mixer_mutex);
}
if (audio_buffers[0] != NULL) {
@ -478,12 +479,14 @@ Bit32u bx_soundlow_waveout_c::resampler_common(audio_buffer_t *inbuffer, float *
void bx_soundlow_waveout_c::start_resampler_thread()
{
BX_INIT_MUTEX(resampler_mutex);
res_thread_start = 1;
BX_THREAD_CREATE(resampler_thread, this, res_thread_var);
}
void bx_soundlow_waveout_c::start_mixer_thread()
{
BX_INIT_MUTEX(mixer_mutex);
mix_thread_start = 1;
BX_THREAD_CREATE(mixer_thread, this, mix_thread_var);
}

View File

@ -112,8 +112,8 @@ public:
virtual bx_bool mixer_common(Bit8u *buffer, int len);
void resampler_running() {res_thread_start = 1;}
void mixer_running() {mix_thread_start = 1;}
bx_bool resampler_running() {return res_thread_start;}
bx_bool mixer_running() {return mix_thread_start;}
protected:
void start_resampler_thread(void);

View File

@ -90,14 +90,6 @@ bx_soundlow_waveout_win_c::bx_soundlow_waveout_win_c()
BX_PANIC(("Allocated memory was too small!"));
}
bx_soundlow_waveout_win_c::~bx_soundlow_waveout_win_c()
{
if (WaveOutOpen == 1) {
waveOutReset(hWaveOut);
waveOutClose(hWaveOut);
}
}
int bx_soundlow_waveout_win_c::openwaveoutput(const char *wavedev)
{
// could make the output device selectable,
@ -220,6 +212,16 @@ int bx_soundlow_waveout_win_c::output(int length, Bit8u data[])
return BX_SOUNDLOW_OK;
}
int bx_soundlow_waveout_win_c::closewaveoutput()
{
if (WaveOutOpen == 1) {
waveOutReset(hWaveOut);
waveOutClose(hWaveOut);
WaveOutOpen = 1;
}
return BX_SOUNDLOW_OK;
}
// bx_soundlow_wavein_win_c class implementation
bx_soundlow_wavein_win_c::bx_soundlow_wavein_win_c()

View File

@ -160,12 +160,13 @@ typedef struct {
class bx_soundlow_waveout_win_c : public bx_soundlow_waveout_c {
public:
bx_soundlow_waveout_win_c();
virtual ~bx_soundlow_waveout_win_c();
virtual ~bx_soundlow_waveout_win_c() {}
virtual int openwaveoutput(const char *wavedev);
virtual int set_pcm_params(bx_pcm_param_t *param);
virtual int get_packetsize();
virtual int output(int length, Bit8u data[]);
virtual int closewaveoutput();
private:
HWAVEOUT hWaveOut; // Wave output device
int WaveOutOpen; // is it open?