Commit df30f600 authored by Wim Taymans's avatar Wim Taymans
Browse files

clock: fix 2 wakeup races.

when an entry being waited on in the async thread is unscheduled, clear the
wakeup queue so we can continue waiting on other entries.
When an entry being waited on in the async thread is unlocked because an earlier
entry was added to the list, set the entry to OK again. This makes sure that
only the entries being waited on have the BUSY flag set and wake up the timer
poll when they are unscheduled.
parent ea554b1d
......@@ -374,6 +374,7 @@ gst_system_clock_async_thread (GstClock * clock)
/* if it was unscheduled, just move on to the next entry */
if (entry->status == GST_CLOCK_UNSCHEDULED) {
GST_CAT_DEBUG (GST_CAT_CLOCK, "entry %p was unscheduled", entry);
gst_system_clock_clear_async_wakeups_unlocked (sysclock);
goto next_entry;
......@@ -407,6 +408,7 @@ gst_system_clock_async_thread (GstClock * clock)
gst_system_clock_clear_async_wakeups_unlocked (sysclock);
if (entry->type == GST_CLOCK_ENTRY_PERIODIC) {
GST_CAT_DEBUG (GST_CAT_CLOCK, "updating periodic entry %p", entry);
/* adjust time now */
entry->time = requested + entry->interval;
/* and resort the list now */
......@@ -426,6 +428,13 @@ gst_system_clock_async_thread (GstClock * clock)
GST_CAT_DEBUG (GST_CAT_CLOCK, "async entry %p needs restart", entry);
/* clear async wakeups, if any */
gst_system_clock_clear_async_wakeups_unlocked (sysclock);
if (clock->entries->data != entry) {
/* if the new head is not this entry, we set the entry back to the OK
* state. This is needed so that the _unschedule() code can see if an
* entry is currently being waited on (when its state is BUSY). */
entry->status = GST_CLOCK_OK;
......@@ -169,6 +169,7 @@ GST_START_TEST (test_single_shot)
GST_DEBUG ("waiting id %p", id);
result = gst_clock_id_wait_async (id, ok_callback, NULL);
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
GST_DEBUG ("waiting id %p", id2);
result = gst_clock_id_wait_async (id2, error_callback, NULL);
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
......@@ -177,9 +178,11 @@ GST_START_TEST (test_single_shot)
gst_clock_id_unschedule (id2);
GST_DEBUG ("canceled id %p", id2);
gst_clock_id_unref (id2);
g_usleep (TIME_UNIT / (2 * 1000));
gst_clock_id_unschedule (id);
/* wait for the entry to time out */
g_usleep (TIME_UNIT / 1000 * 5);
fail_unless (((GstClockEntry *) id)->status == GST_CLOCK_OK,
"Waiting did not finish");
gst_clock_id_unref (id);
gst_object_unref (clock);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment