mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-06-07 21:30:06 +02:00
New function: g_clear_object()
By analogy to g_clear_error, takes a pass-by-reference GObject reference and, if non-%NULL, unrefs it and sets it equal to %NULL. Bug #620263.
This commit is contained in:
parent
78bc8bec4f
commit
1a1fc130ec
docs/reference/gobject
gobject
@ -257,6 +257,7 @@ GParameter
|
|||||||
g_object_ref
|
g_object_ref
|
||||||
g_object_unref
|
g_object_unref
|
||||||
g_object_ref_sink
|
g_object_ref_sink
|
||||||
|
g_clear_object
|
||||||
GInitiallyUnowned
|
GInitiallyUnowned
|
||||||
GInitiallyUnownedClass
|
GInitiallyUnownedClass
|
||||||
G_TYPE_INITIALLY_UNOWNED
|
G_TYPE_INITIALLY_UNOWNED
|
||||||
|
@ -2728,6 +2728,44 @@ g_object_unref (gpointer _object)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_clear_object:
|
||||||
|
* @object_ptr: a pointer to a #GObject reference
|
||||||
|
*
|
||||||
|
* Clears a reference to a #GObject.
|
||||||
|
*
|
||||||
|
* @object_ptr must not be %NULL.
|
||||||
|
*
|
||||||
|
* If the reference is %NULL then this function does nothing.
|
||||||
|
* Otherwise, the reference count of the object is decreased and the
|
||||||
|
* pointer is set to %NULL.
|
||||||
|
*
|
||||||
|
* This function is threadsafe and modifies the pointer atomically,
|
||||||
|
* using memory barriers where needed.
|
||||||
|
*
|
||||||
|
* A macro is also included that allows this function to be used without
|
||||||
|
* pointer casts.
|
||||||
|
*
|
||||||
|
* Since: 2.28
|
||||||
|
**/
|
||||||
|
#undef g_clear_object
|
||||||
|
void
|
||||||
|
g_clear_object (volatile GObject **object_ptr)
|
||||||
|
{
|
||||||
|
gpointer *ptr = (gpointer) object_ptr;
|
||||||
|
gpointer old;
|
||||||
|
|
||||||
|
/* This is a little frustrating.
|
||||||
|
* Would be nice to have an atomic exchange (with no compare).
|
||||||
|
*/
|
||||||
|
do
|
||||||
|
old = g_atomic_pointer_get (ptr);
|
||||||
|
while G_UNLIKELY (!g_atomic_pointer_compare_and_exchange (ptr, old, NULL));
|
||||||
|
|
||||||
|
if (old)
|
||||||
|
g_object_unref (old);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_object_get_qdata:
|
* g_object_get_qdata:
|
||||||
* @object: The GObject to get a stored user data pointer from
|
* @object: The GObject to get a stored user data pointer from
|
||||||
|
@ -562,6 +562,21 @@ G_STMT_START { \
|
|||||||
#define G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec) \
|
#define G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec) \
|
||||||
G_OBJECT_WARN_INVALID_PSPEC ((object), "property", (property_id), (pspec))
|
G_OBJECT_WARN_INVALID_PSPEC ((object), "property", (property_id), (pspec))
|
||||||
|
|
||||||
|
void g_clear_object (volatile GObject **object_ptr);
|
||||||
|
#define g_clear_object(object_ptr) \
|
||||||
|
G_STMT_START { \
|
||||||
|
/* Only one access, please */ \
|
||||||
|
gpointer *_p = (gpointer) (object_ptr); \
|
||||||
|
gpointer _o; \
|
||||||
|
\
|
||||||
|
do \
|
||||||
|
_o = g_atomic_pointer_get (_p); \
|
||||||
|
while G_UNLIKELY (!g_atomic_pointer_compare_and_exchange (_p, _o, NULL));\
|
||||||
|
\
|
||||||
|
if (_o) \
|
||||||
|
g_object_unref (_o); \
|
||||||
|
} G_STMT_END
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __G_OBJECT_H__ */
|
#endif /* __G_OBJECT_H__ */
|
||||||
|
@ -186,6 +186,7 @@ g_value_get_object
|
|||||||
g_value_set_object
|
g_value_set_object
|
||||||
g_value_dup_object
|
g_value_dup_object
|
||||||
g_value_take_object
|
g_value_take_object
|
||||||
|
g_clear_object
|
||||||
#ifndef G_DISABLE_DEPRECATED
|
#ifndef G_DISABLE_DEPRECATED
|
||||||
g_value_set_object_take_ownership
|
g_value_set_object_take_ownership
|
||||||
g_object_compat_control
|
g_object_compat_control
|
||||||
|
1
gobject/tests/.gitignore
vendored
1
gobject/tests/.gitignore
vendored
@ -1,4 +1,5 @@
|
|||||||
binding
|
binding
|
||||||
dynamictests
|
dynamictests
|
||||||
properties
|
properties
|
||||||
|
reference
|
||||||
threadtests
|
threadtests
|
||||||
|
@ -5,7 +5,7 @@ INCLUDES = -g $(gobject_INCLUDES) $(GLIB_DEBUG_FLAGS)
|
|||||||
noinst_PROGRAMS = $(TEST_PROGS)
|
noinst_PROGRAMS = $(TEST_PROGS)
|
||||||
libgobject_LDADD = ../libgobject-2.0.la $(top_builddir)/gthread/libgthread-2.0.la $(top_builddir)/glib/libglib-2.0.la
|
libgobject_LDADD = ../libgobject-2.0.la $(top_builddir)/gthread/libgthread-2.0.la $(top_builddir)/glib/libglib-2.0.la
|
||||||
|
|
||||||
TEST_PROGS += threadtests dynamictests binding properties
|
TEST_PROGS += threadtests dynamictests binding properties reference
|
||||||
threadtests_SOURCES = threadtests.c
|
threadtests_SOURCES = threadtests.c
|
||||||
threadtests_LDADD = $(libgobject_LDADD)
|
threadtests_LDADD = $(libgobject_LDADD)
|
||||||
dynamictests_SOURCES = dynamictests.c
|
dynamictests_SOURCES = dynamictests.c
|
||||||
@ -14,3 +14,4 @@ binding_SOURCES = binding.c
|
|||||||
binding_LDADD = $(libgobject_LDADD)
|
binding_LDADD = $(libgobject_LDADD)
|
||||||
properties_SOURCES = properties.c
|
properties_SOURCES = properties.c
|
||||||
properties_LDADD = $(libgobject_LDADD)
|
properties_LDADD = $(libgobject_LDADD)
|
||||||
|
reference_LDADD = $(libgobject_LDADD)
|
||||||
|
35
gobject/tests/reference.c
Normal file
35
gobject/tests/reference.c
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_clear (void)
|
||||||
|
{
|
||||||
|
GObject *o = NULL;
|
||||||
|
GObject *tmp;
|
||||||
|
|
||||||
|
g_clear_object (&o);
|
||||||
|
g_assert (o == NULL);
|
||||||
|
|
||||||
|
tmp = g_object_new (G_TYPE_OBJECT, NULL);
|
||||||
|
g_assert_cmpint (tmp->ref_count, ==, 1);
|
||||||
|
o = g_object_ref (tmp);
|
||||||
|
g_assert (o != NULL);
|
||||||
|
|
||||||
|
g_assert_cmpint (tmp->ref_count, ==, 2);
|
||||||
|
g_clear_object (&o);
|
||||||
|
g_assert_cmpint (tmp->ref_count, ==, 1);
|
||||||
|
g_assert (o == NULL);
|
||||||
|
|
||||||
|
g_object_unref (tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
g_test_init (&argc, &argv, NULL);
|
||||||
|
|
||||||
|
g_type_init ();
|
||||||
|
|
||||||
|
g_test_add_func ("/object/clear", test_clear);
|
||||||
|
|
||||||
|
return g_test_run ();
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user