From 8d213d51f6557ed9f42f9c3fdd7c7cf5d3af0ac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 8 Feb 2010 08:12:11 +0100 Subject: [PATCH] shapewipe: Fix race condition during shutdown that can lead to a deadlock --- gst/shapewipe/gstshapewipe.c | 20 +++++++++++++++----- gst/shapewipe/gstshapewipe.h | 2 ++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/gst/shapewipe/gstshapewipe.c b/gst/shapewipe/gstshapewipe.c index 7c512df4ed..b8e40404ab 100644 --- a/gst/shapewipe/gstshapewipe.c +++ b/gst/shapewipe/gstshapewipe.c @@ -917,13 +917,18 @@ gst_shape_wipe_video_sink_chain (GstPad * pad, GstBuffer * buffer) GST_TIME_ARGS (timestamp), self->mask_position); g_mutex_lock (self->mask_mutex); + if (self->shutdown) { + gst_buffer_unref (buffer); + return GST_FLOW_WRONG_STATE; + } + if (!self->mask) g_cond_wait (self->mask_cond, self->mask_mutex); if (self->mask == NULL) { g_mutex_unlock (self->mask_mutex); gst_buffer_unref (buffer); - return GST_FLOW_UNEXPECTED; + return GST_FLOW_WRONG_STATE; } else { mask = gst_buffer_ref (self->mask); } @@ -1007,14 +1012,19 @@ gst_shape_wipe_change_state (GstElement * element, GstStateChange transition) switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: + self->shutdown = FALSE; + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + /* Unblock video sink chain function */ + g_mutex_lock (self->mask_mutex); + self->shutdown = TRUE; + g_cond_signal (self->mask_cond); + g_mutex_unlock (self->mask_mutex); + break; default: break; } - /* Unblock video sink chain function */ - if (transition == GST_STATE_CHANGE_PAUSED_TO_READY) - g_cond_signal (self->mask_cond); - if (GST_ELEMENT_CLASS (parent_class)->change_state) ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); diff --git a/gst/shapewipe/gstshapewipe.h b/gst/shapewipe/gstshapewipe.h index 251a0452cb..36b4fc552d 100644 --- a/gst/shapewipe/gstshapewipe.h +++ b/gst/shapewipe/gstshapewipe.h @@ -62,6 +62,8 @@ struct _GstShapeWipe GstVideoFormat fmt; gint width, height; + gboolean shutdown; + gdouble proportion; GstClockTime earliest_time; GstClockTime frame_duration;