Menu

#2 CoreAudio hangs at program exit

open
nobody
5
2011-01-14
2011-01-14
Albert Veli
No

Hi!

A small problem in OS X CoreAudio:

Steps to reproduce:

* Start playing a song
* Pause song
* Quit

Both the despotify and simple client has the same problem. They will hang if the currently playing song is paused at program exit. If a song is playing normally the program will exit nice.

This problem only occurs on OS X with CoreAudio. I used Snow Leopard + MacPorts to compile, svn -r 514.

I also narrowed the problem down by enabling DEBUG and inserting more DSFYDEBUG lines. The program seems to hang in:

src/clients/despotify/coreaudio.c line 194, in the following call:

AudioDeviceStop (device->adev_id, device->proc_id)

The coreaudio.c file is duplicated in the simple client and the same problem is there too, most likely in the same line.

I have tried but didn't find any other workaround yet than to always have a song playing when giving the quit command.

NOTE: The same problem also occurs if despotify has played through all songs in the playlist and is quiet when you give the quit command. It must be playing a song for the quit command to work correctly.

Cheers!

/Albert

Discussion

  • Albert Veli

    Albert Veli - 2011-01-14

    Maybe the source here can give some hints:

    http://libao.sourcearchive.com/documentation/1.0.0-5/ao__macosx_8c-source.html

    Especially this comment:

    // For some rare cases (using atexit in your program) Coreaudio tears
    // down the HAL itself, so we do not need to do that here.
    // We wouldn't get an error if we did, but AO would hang waiting for the
    // AU to flush the buffer

    But libao doesn't seem to use exactly the same API. It is similar but still not the same, so I am not sure if that comment is relevant.

     
  • Albert Veli

    Albert Veli - 2011-01-15

    Workaround to the CoreAudio hangup problem

     
  • Albert Veli

    Albert Veli - 2011-01-15

    Now I found a workaround to the problem, I attached the diff in coreaudio.diff. It is not nice but it works.

    I found out the problem has to do with device->mutex.

    audio_callback is hanging right after the line saying

    "Zero bytes available and playing, waiting."

    So the workaround is to send a pthread_cond_signal(&device->event); *before* locking the mutex in audio_exit. Only do this if device->playing is 1 *and* device->bufsize is 0.

    The problem with this is a small risk of a race condition. In case bufsize changes between the if() and pthread_cond_signal. It is probably possible to solve this in a better way, but I don't really know how.

     

Log in to post a comment.