summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2009-03-26 22:05:31 +0100
committerWim Taymans <wim@metal.(none)>2009-03-26 22:05:31 +0100
commit4446f9972dcd2fb481b60d5092135283ea3523b0 (patch)
treed8fdb6c84719c8b8d45da47ee67d0712908352bb
parente15cf9bc12eb0065e19c331de3d6013465449425 (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.c20
-rw-r--r--gst/gstsystemclock.c34
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