[Openal-devel] Fix hang in alcCloseDevice()
Elias Naur
naur at odense.kollegienet.dk
Fri Oct 27 04:47:39 PDT 2006
Hi,
I've found a problem in the way alcCloseDevice closes the device. The relevant
code:
ALCboolean
alcCloseDevice( ALCdevice *dev )
{
/* ToDo: Is this test really necessary? */
if ( dev->ops != NULL) {
/* ToDo: Use return value */
dev->ops->close(dev->privateData);
}
free( dev->specifier );
free( dev );
num_devices--;
if( num_devices == 0 ) {
_alExit ();
}
return ALC_TRUE;
}
and take the close operation for the ALSA backend:
static void
closeALSA (struct ALC_BackendPrivateData *privateData)
{
struct alsaData *ad = (struct alsaData *) privateData;
ok (psnd_pcm_close (ad->pcmHandle), "close");
free (ad);
}
so the device is gone when dev->ops->close has been called. However, I've
found that sometimes the device is active in the mixer:
if(bytes_to_write)
{
/* ToDo: We are handling the current context
here only, there might be other active contexts!!! */
AL_context *cc = _alcDCGetContext( );
if( cc != NULL ) {
AL_device *dev = cc->write_device;
if( dev != NULL ) {
alcDeviceWrite_(dev,
mixbuf.data, bytes_to_write);
}
}
}
the alcDeviceWrite_ in turn calls:
int ret = psnd_pcm_writei (ad->pcmHandle, pdata, numFramesToWrite);
which hangs indefinitely after closing the device. This in turn mean that
alExit hangs forever, since it waits for the mixer thread to exit:
if(mixthread != NULL) {
time_for_mixer_to_die = AL_TRUE;
_alWaitThread( mixthread );
while( time_for_mixer_to_die == AL_TRUE ) {
_alMicroSleep(100000);
}
}
I've fixed this by adding a mixer pause lock to alcCloseDevice so we're
certain that the mixer thread is not writing when we are closing the device.
Patch attached, please comment.
- elias
-------------- next part --------------
A non-text attachment was scrubbed...
Name: closehang.patch
Type: text/x-diff
Size: 549 bytes
Desc: not available
Url : http://opensource.creative.com/pipermail/openal-devel/attachments/20061027/983a5853/closehang.bin
More information about the Openal-devel
mailing list