[alsa-devel] Races in alsa-lib with threads

Trent Piepho tpiepho at gmail.com
Wed Nov 14 21:54:15 CET 2012


On Wed, Nov 14, 2012 at 3:03 PM, Rémi Denis-Courmont <remi at remlab.net> wrote:
> Le mercredi 14 novembre 2012 21:49:36, Trent Piepho a écrit :
>> > You claim that the Gstreamer ALSA sink plugin accesses alsa-lib from two
>> > threads simultaneously. Could you elaborate on how this can happen, maybe
>> > it is easy to fix?
>>
>> gstreamer has no lock around the call to snd_pcm_delay().  So it can
>> race with snd_pcm_wait() or snd_pcm_writei(), which are called in
>> another thread.  There is a lock around the block of code calling
>> wait()/writei(), but this lock isn't used for calling delay().
>
> Use non-blocking I/O and poll(). Then the snd_pcm_write() calls will not sleep
> and can be interlocked with snd_pcm_delay() calls.

gstreamer uses non-blocking I/O.  But uses snd_pcm_wait rather than
poll directly.  I wonder if poll() is entirely correct when ALSA
plugins are in the chain?

"the snd_pcm_write() calls ...can be interlocked with snd_pcm_delay() calls".

It's still a race to call writei() and delay() at the same time, even
if writei() is non-blocking.  But only if the rate plugin is being
used.  Of course the actual race is very small, and doesn't include
the time spent doing resampling or mixing in plugins which are still
part of the writei() call in non-blocking mode.  It's basically like
the BKL around every ALSA call.

>> It seems that they didn't know there would be a problem.
>
> Eh? It is rather the exception for a library to be thread-safe when using the
> same object in multiple threads.

It's ok to call kernel syscalls on the same fd at the same time.  The
kernel used to have the BKL for this.  Now it has fine grained locking
around the actual critical sections.  So if ALSA is called thread
safe, it doesn't seem that unreasonable to think one can do this.

> It looks more like "they" did not pay attention to what they were doing.

I think the point is that this bug was in gstreamer.  gstreamer is
commonly used by many people.  The bug has been there for years.  Many
programmers have looked at the code.  Yet no one noticed it or tracked
it down until now.  If it's so obvious why did it take so long?

You aren't aware of this problem in other multi-threaded code, but
that doesn't mean it doesn't exist.  You weren't aware of the problem
in gstreamer and yet it exists.


More information about the Alsa-devel mailing list