mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 01:00:37 +00:00
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.
This commit is contained in:
parent
ea554b1d62
commit
df30f60048
2 changed files with 14 additions and 2 deletions
|
@ -374,6 +374,7 @@ gst_system_clock_async_thread (GstClock * clock)
|
||||||
/* if it was unscheduled, just move on to the next entry */
|
/* if it was unscheduled, just move on to the next entry */
|
||||||
if (entry->status == GST_CLOCK_UNSCHEDULED) {
|
if (entry->status == GST_CLOCK_UNSCHEDULED) {
|
||||||
GST_CAT_DEBUG (GST_CAT_CLOCK, "entry %p was unscheduled", entry);
|
GST_CAT_DEBUG (GST_CAT_CLOCK, "entry %p was unscheduled", entry);
|
||||||
|
gst_system_clock_clear_async_wakeups_unlocked (sysclock);
|
||||||
goto next_entry;
|
goto next_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,6 +408,7 @@ gst_system_clock_async_thread (GstClock * clock)
|
||||||
gst_system_clock_clear_async_wakeups_unlocked (sysclock);
|
gst_system_clock_clear_async_wakeups_unlocked (sysclock);
|
||||||
}
|
}
|
||||||
if (entry->type == GST_CLOCK_ENTRY_PERIODIC) {
|
if (entry->type == GST_CLOCK_ENTRY_PERIODIC) {
|
||||||
|
GST_CAT_DEBUG (GST_CAT_CLOCK, "updating periodic entry %p", entry);
|
||||||
/* adjust time now */
|
/* adjust time now */
|
||||||
entry->time = requested + entry->interval;
|
entry->time = requested + entry->interval;
|
||||||
/* and resort the list now */
|
/* 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);
|
GST_CAT_DEBUG (GST_CAT_CLOCK, "async entry %p needs restart", entry);
|
||||||
/* clear async wakeups, if any */
|
/* clear async wakeups, if any */
|
||||||
gst_system_clock_clear_async_wakeups_unlocked (sysclock);
|
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;
|
continue;
|
||||||
default:
|
default:
|
||||||
GST_CAT_DEBUG (GST_CAT_CLOCK,
|
GST_CAT_DEBUG (GST_CAT_CLOCK,
|
||||||
|
|
|
@ -169,6 +169,7 @@ GST_START_TEST (test_single_shot)
|
||||||
GST_DEBUG ("waiting id %p", id);
|
GST_DEBUG ("waiting id %p", id);
|
||||||
result = gst_clock_id_wait_async (id, ok_callback, NULL);
|
result = gst_clock_id_wait_async (id, ok_callback, NULL);
|
||||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||||
|
|
||||||
GST_DEBUG ("waiting id %p", id2);
|
GST_DEBUG ("waiting id %p", id2);
|
||||||
result = gst_clock_id_wait_async (id2, error_callback, NULL);
|
result = gst_clock_id_wait_async (id2, error_callback, NULL);
|
||||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
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_clock_id_unschedule (id2);
|
||||||
GST_DEBUG ("canceled id %p", id2);
|
GST_DEBUG ("canceled id %p", id2);
|
||||||
gst_clock_id_unref (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_clock_id_unref (id);
|
||||||
|
|
||||||
gst_object_unref (clock);
|
gst_object_unref (clock);
|
||||||
|
|
Loading…
Reference in a new issue