mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-09-03 02:33:53 +00:00
gst-validate-scenario: Fix (another) race condition in EOS handling
Since gst_validate_action_set_done() is asynchronous, the bus EOS handler may already be running before the action is actually finished. This patch ensures that is not a problem.
This commit is contained in:
parent
a443b921a2
commit
af205f63b7
1 changed files with 28 additions and 1 deletions
|
@ -108,6 +108,7 @@ static GstValidateActionType *_find_action_type (const gchar * type_name);
|
||||||
static GstValidateExecuteActionReturn
|
static GstValidateExecuteActionReturn
|
||||||
_fill_action (GstValidateScenario * scenario, GstValidateAction * action,
|
_fill_action (GstValidateScenario * scenario, GstValidateAction * action,
|
||||||
GstStructure * structure, gboolean add_to_lists);
|
GstStructure * structure, gboolean add_to_lists);
|
||||||
|
static gboolean _action_set_done (GstValidateAction * action);
|
||||||
|
|
||||||
/* GstValidateScenario is not really thread safe and
|
/* GstValidateScenario is not really thread safe and
|
||||||
* everything should be done from the thread GstValidate
|
* everything should be done from the thread GstValidate
|
||||||
|
@ -246,6 +247,7 @@ struct _GstValidateActionPrivate
|
||||||
|
|
||||||
GWeakRef scenario;
|
GWeakRef scenario;
|
||||||
gboolean needs_playback_parsing;
|
gboolean needs_playback_parsing;
|
||||||
|
gboolean pending_set_done;
|
||||||
};
|
};
|
||||||
|
|
||||||
static JsonNode *
|
static JsonNode *
|
||||||
|
@ -3114,6 +3116,27 @@ message_cb (GstBus * bus, GstMessage * message, GstValidateScenario * scenario)
|
||||||
GstStructure *s;
|
GstStructure *s;
|
||||||
|
|
||||||
GST_VALIDATE_SCENARIO_EOS_HANDLING_LOCK (scenario);
|
GST_VALIDATE_SCENARIO_EOS_HANDLING_LOCK (scenario);
|
||||||
|
{
|
||||||
|
/* gst_validate_action_set_done() does not finish the action
|
||||||
|
* immediately. Instead, it posts a task to the main thread to do most
|
||||||
|
* of the work in _action_set_done().
|
||||||
|
*
|
||||||
|
* While the EOS handling lock guarantees that if an action had to call
|
||||||
|
* gst_validate_action_set_done() it has done so, it does not guarantee
|
||||||
|
* that _action_set_done() has been called.
|
||||||
|
*
|
||||||
|
* Is it possible that this handler is run before _action_set_done(), so
|
||||||
|
* we check at this point for actions that have a pending_set_done and
|
||||||
|
* call it before continuing. */
|
||||||
|
GList *actions = g_list_copy (priv->actions);
|
||||||
|
GList *i;
|
||||||
|
for (i = actions; i; i = i->next) {
|
||||||
|
GstValidateAction *action = (GstValidateAction *) i->data;
|
||||||
|
if (action->priv->pending_set_done)
|
||||||
|
_action_set_done (action);
|
||||||
|
}
|
||||||
|
g_list_free (actions);
|
||||||
|
}
|
||||||
|
|
||||||
if (!is_error) {
|
if (!is_error) {
|
||||||
priv->got_eos = TRUE;
|
priv->got_eos = TRUE;
|
||||||
|
@ -4237,7 +4260,7 @@ _action_set_done (GstValidateAction * action)
|
||||||
GstClockTime execution_duration;
|
GstClockTime execution_duration;
|
||||||
GstValidateScenario *scenario = gst_validate_action_get_scenario (action);
|
GstValidateScenario *scenario = gst_validate_action_get_scenario (action);
|
||||||
|
|
||||||
if (scenario == NULL)
|
if (scenario == NULL || !action->priv->pending_set_done)
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
|
|
||||||
execution_duration = gst_util_get_timestamp () - action->priv->execution_time;
|
execution_duration = gst_util_get_timestamp () - action->priv->execution_time;
|
||||||
|
@ -4268,6 +4291,7 @@ _action_set_done (GstValidateAction * action)
|
||||||
}
|
}
|
||||||
gst_object_unref (scenario);
|
gst_object_unref (scenario);
|
||||||
|
|
||||||
|
action->priv->pending_set_done = FALSE;
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4298,6 +4322,9 @@ gst_validate_action_set_done (GstValidateAction * action)
|
||||||
gst_validate_action_unref (action);
|
gst_validate_action_unref (action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_assert (!action->priv->pending_set_done);
|
||||||
|
action->priv->pending_set_done = TRUE;
|
||||||
|
|
||||||
g_main_context_invoke_full (NULL, G_PRIORITY_DEFAULT_IDLE,
|
g_main_context_invoke_full (NULL, G_PRIORITY_DEFAULT_IDLE,
|
||||||
(GSourceFunc) _action_set_done,
|
(GSourceFunc) _action_set_done,
|
||||||
gst_mini_object_ref (GST_MINI_OBJECT (action)),
|
gst_mini_object_ref (GST_MINI_OBJECT (action)),
|
||||||
|
|
Loading…
Reference in a new issue