gst_task_configure_name (task);
while (G_LIKELY (GET_TASK_STATE (task) != GST_TASK_STOPPED)) {
- if (G_UNLIKELY (GET_TASK_STATE (task) == GST_TASK_PAUSED)) {
+ GST_OBJECT_LOCK (task);
+ while (G_UNLIKELY (GST_TASK_STATE (task) == GST_TASK_PAUSED)) {
+ g_rec_mutex_unlock (lock);
+
+ GST_TASK_SIGNAL (task);
+ GST_INFO_OBJECT (task, "Task going to paused");
+ GST_TASK_WAIT (task);
+ GST_INFO_OBJECT (task, "Task resume from paused");
+ GST_OBJECT_UNLOCK (task);
+ /* locking order.. */
+ g_rec_mutex_lock (lock);
GST_OBJECT_LOCK (task);
- while (G_UNLIKELY (GST_TASK_STATE (task) == GST_TASK_PAUSED)) {
- g_rec_mutex_unlock (lock);
+ }
- GST_TASK_SIGNAL (task);
- GST_INFO_OBJECT (task, "Task going to paused");
- GST_TASK_WAIT (task);
- GST_INFO_OBJECT (task, "Task resume from paused");
- GST_OBJECT_UNLOCK (task);
- /* locking order.. */
- g_rec_mutex_lock (lock);
-
- GST_OBJECT_LOCK (task);
- if (G_UNLIKELY (GET_TASK_STATE (task) == GST_TASK_STOPPED)) {
- GST_OBJECT_UNLOCK (task);
- goto done;
- }
- }
+ if (G_UNLIKELY (GET_TASK_STATE (task) == GST_TASK_STOPPED)) {
+ GST_OBJECT_UNLOCK (task);
+ break;
+ } else {
GST_OBJECT_UNLOCK (task);
}
task->func (task->user_data);
}
-done:
+
g_rec_mutex_unlock (lock);
GST_OBJECT_LOCK (task);
static GRecMutex task_mutex;
+#define TEST_RACE_ITERATIONS 1000
+
+static void
+task_signal_pause_func (void *data)
+{
+ GstTask **t = data;
+
+ g_mutex_lock (&task_lock);
+ GST_DEBUG ("signal");
+ g_cond_signal (&task_cond);
+
+ gst_task_pause (*t);
+ g_mutex_unlock (&task_lock);
+}
+
+GST_START_TEST (test_pause_stop_race)
+{
+ guint it = TEST_RACE_ITERATIONS;
+ GstTask *t;
+ gboolean ret;
+
+ t = gst_task_new (task_signal_pause_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);
+
+ while (it-- > 0) {
+ g_mutex_lock (&task_lock);
+ GST_DEBUG ("starting");
+ ret = gst_task_start (t);
+ fail_unless (ret == TRUE);
+ /* wait for it to spin up */
+ GST_DEBUG ("waiting");
+ g_cond_wait (&task_cond, &task_lock);
+ GST_DEBUG ("done waiting");
+ g_mutex_unlock (&task_lock);
+
+ GST_DEBUG ("starting");
+ ret = gst_task_stop (t);
+ fail_unless (ret == TRUE);
+
+ GST_DEBUG ("joining");
+ ret = gst_task_join (t);
+ fail_unless (ret == TRUE);
+ }
+
+ g_cond_clear (&task_cond);
+ g_mutex_clear (&task_lock);
+
+ gst_object_unref (t);
+}
+
+GST_END_TEST;
+
static void
task_func2 (void *data)
{
tcase_add_test (tc_chain, test_lock);
tcase_add_test (tc_chain, test_lock_start);
tcase_add_test (tc_chain, test_join);
+ tcase_add_test (tc_chain, test_pause_stop_race);
return s;
}