diff options
author | Wim Taymans <wim.taymans@collabora.co.uk> | 2009-03-26 22:05:31 +0100 |
---|---|---|
committer | Wim Taymans <wim@metal.(none)> | 2009-03-26 22:05:31 +0100 |
commit | 4446f9972dcd2fb481b60d5092135283ea3523b0 (patch) | |
tree | d8fdb6c84719c8b8d45da47ee67d0712908352bb | |
parent | e15cf9bc12eb0065e19c331de3d6013465449425 (diff) |
clock: make UNSCHEDULED checks threadsafe
Move the checks for using an unscheduled entry from the unsafe GstClock to the
SystemClock object so that we can perform the correct locking.
fix a leak and potential deadlock then the async thread fails to start.
Sprinkle some G_LIKELY around because we can.
-rw-r--r-- | gst/gstclock.c | 20 | ||||
-rw-r--r-- | gst/gstsystemclock.c | 34 |
2 files changed, 28 insertions, 26 deletions
diff --git a/gst/gstclock.c b/gst/gstclock.c index 15070d0658..e21ccc3ae6 100644 --- a/gst/gstclock.c +++ b/gst/gstclock.c @@ -372,10 +372,6 @@ gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter) if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested))) goto invalid_time; - /* a previously unscheduled entry cannot be scheduled again */ - if (G_UNLIKELY (entry->status == GST_CLOCK_UNSCHEDULED)) - goto unscheduled; - cclass = GST_CLOCK_GET_CLASS (clock); GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "waiting on clock entry %p", id); @@ -420,12 +416,6 @@ invalid_time: "invalid time requested, returning _BADTIME"); return GST_CLOCK_BADTIME; } -unscheduled: - { - GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, - "entry was unscheduled return _UNSCHEDULED"); - return GST_CLOCK_UNSCHEDULED; - } not_supported: { GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported"); @@ -473,10 +463,6 @@ gst_clock_id_wait_async (GstClockID id, if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested))) goto invalid_time; - /* a previously unscheduled entry cannot be scheduled again */ - if (G_UNLIKELY (entry->status == GST_CLOCK_UNSCHEDULED)) - goto unscheduled; - cclass = GST_CLOCK_GET_CLASS (clock); if (G_UNLIKELY (cclass->wait_async == NULL)) @@ -497,12 +483,6 @@ invalid_time: "invalid time requested, returning _BADTIME"); return GST_CLOCK_BADTIME; } -unscheduled: - { - GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, - "entry was unscheduled return _UNSCHEDULED"); - return GST_CLOCK_UNSCHEDULED; - } not_supported: { GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported"); diff --git a/gst/gstsystemclock.c b/gst/gstsystemclock.c index 003f7a3cea..bc87ab7de8 100644 --- a/gst/gstsystemclock.c +++ b/gst/gstsystemclock.c @@ -675,10 +675,20 @@ gst_system_clock_id_wait_jitter (GstClock * clock, GstClockEntry * entry, GstClockReturn ret; GST_OBJECT_LOCK (clock); + if (G_UNLIKELY (entry->status == GST_CLOCK_UNSCHEDULED)) + goto was_unscheduled; + ret = gst_system_clock_id_wait_jitter_unlocked (clock, entry, jitter, TRUE); GST_OBJECT_UNLOCK (clock); return ret; + + /* ERRORS */ +was_unscheduled: + { + GST_OBJECT_UNLOCK (clock); + return GST_CLOCK_UNSCHEDULED; + } } /* Start the async clock thread. Must be called with the object lock @@ -688,12 +698,12 @@ gst_system_clock_start_async (GstSystemClock * clock) { GError *error = NULL; - if (clock->thread != NULL) + if (G_LIKELY (clock->thread != NULL)) return TRUE; /* Thread already running. Nothing to do */ clock->thread = g_thread_create ((GThreadFunc) gst_system_clock_async_thread, clock, TRUE, &error); - if (error) + if (G_UNLIKELY (error)) goto no_thread; /* wait for it to spin up */ @@ -705,6 +715,7 @@ gst_system_clock_start_async (GstSystemClock * clock) no_thread: { g_warning ("could not create async clock thread: %s", error->message); + g_error_free (error); } return FALSE; } @@ -727,11 +738,13 @@ gst_system_clock_id_wait_async (GstClock * clock, GstClockEntry * entry) GST_CAT_DEBUG (GST_CAT_CLOCK, "adding async entry %p", entry); GST_OBJECT_LOCK (clock); - /* Start the clock async thread if needed */ - if (!gst_system_clock_start_async (sysclock)) + if (G_UNLIKELY (!gst_system_clock_start_async (sysclock))) goto thread_error; + if (G_UNLIKELY (entry->status == GST_CLOCK_UNSCHEDULED)) + goto was_unscheduled; + if (clock->entries) head = clock->entries->data; else @@ -769,9 +782,18 @@ gst_system_clock_id_wait_async (GstClock * clock, GstClockEntry * entry) return GST_CLOCK_OK; + /* ERRORS */ thread_error: - /* Could not start the async clock thread */ - return GST_CLOCK_ERROR; + { + /* Could not start the async clock thread */ + GST_OBJECT_UNLOCK (clock); + return GST_CLOCK_ERROR; + } +was_unscheduled: + { + GST_OBJECT_UNLOCK (clock); + return GST_CLOCK_UNSCHEDULED; + } } /* unschedule an entry. This will set the state of the entry to GST_CLOCK_UNSCHEDULED |