mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-27 18:50:48 +00:00
pulse: Add some documentation about threading and synchronisation
This gives a quick introduction to how the pulsesink/pulsesrc code interacts with the pa_threaded_mainloop that we start up to communicate with the server.
This commit is contained in:
parent
0ed08ac3fd
commit
2a3adec2f7
2 changed files with 29 additions and 2 deletions
|
@ -107,6 +107,30 @@ typedef struct _GstPulseRingBufferClass GstPulseRingBufferClass;
|
|||
|
||||
typedef struct _GstPulseContext GstPulseContext;
|
||||
|
||||
/* A note on threading.
|
||||
*
|
||||
* We use a pa_threaded_mainloop to interact with the PulseAudio server. This
|
||||
* starts up a separate thread that runs a mainloop to carry back events,
|
||||
* messages and timing updates from the PulseAudio server.
|
||||
*
|
||||
* In most cases, the PulseAudio API we use communicates with the server and
|
||||
* processes replies asynchronously. Operations on PA objects that result in
|
||||
* such communication are protected with a pa_threaded_mainloop_lock() and
|
||||
* pa_threaded_mainloop_unlock(). These guarantee mutual exclusion with the
|
||||
* mainloop thread -- when an iteration of the mainloop thread begins, it first
|
||||
* tries to acquire this lock, and cannot do so if our code also holds that
|
||||
* lock.
|
||||
*
|
||||
* When we need to complete an operation synchronously, we use
|
||||
* pa_threaded_mainloop_wait() and pa_threaded_mainloop_signal(). These work
|
||||
* much as pthread conditionals do. pa_threaded_mainloop_wait() is called with
|
||||
* the mainloop lock held. It releases the lock (thereby allowing the mainloop
|
||||
* to execute), and waits till one of our callbacks to be executed by the
|
||||
* mainloop thread calls pa_threaded_mainloop_signal(). At the end of the
|
||||
* mainloop iteration, the pa_threaded_mainloop_wait() will reacquire the
|
||||
* mainloop lock and return control to the caller.
|
||||
*/
|
||||
|
||||
/* Store the PA contexts in a hash table to allow easy sharing among
|
||||
* multiple instances of the sink. Keys are $context_name@$server_name
|
||||
* (strings) and values should be GstPulseContext pointers.
|
||||
|
@ -1161,7 +1185,7 @@ gst_pulseringbuffer_clear (GstAudioRingBuffer * buf)
|
|||
pa_threaded_mainloop_unlock (mainloop);
|
||||
}
|
||||
|
||||
/* called from pulse with the mainloop lock */
|
||||
/* called from pulse thread with the mainloop lock */
|
||||
static void
|
||||
mainloop_enter_defer_cb (pa_mainloop_api * api, void *userdata)
|
||||
{
|
||||
|
@ -1248,7 +1272,7 @@ gst_pulseringbuffer_pause (GstAudioRingBuffer * buf)
|
|||
return res;
|
||||
}
|
||||
|
||||
/* called from pulse with the mainloop lock */
|
||||
/* called from pulse thread with the mainloop lock */
|
||||
static void
|
||||
mainloop_leave_defer_cb (pa_mainloop_api * api, void *userdata)
|
||||
{
|
||||
|
|
|
@ -60,6 +60,9 @@ GST_DEBUG_CATEGORY_EXTERN (pulse_debug);
|
|||
#define DEFAULT_MUTE FALSE
|
||||
#define MAX_VOLUME 10.0
|
||||
|
||||
/* See the pulsesink code for notes on how we interact with the PA mainloop
|
||||
* thread. */
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
|
Loading…
Reference in a new issue