summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorArun Raghavan <arun@accosted.net>2014-09-29 20:18:08 +0530
committerArun Raghavan <arun@accosted.net>2014-09-30 06:28:50 +0530
commit0ed08ac3fd1a086ada5ce8b70045994c4d25cc80 (patch)
tree44e2dce90e810d0b0b805b22a2adca5471c70dae /ext
parenteca3e2474da729d239c5ff5eae41075cd1f0c20b (diff)
pulsesink: Make emitting stream status messages synchronous
The stream status messages are emitted in the PA mainloop thread, which means the mainloop lock is taken, followed by the Gst object lock (by gst_element_post_message()). In all other locations, the order of locking is reversed (this is unavoidable in a bunch of cases where the object lock is taken by GstBaseSink or GstAudioBaseSink, and then we get control to take the mainloop lock). The only way to guarantee that the defer callback for stream status messages doesn't deadlock is to either stop posting those messages, or make sure that the message emission is completed before we proceed to any point that might take the object lock before the mainloop lock (which is what we do after this patch). https://bugzilla.gnome.org/show_bug.cgi?id=736071
Diffstat (limited to 'ext')
-rw-r--r--ext/pulse/pulsesink.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/ext/pulse/pulsesink.c b/ext/pulse/pulsesink.c
index e580afce2..e77ce8d5e 100644
--- a/ext/pulse/pulsesink.c
+++ b/ext/pulse/pulsesink.c
@@ -1209,6 +1209,14 @@ gst_pulseringbuffer_start (GstAudioRingBuffer * buf)
g_atomic_int_get (&GST_AUDIO_BASE_SINK (psink)->eos_rendering))
gst_pulsering_set_corked (pbuf, FALSE, FALSE);
+ /* Wait for the stream status message to be posted. This needs to be done
+ * synchronously because the callback will take the mainloop lock
+ * (implicitly) and then take the GST_OBJECT_LOCK. Everywhere else, we take
+ * the locks in the reverse order, so not doing this synchronously could
+ * cause a deadlock. */
+ GST_DEBUG_OBJECT (psink, "waiting for stream status (ENTER) to be posted");
+ pa_threaded_mainloop_wait (mainloop);
+
pa_threaded_mainloop_unlock (mainloop);
return TRUE;
@@ -1315,6 +1323,14 @@ cleanup:
pa_mainloop_api_once (pa_threaded_mainloop_get_api (mainloop),
mainloop_leave_defer_cb, psink);
+ /* Wait for the stream status message to be posted. This needs to be done
+ * synchronously because the callback will take the mainloop lock
+ * (implicitly) and then take the GST_OBJECT_LOCK. Everywhere else, we take
+ * the locks in the reverse order, so not doing this synchronously could
+ * cause a deadlock. */
+ GST_DEBUG_OBJECT (psink, "waiting for stream status (LEAVE) to be posted");
+ pa_threaded_mainloop_wait (mainloop);
+
pa_threaded_mainloop_unlock (mainloop);
return res;