[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