diff --git a/subprojects/gstreamer/gst/gst_private.h b/subprojects/gstreamer/gst/gst_private.h index b0e1473083..d775cd381f 100644 --- a/subprojects/gstreamer/gst/gst_private.h +++ b/subprojects/gstreamer/gst/gst_private.h @@ -514,14 +514,11 @@ struct _GstDynamicTypeFactoryClass { /* privat flag used by GstBus / GstMessage */ #define GST_MESSAGE_FLAG_ASYNC_DELIVERY (GST_MINI_OBJECT_FLAG_LAST << 0) -/* private type used by GstClock */ -typedef struct _GstClockWeakRef GstClockWeakRef; - /* private struct used by GstClock and GstSystemClock */ struct _GstClockEntryImpl { GstClockEntry entry; - GstClockWeakRef *weakref; + GWeakRef *clock; GDestroyNotify destroy_entry; gpointer padding[21]; /* padding for allowing e.g. systemclock * to add data in lieu of overridable diff --git a/subprojects/gstreamer/gst/gstclock.c b/subprojects/gstreamer/gst/gstclock.c index 7f6b12408e..365a0e1d79 100644 --- a/subprojects/gstreamer/gst/gstclock.c +++ b/subprojects/gstreamer/gst/gstclock.c @@ -132,60 +132,6 @@ enum #define GST_CLOCK_SLAVE_LOCK(clock) g_mutex_lock (&GST_CLOCK_CAST (clock)->priv->slave_lock) #define GST_CLOCK_SLAVE_UNLOCK(clock) g_mutex_unlock (&GST_CLOCK_CAST (clock)->priv->slave_lock) -/* An atomically ref-counted wrapper around a GWeakRef for a GstClock, created - * by the clock and shared with all its clock entries. - * - * This exists because g_weak_ref_ operations are quite expensive and operate - * with a global GRWLock. _get takes a reader lock, _init and _clear take a - * writer lock. We want to avoid having a GWeakRef in every clock entry. - * - * FIXME: Simplify this with g_atomic_rc_box_new (GWeakRef) once we can depend - * on GLib 2.58. - */ -struct _GstClockWeakRef -{ - gint refcount; - GWeakRef clock; -}; - -static GstClockWeakRef * -gst_clock_weak_ref_new (GstClock * clock) -{ - GstClockWeakRef *weakref = g_slice_new (GstClockWeakRef); - - weakref->refcount = 1; - g_weak_ref_init (&weakref->clock, clock); - - return weakref; -} - -static GstClockWeakRef * -gst_clock_weak_ref_ref (GstClockWeakRef * weakref) -{ - g_atomic_int_add (&weakref->refcount, 1); - return weakref; -} - -static void -gst_clock_weak_ref_unref (GstClockWeakRef * weakref) -{ - gint old_refcount; - - old_refcount = g_atomic_int_add (&weakref->refcount, -1); - g_return_if_fail (old_refcount > 0); - - if (G_UNLIKELY (old_refcount == 1)) { - g_weak_ref_clear (&weakref->clock); - g_slice_free (GstClockWeakRef, weakref); - } -} - -static GstClock * -gst_clock_weak_ref_get (GstClockWeakRef * weakref) -{ - return g_weak_ref_get (&weakref->clock); -} - struct _GstClockPrivate { GMutex slave_lock; /* order: SLAVE_LOCK, OBJECT_LOCK */ @@ -220,12 +166,12 @@ struct _GstClockPrivate gboolean synced; - GstClockWeakRef *weakref; + GWeakRef *clock_weakref; }; typedef struct _GstClockEntryImpl GstClockEntryImpl; -#define GST_CLOCK_ENTRY_CLOCK_WEAK_REF(entry) (((GstClockEntryImpl *)(entry))->weakref) +#define GST_CLOCK_ENTRY_CLOCK_WEAK_REF(entry) (((GstClockEntryImpl *)(entry))->clock) /* seqlocks */ #define read_seqbegin(clock) \ @@ -317,7 +263,7 @@ gst_clock_entry_new (GstClock * clock, GstClockTime time, #endif #endif GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry) = - gst_clock_weak_ref_ref (clock->priv->weakref); + g_atomic_rc_box_acquire (clock->priv->clock_weakref); entry->type = type; entry->time = time; entry->interval = interval; @@ -431,7 +377,8 @@ _gst_clock_id_free (GstClockID id) if (entry_impl->destroy_entry) entry_impl->destroy_entry (entry_impl); - gst_clock_weak_ref_unref (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry)); + g_atomic_rc_box_release_full (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry), + (GDestroyNotify) g_weak_ref_clear); /* FIXME: add tracer hook for struct allocations such as clock entries */ @@ -588,7 +535,7 @@ gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter) entry = (GstClockEntry *) id; requested = GST_CLOCK_ENTRY_TIME (entry); - clock = gst_clock_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry)); + clock = g_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry)); if (G_UNLIKELY (clock == NULL)) goto invalid_entry; @@ -670,7 +617,7 @@ gst_clock_id_wait_async (GstClockID id, entry = (GstClockEntry *) id; requested = GST_CLOCK_ENTRY_TIME (entry); - clock = gst_clock_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry)); + clock = g_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry)); if (G_UNLIKELY (clock == NULL)) goto invalid_entry; @@ -733,7 +680,7 @@ gst_clock_id_unschedule (GstClockID id) g_return_if_fail (id != NULL); entry = (GstClockEntry *) id; - clock = gst_clock_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry)); + clock = g_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry)); if (G_UNLIKELY (clock == NULL)) goto invalid_entry; @@ -826,7 +773,17 @@ gst_clock_init (GstClock * clock) priv->timeout = DEFAULT_TIMEOUT; priv->times = g_new0 (GstClockTime, 4 * priv->window_size); priv->times_temp = priv->times + 2 * priv->window_size; - priv->weakref = gst_clock_weak_ref_new (clock); + /* + * An atomically ref-counted wrapper around a GWeakRef for this GstClock, + * created by the clock and shared with all its clock entries. + * + * This exists because g_weak_ref_ operations are quite expensive and operate + * with a global GRWLock. _get takes a reader lock, _init and _clear take + * a writer lock. We want to avoid having to instantiate a new GWeakRef for + * every clock entry. + */ + priv->clock_weakref = g_atomic_rc_box_new (GWeakRef); + g_weak_ref_init (priv->clock_weakref, clock); } static void @@ -859,7 +816,8 @@ gst_clock_finalize (GObject * object) clock->priv->times_temp = NULL; GST_CLOCK_SLAVE_UNLOCK (clock); - gst_clock_weak_ref_unref (clock->priv->weakref); + g_atomic_rc_box_release_full (clock->priv->clock_weakref, + (GDestroyNotify) g_weak_ref_clear); g_mutex_clear (&clock->priv->slave_lock); g_cond_clear (&clock->priv->sync_cond); @@ -1433,7 +1391,7 @@ gst_clock_id_get_clock (GstClockID id) g_return_val_if_fail (id != NULL, NULL); entry = (GstClockEntry *) id; - return gst_clock_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry)); + return g_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry)); } /** @@ -1460,7 +1418,7 @@ gst_clock_id_uses_clock (GstClockID id, GstClock * clock) g_return_val_if_fail (clock != NULL, FALSE); entry = (GstClockEntry *) id; - entry_clock = gst_clock_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry)); + entry_clock = g_weak_ref_get (GST_CLOCK_ENTRY_CLOCK_WEAK_REF (entry)); if (entry_clock == clock) ret = TRUE;