summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThibault Saunier <tsaunier@igalia.com>2020-11-19 22:41:40 -0300
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>2020-11-25 00:25:16 +0000
commitf5c3a0c9a0cace2ff90f427132ceb428afd63a3e (patch)
treeb3c7798aae7b2c19bd2f2188a829d65fd22d1e6a
parent3da3e8825b02112de0a3605270d6f79f687f2f58 (diff)
scenario: Add a 'non-blocking' flag to the `wait` signal
This way we can execute actions that will lead to the signal emission later in the execution. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-devtools/-/merge_requests/228>
-rw-r--r--validate/gst/validate/gst-validate-scenario.c52
1 files changed, 42 insertions, 10 deletions
diff --git a/validate/gst/validate/gst-validate-scenario.c b/validate/gst/validate/gst-validate-scenario.c
index 729e709..00699cc 100644
--- a/validate/gst/validate/gst-validate-scenario.c
+++ b/validate/gst/validate/gst-validate-scenario.c
@@ -237,7 +237,7 @@ struct _GstValidateScenarioPrivate
guint execute_actions_source_id; /* MT safe. Protect with SCENARIO_LOCK */
guint wait_id;
- guint signal_handler_id;
+ guint signal_handler_id; /* MT safe. Protect with SCENARIO_LOCK */
guint action_execution_interval;
/* Name of message the wait action is waiting for */
@@ -2725,12 +2725,13 @@ stop_waiting (GstValidateAction * action)
static void
stop_waiting_signal (GstStructure * data)
{
+ guint sigid = 0;
GstElement *target;
GstValidateAction *action;
GstValidateScenario *scenario;
gst_structure_get (data, "target", G_TYPE_POINTER, &target,
- "action", G_TYPE_POINTER, &action, NULL);
+ "action", G_TYPE_POINTER, &action, "sigid", G_TYPE_UINT, &sigid, NULL);
gst_structure_free (data);
scenario = gst_validate_action_get_scenario (action);
@@ -2738,9 +2739,13 @@ stop_waiting_signal (GstStructure * data)
g_assert (scenario);
gst_validate_printf (scenario, "Stop waiting for signal\n");
- g_signal_handler_disconnect (target, scenario->priv->signal_handler_id);
+ SCENARIO_LOCK (scenario);
+ g_signal_handler_disconnect (target,
+ sigid ? sigid : scenario->priv->signal_handler_id);
+ if (!sigid)
+ scenario->priv->signal_handler_id = 0;
+ SCENARIO_UNLOCK (scenario);
- scenario->priv->signal_handler_id = 0;
gst_validate_action_set_done (action);
_add_execute_actions_gsource (scenario);
gst_object_unref (scenario);
@@ -2801,10 +2806,12 @@ static GstValidateExecuteActionReturn
_execute_wait_for_signal (GstValidateScenario * scenario,
GstValidateAction * action)
{
+ gboolean non_blocking;
GstValidateScenarioPrivate *priv = scenario->priv;
const gchar *signal_name = gst_structure_get_string
(action->structure, "signal-name");
GstElement *target;
+ GstStructure *data;
DECLARE_AND_GET_PIPELINE (scenario, action);
if (signal_name == NULL) {
@@ -2826,14 +2833,29 @@ _execute_wait_for_signal (GstValidateScenario * scenario,
priv->execute_actions_source_id = 0;
}
- priv->signal_handler_id =
- g_signal_connect_swapped (target, signal_name,
- (GCallback) stop_waiting_signal, gst_structure_new ("a", "action",
- G_TYPE_POINTER, action, "target", G_TYPE_POINTER, target, NULL));
+ data =
+ gst_structure_new ("a", "action", G_TYPE_POINTER, action, "target",
+ G_TYPE_POINTER, target, NULL);
+ SCENARIO_LOCK (scenario);
+ priv->signal_handler_id = g_signal_connect_swapped (target, signal_name,
+ (GCallback) stop_waiting_signal, data);
+
+ non_blocking =
+ gst_structure_get_boolean (action->structure, "non-blocking",
+ &non_blocking);
+ if (non_blocking) {
+ gst_validate_action_ref (action);
+ gst_structure_set (data, "sigid", G_TYPE_UINT, priv->signal_handler_id,
+ NULL);
+ priv->signal_handler_id = 0;
+ }
+ SCENARIO_UNLOCK (scenario);
gst_object_unref (pipeline);
- return GST_VALIDATE_EXECUTE_ACTION_ASYNC;
+
+ return non_blocking ? GST_VALIDATE_EXECUTE_ACTION_NON_BLOCKING :
+ GST_VALIDATE_EXECUTE_ACTION_ASYNC;
}
static gboolean
@@ -6403,7 +6425,17 @@ register_action_types (void)
},
{
.name = "signal-name",
- .description = "The name of the signal to wait for on @target-element-name",
+ .description = "The name of the signal to wait for on @target-element-name."
+ " To ensure that the signal is executed without blocking while waiting for it"
+ " you can set the field 'non-blocking=true'.",
+ .mandatory = FALSE,
+ .types = "string",
+ NULL
+ },
+ {
+ .name = "non-blocking",
+ .description = "**Only for signals**."
+ " Ensures that the signal is emitted without a blocking waiting.",
.mandatory = FALSE,
.types = "string",
NULL