summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorThibault Saunier <tsaunier@igalia.com>2021-09-01 17:35:45 -0400
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>2021-09-03 15:56:31 +0000
commitcd3aa029d6b85405b2318be109bacaabe6522d1a (patch)
tree67e90d7f6e7ca4804e42eddc1dc1daec6a4495f4 /ext
parentf7cbbb5d9a1ff67f94477d8a7f7d4357416ea2e3 (diff)
downloadgstreamer-plugins-bad-cd3aa029d6b85405b2318be109bacaabe6522d1a.tar.gz
wpe: Fix race condition on teardown
There was a race when going to PAUSED while pushing a buffer to the pipeline process (where we weren't even cancelling anything). This rework base all the cancellation around the GCancellable "cancelled" signal trying to ensure that the streaming thread will not block once a cancel operation happens. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2504>
Diffstat (limited to 'ext')
-rw-r--r--ext/wpe/wpe-extension/gstwpeaudiosink.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/ext/wpe/wpe-extension/gstwpeaudiosink.c b/ext/wpe/wpe-extension/gstwpeaudiosink.c
index d5d8a944a..66a6c4d93 100644
--- a/ext/wpe/wpe-extension/gstwpeaudiosink.c
+++ b/ext/wpe/wpe-extension/gstwpeaudiosink.c
@@ -186,11 +186,28 @@ unlock (GstBaseSink * sink)
GstWpeAudioSink *self = GST_WPE_AUDIO_SINK (sink);
g_cancellable_cancel (self->cancellable);
+
+ return TRUE;
+}
+
+static gboolean
+unlock_stop (GstBaseSink * sink)
+{
+ GstWpeAudioSink *self = GST_WPE_AUDIO_SINK (sink);
+ GCancellable *cancellable = self->cancellable;
+
+ self->cancellable = g_cancellable_new ();
+ g_object_unref (cancellable);
+
+ return TRUE;
+}
+
+static void
+_cancelled_cb (GCancellable * _cancellable, GstWpeAudioSink * self)
+{
g_mutex_lock (&self->buf_lock);
g_cond_broadcast (&self->buf_cond);
g_mutex_unlock (&self->buf_lock);
-
- return TRUE;
}
static gboolean
@@ -205,7 +222,7 @@ stop (GstBaseSink * sink)
}
/* Stop processing and claim buffers back */
- unlock (sink);
+ g_cancellable_cancel (self->cancellable);
GST_DEBUG_OBJECT (sink, "Stopping %d", self->id);
gst_wpe_extension_send_message (webkit_user_message_new ("gstwpe.stop",
@@ -220,9 +237,22 @@ change_state (GstElement * element, GstStateChange transition)
GstWpeAudioSink *self = GST_WPE_AUDIO_SINK (element);
switch (transition) {
+ case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+ {
+ if (g_cancellable_is_cancelled (self->cancellable)) {
+ GCancellable *cancellable = self->cancellable;
+ self->cancellable = g_cancellable_new ();
+
+ g_object_unref (cancellable);
+ }
+ break;
+ }
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+ g_cancellable_cancel (self->cancellable);
+
gst_wpe_extension_send_message (webkit_user_message_new ("gstwpe.pause",
- g_variant_new_uint32 (self->id)), self->cancellable, NULL, NULL);
+ g_variant_new_uint32 (self->id)), NULL, NULL, NULL);
+
break;
default:
break;
@@ -250,6 +280,8 @@ gst_wpe_audio_sink_init (GstWpeAudioSink * self)
g_return_if_fail (pad_template != NULL);
self->cancellable = g_cancellable_new ();
+ g_cancellable_connect (self->cancellable,
+ G_CALLBACK (_cancelled_cb), self, NULL);
}
static void
@@ -273,6 +305,7 @@ gst_wpe_audio_sink_class_init (GstWpeAudioSinkClass * klass)
gstelement_class->change_state = GST_DEBUG_FUNCPTR (change_state);
gstbasesink_class->stop = GST_DEBUG_FUNCPTR (stop);
gstbasesink_class->unlock = GST_DEBUG_FUNCPTR (unlock);
+ gstbasesink_class->unlock_stop = GST_DEBUG_FUNCPTR (unlock_stop);
gstbasesink_class->render = GST_DEBUG_FUNCPTR (render);
gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (set_caps);
}