examples: fix another race condition

Fix a race condition that caused randome deadlocks on EOS.
This commit is contained in:
Josep Torra 2013-09-24 18:48:24 +02:00
parent 92098e66af
commit a628153260

View file

@ -1102,14 +1102,12 @@ handle_queued_objects (APP_STATE_T * state)
GstMiniObject *object = NULL; GstMiniObject *object = NULL;
gboolean done = FALSE; gboolean done = FALSE;
if (g_async_queue_length (state->queue) == 0) {
return FALSE;
}
g_mutex_lock (state->queue_lock); g_mutex_lock (state->queue_lock);
if (state->flushing) { if (state->flushing) {
g_cond_broadcast (state->cond); g_cond_broadcast (state->cond);
done = TRUE; done = TRUE;
} else if (g_async_queue_length (state->queue) == 0) {
done = TRUE;
} }
g_mutex_unlock (state->queue_lock); g_mutex_unlock (state->queue_lock);
@ -1180,6 +1178,8 @@ handle_queued_objects (APP_STATE_T * state)
state->popped_obj = object; state->popped_obj = object;
g_cond_broadcast (state->cond); g_cond_broadcast (state->cond);
g_mutex_unlock (state->queue_lock); g_mutex_unlock (state->queue_lock);
g_mutex_lock (state->flow_lock);
g_mutex_unlock (state->flow_lock);
} }
return FALSE; return FALSE;
@ -1197,16 +1197,16 @@ queue_object (APP_STATE_T * state, GstMiniObject * obj, gboolean synchronous)
goto beach; goto beach;
} }
g_mutex_lock (state->queue_lock);
g_async_queue_push (state->queue, obj); g_async_queue_push (state->queue, obj);
if (synchronous) { if (synchronous) {
/* Waiting for object to be handled */ /* Waiting for object to be handled */
g_mutex_lock (state->queue_lock);
do { do {
g_cond_wait (state->cond, state->queue_lock); g_cond_wait (state->cond, state->queue_lock);
} while (!state->flushing && state->popped_obj != obj); } while (!state->flushing && state->popped_obj != obj);
g_mutex_unlock (state->queue_lock);
} }
g_mutex_unlock (state->queue_lock);
beach: beach:
g_mutex_unlock (state->flow_lock); g_mutex_unlock (state->flow_lock);
@ -1243,7 +1243,7 @@ events_cb (GstPad * pad, GstPadProbeInfo * probe_info, gpointer user_data)
flush_stop (state); flush_stop (state);
break; break;
case GST_EVENT_EOS: case GST_EVENT_EOS:
queue_object (state, GST_MINI_OBJECT_CAST (gst_event_ref (event)), TRUE); queue_object (state, GST_MINI_OBJECT_CAST (gst_event_ref (event)), FALSE);
break; break;
default: default:
break; break;
@ -1592,7 +1592,6 @@ eos_cb (GstBus * bus, GstMessage * msg, APP_STATE_T * state)
{ {
if (GST_MESSAGE_SRC (msg) == GST_OBJECT (state->pipeline)) { if (GST_MESSAGE_SRC (msg) == GST_OBJECT (state->pipeline)) {
g_print ("End-Of-Stream reached.\n"); g_print ("End-Of-Stream reached.\n");
flush_start (state);
gst_element_set_state (state->pipeline, GST_STATE_READY); gst_element_set_state (state->pipeline, GST_STATE_READY);
} }
} }