alsasink: don't use 100% CPU
authoryanghuolin <Huolin.Yang@delphi.com>
Thu, 15 Nov 2012 08:31:47 +0000 (03:31 -0500)
committerWim Taymans <wim.taymans@collabora.co.uk>
Thu, 24 Jan 2013 14:08:31 +0000 (15:08 +0100)
commit67a7b5a99317ca1f92fb6a88542647aa3ad92c4b
tree4b3692ab24876ec4e8d27a481a06532babe07aa1
parent500b86489923b8add387598f367eb8368522c9de
alsasink: don't use 100% CPU

The root cause is that alsa-lib is not thread safe for the same handle.
There are two threads in the gstreamer accessing alsa-lib not serilized.
The race condition happens when one thread holds the old framebuffer app_ptr
position in the kernel, another thread advances the framebuffer app_ptr.
when the former thread is scheduled to run again, it overwrites the app_ptr
to old value by copying from kernel.Thus,the app_ptr in the upper
alsa-lib(pcm_rate) become one period size more advanced than the lower
alsa-lib(pcm_hw & kernel).

gstreamer uses noblock and poll method to communicate with the alsa-lib.
The app_ptr unsync situation as described above makes the poll return immediately because
it concludes there is enough space for the ring-buffer via the low-level alsa-lib.
The write function returns immediately because it concludes there is not enough
space for the ring-buffer from the upper-level alsa-lib. Then the loop of poll
and write runs again and again until another period size is available for
ring-buffer.This leads to the cpu 100 problem.

delay_lock  is used to avoid the race condition.

Fixes: https://bugzilla.gnome.org/show_bug.cgi?id=690937
ext/alsa/gstalsasink.c
ext/alsa/gstalsasink.h