mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-10-31 16:32:18 +01: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:
		| @@ -257,6 +257,7 @@ GParameter | ||||
| g_object_ref | ||||
| g_object_unref | ||||
| g_object_ref_sink | ||||
| g_clear_object | ||||
| GInitiallyUnowned | ||||
| GInitiallyUnownedClass | ||||
| 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: | ||||
|  * @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) \ | ||||
|     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 | ||||
|  | ||||
| #endif /* __G_OBJECT_H__ */ | ||||
|   | ||||
| @@ -186,6 +186,7 @@ g_value_get_object | ||||
| g_value_set_object | ||||
| g_value_dup_object | ||||
| g_value_take_object | ||||
| g_clear_object | ||||
| #ifndef G_DISABLE_DEPRECATED | ||||
| g_value_set_object_take_ownership | ||||
| g_object_compat_control | ||||
|   | ||||
							
								
								
									
										1
									
								
								gobject/tests/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								gobject/tests/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,4 +1,5 @@ | ||||
| binding | ||||
| dynamictests | ||||
| properties | ||||
| reference | ||||
| threadtests | ||||
|   | ||||
| @@ -5,7 +5,7 @@ INCLUDES = -g $(gobject_INCLUDES) $(GLIB_DEBUG_FLAGS) | ||||
| noinst_PROGRAMS  = $(TEST_PROGS) | ||||
| 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_LDADD	= $(libgobject_LDADD) | ||||
| dynamictests_SOURCES	= dynamictests.c | ||||
| @@ -14,3 +14,4 @@ binding_SOURCES		= binding.c | ||||
| binding_LDADD		= $(libgobject_LDADD) | ||||
| properties_SOURCES      = properties.c | ||||
| 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 (); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user