mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
clock: Use g_atomic_rc_box for refcounting entry clocks
g_atomic_rc_box was added in GLib 2.58, and we require 2.62 now, so we can fix the FIXME and use this. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2568>
This commit is contained in:
parent
9d9e59622f
commit
604b92b9cb
2 changed files with 24 additions and 69 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue