return res;
}
-
-/**
- * gst_task_set_state:
- * @task: a #GstTask
- * @state: the new task state
- *
- * Sets the state of @task to @state.
- *
- * The @task must have a lock associated with it using
- * gst_task_set_lock() when going to GST_TASK_STARTED or GST_TASK_PAUSED or
- * this function will return %FALSE.
- *
- * MT safe.
- *
- * Returns: %TRUE if the state could be changed.
- */
-gboolean
-gst_task_set_state (GstTask * task, GstTaskState state)
+static inline gboolean
+gst_task_set_state_unlocked (GstTask * task, GstTaskState state)
{
GstTaskState old;
gboolean res = TRUE;
- g_return_val_if_fail (GST_IS_TASK (task), FALSE);
-
GST_DEBUG_OBJECT (task, "Changing task %p to state %d", task, state);
- GST_OBJECT_LOCK (task);
if (state != GST_TASK_STOPPED)
if (G_UNLIKELY (GST_TASK_GET_LOCK (task) == NULL))
goto no_lock;
break;
}
}
- GST_OBJECT_UNLOCK (task);
return res;
no_lock:
{
GST_WARNING_OBJECT (task, "state %d set on task without a lock", state);
- GST_OBJECT_UNLOCK (task);
g_warning ("task without a lock can't be set to state %d", state);
return FALSE;
}
}
+
+/**
+ * gst_task_set_state:
+ * @task: a #GstTask
+ * @state: the new task state
+ *
+ * Sets the state of @task to @state.
+ *
+ * The @task must have a lock associated with it using
+ * gst_task_set_lock() when going to GST_TASK_STARTED or GST_TASK_PAUSED or
+ * this function will return %FALSE.
+ *
+ * MT safe.
+ *
+ * Returns: %TRUE if the state could be changed.
+ */
+gboolean
+gst_task_set_state (GstTask * task, GstTaskState state)
+{
+ gboolean res = TRUE;
+
+ g_return_val_if_fail (GST_IS_TASK (task), FALSE);
+
+ GST_OBJECT_LOCK (task);
+ res = gst_task_set_state_unlocked (task, state);
+ GST_OBJECT_UNLOCK (task);
+
+ return res;
+}
+
/**
* gst_task_start:
* @task: The #GstTask to start
return gst_task_set_state (task, GST_TASK_PAUSED);
}
+/**
+ * gst_task_resume:
+ * @task: The #GstTask to resume
+ *
+ * Resume @task in case it was paused. If the task was stopped, it will
+ * remain in that state and this function will return %FALSE.
+ *
+ * Returns: %TRUE if the task could be resumed.
+ *
+ * MT safe.
+ * Since: 1.18
+ */
+gboolean
+gst_task_resume (GstTask * task)
+{
+ gboolean res = FALSE;
+ g_return_val_if_fail (GST_IS_TASK (task), FALSE);
+
+ GST_OBJECT_LOCK (task);
+ if (GET_TASK_STATE (task) != GST_TASK_STOPPED)
+ res = gst_task_set_state_unlocked (task, GST_TASK_STARTED);
+ GST_OBJECT_UNLOCK (task);
+
+ return res;
+}
+
/**
* gst_task_join:
* @task: The #GstTask to join
#define TEST_RACE_ITERATIONS 1000
+static void
+task_resume_func (void *data)
+{
+ g_mutex_lock (&task_lock);
+ g_cond_signal (&task_cond);
+ g_mutex_unlock (&task_lock);
+}
+
+GST_START_TEST (test_resume)
+{
+ GstTask *t;
+
+ t = gst_task_new (task_resume_func, &t, NULL);
+ fail_if (t == NULL);
+
+ g_rec_mutex_init (&task_mutex);
+ gst_task_set_lock (t, &task_mutex);
+
+ g_cond_init (&task_cond);
+ g_mutex_init (&task_lock);
+
+ g_mutex_lock (&task_lock);
+
+ /* Pause the task, and resume it. */
+ fail_unless (gst_task_pause (t));
+ fail_unless (gst_task_resume (t));
+
+ while (GST_TASK_STATE (t) != GST_TASK_STARTED)
+ g_cond_wait (&task_cond, &task_lock);
+
+ fail_unless (gst_task_stop (t));
+ g_mutex_unlock (&task_lock);
+ fail_unless (gst_task_join (t));
+
+ /* Make sure we cannot resume from stopped. */
+ fail_if (gst_task_resume (t));
+
+ gst_object_unref (t);
+}
+
+GST_END_TEST;
+
static void
task_signal_pause_func (void *data)
{
tcase_add_test (tc_chain, test_lock_start);
tcase_add_test (tc_chain, test_join);
tcase_add_test (tc_chain, test_pause_stop_race);
+ tcase_add_test (tc_chain, test_resume);
return s;
}