mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-07-02 20:55:55 +00:00
miniobject: add steal_qdata
Rework the qdata code a little
This commit is contained in:
parent
03ac16c1d8
commit
d3f5dd0707
|
@ -71,14 +71,16 @@ static GQuark weak_ref_quark;
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GQuark quark;
|
GQuark quark;
|
||||||
GstMiniObjectWeakNotify notify;
|
GstMiniObjectNotify notify;
|
||||||
gpointer data;
|
gpointer data;
|
||||||
|
GDestroyNotify destroy;
|
||||||
} GstQData;
|
} GstQData;
|
||||||
|
|
||||||
#define QDATA(o,i) ((GstQData *)(o)->qdata)[(i)]
|
#define QDATA(o,i) ((GstQData *)(o)->qdata)[(i)]
|
||||||
#define QDATA_QUARK(o,i) (QDATA(o,i).quark)
|
#define QDATA_QUARK(o,i) (QDATA(o,i).quark)
|
||||||
#define QDATA_NOTIFY(o,i) (QDATA(o,i).notify)
|
#define QDATA_NOTIFY(o,i) (QDATA(o,i).notify)
|
||||||
#define QDATA_DATA(o,i) (QDATA(o,i).data)
|
#define QDATA_DATA(o,i) (QDATA(o,i).data)
|
||||||
|
#define QDATA_DESTROY(o,i) (QDATA(o,i).destroy)
|
||||||
|
|
||||||
void
|
void
|
||||||
_priv_gst_mini_object_initialize (void)
|
_priv_gst_mini_object_initialize (void)
|
||||||
|
@ -238,14 +240,62 @@ gst_mini_object_ref (GstMiniObject * mini_object)
|
||||||
return mini_object;
|
return mini_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gint
|
||||||
qdata_notify (GstMiniObject * obj)
|
find_notify (GstMiniObject * object, GQuark quark, gboolean match_notify,
|
||||||
|
GstMiniObjectNotify notify, gpointer data)
|
||||||
{
|
{
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
for (i = 0; i < obj->n_qdata; i++)
|
for (i = 0; i < object->n_qdata; i++) {
|
||||||
QDATA_NOTIFY (obj, i) (QDATA_DATA (obj, i), obj);
|
if (QDATA_QUARK (object, i) == quark) {
|
||||||
g_free (obj->qdata);
|
/* check if we need to match the callback too */
|
||||||
|
if (!match_notify || (QDATA_NOTIFY (object, i) == notify &&
|
||||||
|
QDATA_DATA (object, i) == data))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
remove_notify (GstMiniObject * object, gint index)
|
||||||
|
{
|
||||||
|
/* remove item */
|
||||||
|
if (--object->n_qdata == 0) {
|
||||||
|
/* we don't shrink but free when everything is gone */
|
||||||
|
g_free (object->qdata);
|
||||||
|
object->qdata = NULL;
|
||||||
|
} else if (index != object->n_qdata)
|
||||||
|
QDATA (object, index) = QDATA (object, object->n_qdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_notify (GstMiniObject * object, gint index, GQuark quark,
|
||||||
|
GstMiniObjectNotify notify, gpointer data, GDestroyNotify destroy)
|
||||||
|
{
|
||||||
|
if (index == -1) {
|
||||||
|
/* add item */
|
||||||
|
index = object->n_qdata++;
|
||||||
|
object->qdata =
|
||||||
|
g_realloc (object->qdata, sizeof (GstQData) * object->n_qdata);
|
||||||
|
}
|
||||||
|
QDATA_QUARK (object, index) = quark;
|
||||||
|
QDATA_NOTIFY (object, index) = notify;
|
||||||
|
QDATA_DATA (object, index) = data;
|
||||||
|
QDATA_DESTROY (object, index) = destroy;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
call_finalize_notify (GstMiniObject * obj)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < obj->n_qdata; i++) {
|
||||||
|
if (QDATA_QUARK (obj, i) == weak_ref_quark)
|
||||||
|
QDATA_NOTIFY (obj, i) (QDATA_DATA (obj, i), obj);
|
||||||
|
if (QDATA_DESTROY (obj, i))
|
||||||
|
QDATA_DESTROY (obj, i) (QDATA_DATA (obj, i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -278,10 +328,10 @@ gst_mini_object_unref (GstMiniObject * mini_object)
|
||||||
/* if the subclass recycled the object (and returned FALSE) we don't
|
/* if the subclass recycled the object (and returned FALSE) we don't
|
||||||
* want to free the instance anymore */
|
* want to free the instance anymore */
|
||||||
if (G_LIKELY (do_free)) {
|
if (G_LIKELY (do_free)) {
|
||||||
/* The weak reference stack is freed in the notification function */
|
if (mini_object->n_qdata) {
|
||||||
if (mini_object->n_qdata)
|
call_finalize_notify (mini_object);
|
||||||
qdata_notify (mini_object);
|
g_free (mini_object->qdata);
|
||||||
|
}
|
||||||
#ifndef GST_DISABLE_TRACE
|
#ifndef GST_DISABLE_TRACE
|
||||||
_gst_alloc_trace_free (_gst_mini_object_trace, mini_object);
|
_gst_alloc_trace_free (_gst_mini_object_trace, mini_object);
|
||||||
#endif
|
#endif
|
||||||
|
@ -423,21 +473,14 @@ gst_mini_object_take (GstMiniObject ** olddata, GstMiniObject * newdata)
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
gst_mini_object_weak_ref (GstMiniObject * object,
|
gst_mini_object_weak_ref (GstMiniObject * object,
|
||||||
GstMiniObjectWeakNotify notify, gpointer data)
|
GstMiniObjectNotify notify, gpointer data)
|
||||||
{
|
{
|
||||||
guint i;
|
|
||||||
|
|
||||||
g_return_if_fail (object != NULL);
|
g_return_if_fail (object != NULL);
|
||||||
g_return_if_fail (notify != NULL);
|
g_return_if_fail (notify != NULL);
|
||||||
g_return_if_fail (GST_MINI_OBJECT_REFCOUNT_VALUE (object) >= 1);
|
g_return_if_fail (GST_MINI_OBJECT_REFCOUNT_VALUE (object) >= 1);
|
||||||
|
|
||||||
G_LOCK (qdata_mutex);
|
G_LOCK (qdata_mutex);
|
||||||
i = object->n_qdata++;
|
set_notify (object, -1, weak_ref_quark, notify, data, NULL);
|
||||||
object->qdata =
|
|
||||||
g_realloc (object->qdata, sizeof (GstQData) * object->n_qdata);
|
|
||||||
QDATA_QUARK (object, i) = weak_ref_quark;
|
|
||||||
QDATA_NOTIFY (object, i) = notify;
|
|
||||||
QDATA_DATA (object, i) = data;
|
|
||||||
G_UNLOCK (qdata_mutex);
|
G_UNLOCK (qdata_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,38 +490,26 @@ gst_mini_object_weak_ref (GstMiniObject * object,
|
||||||
* @notify: callback to search for
|
* @notify: callback to search for
|
||||||
* @data: data to search for
|
* @data: data to search for
|
||||||
*
|
*
|
||||||
* Removes a weak reference callback to a mini object.
|
* Removes a weak reference callback from a mini object.
|
||||||
*
|
*
|
||||||
* Since: 0.10.35
|
* Since: 0.10.35
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
gst_mini_object_weak_unref (GstMiniObject * object,
|
gst_mini_object_weak_unref (GstMiniObject * object,
|
||||||
GstMiniObjectWeakNotify notify, gpointer data)
|
GstMiniObjectNotify notify, gpointer data)
|
||||||
{
|
{
|
||||||
guint i;
|
gint i;
|
||||||
gboolean found_one = FALSE;
|
|
||||||
|
|
||||||
g_return_if_fail (object != NULL);
|
g_return_if_fail (object != NULL);
|
||||||
g_return_if_fail (notify != NULL);
|
g_return_if_fail (notify != NULL);
|
||||||
|
|
||||||
G_LOCK (qdata_mutex);
|
G_LOCK (qdata_mutex);
|
||||||
for (i = 0; i < object->n_qdata; i++) {
|
if ((i = find_notify (object, weak_ref_quark, TRUE, notify, data)) != -1) {
|
||||||
if (QDATA_QUARK (object, i) == weak_ref_quark &&
|
remove_notify (object, i);
|
||||||
QDATA_NOTIFY (object, i) == notify && QDATA_DATA (object, i) == data) {
|
} else {
|
||||||
found_one = TRUE;
|
g_warning ("%s: couldn't find weak ref %p(%p)", G_STRFUNC, notify, data);
|
||||||
if (--object->n_qdata == 0) {
|
|
||||||
/* we don't shrink but free when everything is gone */
|
|
||||||
g_free (object->qdata);
|
|
||||||
object->qdata = NULL;
|
|
||||||
} else if (i != object->n_qdata)
|
|
||||||
QDATA (object, i) = QDATA (object, object->n_qdata);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
G_UNLOCK (qdata_mutex);
|
G_UNLOCK (qdata_mutex);
|
||||||
|
|
||||||
if (!found_one)
|
|
||||||
g_warning ("%s: couldn't find weak ref %p(%p)", G_STRFUNC, notify, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -506,7 +537,7 @@ void
|
||||||
gst_mini_object_set_qdata (GstMiniObject * object, GQuark quark,
|
gst_mini_object_set_qdata (GstMiniObject * object, GQuark quark,
|
||||||
gpointer data, GDestroyNotify destroy)
|
gpointer data, GDestroyNotify destroy)
|
||||||
{
|
{
|
||||||
guint i;
|
gint i;
|
||||||
gpointer old_data = NULL;
|
gpointer old_data = NULL;
|
||||||
GDestroyNotify old_notify = NULL;
|
GDestroyNotify old_notify = NULL;
|
||||||
|
|
||||||
|
@ -514,32 +545,16 @@ gst_mini_object_set_qdata (GstMiniObject * object, GQuark quark,
|
||||||
g_return_if_fail (quark > 0);
|
g_return_if_fail (quark > 0);
|
||||||
|
|
||||||
G_LOCK (qdata_mutex);
|
G_LOCK (qdata_mutex);
|
||||||
for (i = 0; i < object->n_qdata; i++) {
|
if ((i = find_notify (object, quark, FALSE, NULL, NULL)) != -1) {
|
||||||
if (QDATA_QUARK (object, i) == quark) {
|
|
||||||
old_data = QDATA_DATA (object, i);
|
|
||||||
old_notify = (GDestroyNotify) QDATA_NOTIFY (object, i);
|
|
||||||
|
|
||||||
if (data == NULL) {
|
old_data = QDATA_DATA (object, i);
|
||||||
/* remove item */
|
old_notify = QDATA_DESTROY (object, i);
|
||||||
if (--object->n_qdata == 0) {
|
|
||||||
/* we don't shrink but free when everything is gone */
|
if (data == NULL)
|
||||||
g_free (object->qdata);
|
remove_notify (object, i);
|
||||||
object->qdata = NULL;
|
|
||||||
} else if (i != object->n_qdata)
|
|
||||||
QDATA (object, i) = QDATA (object, object->n_qdata);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!old_data) {
|
if (data != NULL)
|
||||||
/* add item */
|
set_notify (object, i, quark, NULL, data, destroy);
|
||||||
i = object->n_qdata++;
|
|
||||||
object->qdata =
|
|
||||||
g_realloc (object->qdata, sizeof (GstQData) * object->n_qdata);
|
|
||||||
}
|
|
||||||
QDATA_QUARK (object, i) = quark;
|
|
||||||
QDATA_DATA (object, i) = data;
|
|
||||||
QDATA_NOTIFY (object, i) = (GstMiniObjectWeakNotify) destroy;
|
|
||||||
G_UNLOCK (qdata_mutex);
|
G_UNLOCK (qdata_mutex);
|
||||||
|
|
||||||
if (old_notify)
|
if (old_notify)
|
||||||
|
@ -560,17 +575,47 @@ gpointer
|
||||||
gst_mini_object_get_qdata (GstMiniObject * object, GQuark quark)
|
gst_mini_object_get_qdata (GstMiniObject * object, GQuark quark)
|
||||||
{
|
{
|
||||||
guint i;
|
guint i;
|
||||||
gpointer result = NULL;
|
gpointer result;
|
||||||
|
|
||||||
g_return_val_if_fail (object != NULL, NULL);
|
g_return_val_if_fail (object != NULL, NULL);
|
||||||
g_return_val_if_fail (quark > 0, NULL);
|
g_return_val_if_fail (quark > 0, NULL);
|
||||||
|
|
||||||
G_LOCK (qdata_mutex);
|
G_LOCK (qdata_mutex);
|
||||||
for (i = 0; i < object->n_qdata; i++) {
|
if ((i = find_notify (object, quark, FALSE, NULL, NULL)) != -1)
|
||||||
if (QDATA_QUARK (object, i) == quark) {
|
result = QDATA_DATA (object, i);
|
||||||
result = QDATA_DATA (object, i);
|
else
|
||||||
break;
|
result = NULL;
|
||||||
}
|
G_UNLOCK (qdata_mutex);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_mini_object_steal_qdata:
|
||||||
|
* @object: The GstMiniObject to get a stored user data pointer from
|
||||||
|
* @quark: A #GQuark, naming the user data pointer
|
||||||
|
*
|
||||||
|
* This function gets back user data pointers stored via gst_mini_object_set_qdata()
|
||||||
|
* and removes the data from @object without invoking its destroy() function (if
|
||||||
|
* any was set).
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): The user data pointer set, or %NULL
|
||||||
|
*/
|
||||||
|
gpointer
|
||||||
|
gst_mini_object_steal_qdata (GstMiniObject * object, GQuark quark)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
gpointer result;
|
||||||
|
|
||||||
|
g_return_val_if_fail (object != NULL, NULL);
|
||||||
|
g_return_val_if_fail (quark > 0, NULL);
|
||||||
|
|
||||||
|
G_LOCK (qdata_mutex);
|
||||||
|
if ((i = find_notify (object, quark, FALSE, NULL, NULL)) != -1) {
|
||||||
|
result = QDATA_DATA (object, i);
|
||||||
|
remove_notify (object, i);
|
||||||
|
} else {
|
||||||
|
result = NULL;
|
||||||
}
|
}
|
||||||
G_UNLOCK (qdata_mutex);
|
G_UNLOCK (qdata_mutex);
|
||||||
|
|
||||||
|
|
|
@ -68,20 +68,14 @@ typedef gboolean (*GstMiniObjectDisposeFunction) (GstMiniObject *obj);
|
||||||
typedef void (*GstMiniObjectFreeFunction) (GstMiniObject *obj);
|
typedef void (*GstMiniObjectFreeFunction) (GstMiniObject *obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstMiniObjectWeakNotify:
|
* GstMiniObjectNotify:
|
||||||
* @user_data: data that was provided when the weak reference was established
|
* @user_data: data that was provided when the notify was added
|
||||||
* @where_the_mini_object_was: the mini object being finalized
|
* @obj: the mini object
|
||||||
*
|
*
|
||||||
* A #GstMiniObjectWeakNotify function can be added to a mini object as a
|
* A #GstMiniObjectNotify function can be added to a mini object as a
|
||||||
* callback that gets triggered when the mini object is finalized. Since the
|
* callback that gets triggered with gst_mini_object_notify().
|
||||||
* mini object is already being finalized when the #GstMiniObjectWeakNotify is
|
|
||||||
* called, there's not much you could do with the object, apart from e.g. using
|
|
||||||
* its adress as hash-index or the like.
|
|
||||||
*
|
|
||||||
* Since: 0.10.35
|
|
||||||
*/
|
*/
|
||||||
typedef void (*GstMiniObjectWeakNotify) (gpointer user_data,
|
typedef void (*GstMiniObjectNotify) (gpointer user_data, GstMiniObject * obj);
|
||||||
GstMiniObject * where_the_mini_object_was);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GST_MINI_OBJECT_TYPE:
|
* GST_MINI_OBJECT_TYPE:
|
||||||
|
@ -195,15 +189,16 @@ GstMiniObject * gst_mini_object_ref (GstMiniObject *mini_object);
|
||||||
void gst_mini_object_unref (GstMiniObject *mini_object);
|
void gst_mini_object_unref (GstMiniObject *mini_object);
|
||||||
|
|
||||||
void gst_mini_object_weak_ref (GstMiniObject *object,
|
void gst_mini_object_weak_ref (GstMiniObject *object,
|
||||||
GstMiniObjectWeakNotify notify,
|
GstMiniObjectNotify notify,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
void gst_mini_object_weak_unref (GstMiniObject *object,
|
void gst_mini_object_weak_unref (GstMiniObject *object,
|
||||||
GstMiniObjectWeakNotify notify,
|
GstMiniObjectNotify notify,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
|
|
||||||
void gst_mini_object_set_qdata (GstMiniObject *object, GQuark quark,
|
void gst_mini_object_set_qdata (GstMiniObject *object, GQuark quark,
|
||||||
gpointer data, GDestroyNotify destroy);
|
gpointer data, GDestroyNotify destroy);
|
||||||
gpointer gst_mini_object_get_qdata (GstMiniObject *object, GQuark quark);
|
gpointer gst_mini_object_get_qdata (GstMiniObject *object, GQuark quark);
|
||||||
|
gpointer gst_mini_object_steal_qdata (GstMiniObject *object, GQuark quark);
|
||||||
|
|
||||||
|
|
||||||
gboolean gst_mini_object_replace (GstMiniObject **olddata, GstMiniObject *newdata);
|
gboolean gst_mini_object_replace (GstMiniObject **olddata, GstMiniObject *newdata);
|
||||||
|
|
|
@ -603,6 +603,7 @@ EXPORTS
|
||||||
gst_mini_object_replace
|
gst_mini_object_replace
|
||||||
gst_mini_object_set_qdata
|
gst_mini_object_set_qdata
|
||||||
gst_mini_object_steal
|
gst_mini_object_steal
|
||||||
|
gst_mini_object_steal_qdata
|
||||||
gst_mini_object_take
|
gst_mini_object_take
|
||||||
gst_mini_object_unref
|
gst_mini_object_unref
|
||||||
gst_mini_object_weak_ref
|
gst_mini_object_weak_ref
|
||||||
|
|
Loading…
Reference in a new issue