diff --git a/gst/gstsystemclock.c b/gst/gstsystemclock.c index bc4fe2b05d..b65c0d877b 100644 --- a/gst/gstsystemclock.c +++ b/gst/gstsystemclock.c @@ -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; + } continue; default: GST_CAT_DEBUG (GST_CAT_CLOCK, diff --git a/tests/check/gst/gstsystemclock.c b/tests/check/gst/gstsystemclock.c index 52406e0591..53cb5779b1 100644 --- a/tests/check/gst/gstsystemclock.c +++ b/tests/check/gst/gstsystemclock.c @@ -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);