Merge branch 'g-clear-pointer-no-side-effects' into 'master'
[glib.git] / tests / gobject / references.c
blob8c126604231ba860cfdaf6d35f36a34f54c422f5
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 2005 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General
15 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 #undef G_LOG_DOMAIN
19 #define G_LOG_DOMAIN "TestReferences"
21 #undef G_DISABLE_ASSERT
22 #undef G_DISABLE_CHECKS
23 #undef G_DISABLE_CAST_CHECKS
25 #include <glib-object.h>
27 /* This test tests weak and toggle references
30 static GObject *global_object;
32 static gboolean object_destroyed;
33 static gboolean weak_ref1_notified;
34 static gboolean weak_ref2_notified;
35 static gboolean toggle_ref1_weakened;
36 static gboolean toggle_ref1_strengthened;
37 static gboolean toggle_ref2_weakened;
38 static gboolean toggle_ref2_strengthened;
39 static gboolean toggle_ref3_weakened;
40 static gboolean toggle_ref3_strengthened;
43 * TestObject, a parent class for TestObject
45 static GType test_object_get_type (void);
46 #define TEST_TYPE_OBJECT (test_object_get_type ())
47 typedef struct _TestObject TestObject;
48 typedef struct _TestObjectClass TestObjectClass;
50 struct _TestObject
52 GObject parent_instance;
54 struct _TestObjectClass
56 GObjectClass parent_class;
59 G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT)
61 static void
62 test_object_finalize (GObject *object)
64 object_destroyed = TRUE;
66 G_OBJECT_CLASS (test_object_parent_class)->finalize (object);
69 static void
70 test_object_class_init (TestObjectClass *class)
72 GObjectClass *object_class = G_OBJECT_CLASS (class);
74 object_class->finalize = test_object_finalize;
77 static void
78 test_object_init (TestObject *test_object)
82 static void
83 clear_flags (void)
85 object_destroyed = FALSE;
86 weak_ref1_notified = FALSE;
87 weak_ref2_notified = FALSE;
88 toggle_ref1_weakened = FALSE;
89 toggle_ref1_strengthened = FALSE;
90 toggle_ref2_weakened = FALSE;
91 toggle_ref2_strengthened = FALSE;
92 toggle_ref3_weakened = FALSE;
93 toggle_ref3_strengthened = FALSE;
96 static void
97 weak_ref1 (gpointer data,
98 GObject *object)
100 g_assert (object == global_object);
101 g_assert (data == GUINT_TO_POINTER (42));
103 weak_ref1_notified = TRUE;
106 static void
107 weak_ref2 (gpointer data,
108 GObject *object)
110 g_assert (object == global_object);
111 g_assert (data == GUINT_TO_POINTER (24));
113 weak_ref2_notified = TRUE;
116 static void
117 toggle_ref1 (gpointer data,
118 GObject *object,
119 gboolean is_last_ref)
121 g_assert (object == global_object);
122 g_assert (data == GUINT_TO_POINTER (42));
124 if (is_last_ref)
125 toggle_ref1_weakened = TRUE;
126 else
127 toggle_ref1_strengthened = TRUE;
130 static void
131 toggle_ref2 (gpointer data,
132 GObject *object,
133 gboolean is_last_ref)
135 g_assert (object == global_object);
136 g_assert (data == GUINT_TO_POINTER (24));
138 if (is_last_ref)
139 toggle_ref2_weakened = TRUE;
140 else
141 toggle_ref2_strengthened = TRUE;
144 static void
145 toggle_ref3 (gpointer data,
146 GObject *object,
147 gboolean is_last_ref)
149 g_assert (object == global_object);
150 g_assert (data == GUINT_TO_POINTER (34));
152 if (is_last_ref)
154 toggle_ref3_weakened = TRUE;
155 g_object_remove_toggle_ref (object, toggle_ref3, GUINT_TO_POINTER (34));
157 else
158 toggle_ref3_strengthened = TRUE;
162 main (int argc,
163 char *argv[])
165 GObject *object;
167 g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) |
168 G_LOG_LEVEL_WARNING |
169 G_LOG_LEVEL_CRITICAL);
171 /* Test basic weak reference operation
173 global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL);
175 g_object_weak_ref (object, weak_ref1, GUINT_TO_POINTER (42));
177 clear_flags ();
178 g_object_unref (object);
179 g_assert (weak_ref1_notified == TRUE);
180 g_assert (object_destroyed == TRUE);
182 /* Test two weak references at once
184 global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL);
186 g_object_weak_ref (object, weak_ref1, GUINT_TO_POINTER (42));
187 g_object_weak_ref (object, weak_ref2, GUINT_TO_POINTER (24));
189 clear_flags ();
190 g_object_unref (object);
191 g_assert (weak_ref1_notified == TRUE);
192 g_assert (weak_ref2_notified == TRUE);
193 g_assert (object_destroyed == TRUE);
195 /* Test remove weak references
197 global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL);
199 g_object_weak_ref (object, weak_ref1, GUINT_TO_POINTER (42));
200 g_object_weak_ref (object, weak_ref2, GUINT_TO_POINTER (24));
201 g_object_weak_unref (object, weak_ref1, GUINT_TO_POINTER (42));
203 clear_flags ();
204 g_object_unref (object);
205 g_assert (weak_ref1_notified == FALSE);
206 g_assert (weak_ref2_notified == TRUE);
207 g_assert (object_destroyed == TRUE);
209 /* Test basic toggle reference operation
211 global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL);
213 g_object_add_toggle_ref (object, toggle_ref1, GUINT_TO_POINTER (42));
215 clear_flags ();
216 g_object_unref (object);
217 g_assert (toggle_ref1_weakened == TRUE);
218 g_assert (toggle_ref1_strengthened == FALSE);
219 g_assert (object_destroyed == FALSE);
221 clear_flags ();
222 g_object_ref (object);
223 g_assert (toggle_ref1_weakened == FALSE);
224 g_assert (toggle_ref1_strengthened == TRUE);
225 g_assert (object_destroyed == FALSE);
227 g_object_unref (object);
229 clear_flags ();
230 g_object_remove_toggle_ref (object, toggle_ref1, GUINT_TO_POINTER (42));
231 g_assert (toggle_ref1_weakened == FALSE);
232 g_assert (toggle_ref1_strengthened == FALSE);
233 g_assert (object_destroyed == TRUE);
235 global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL);
237 /* Test two toggle references at once
239 g_object_add_toggle_ref (object, toggle_ref1, GUINT_TO_POINTER (42));
240 g_object_add_toggle_ref (object, toggle_ref2, GUINT_TO_POINTER (24));
242 clear_flags ();
243 g_object_unref (object);
244 g_assert (toggle_ref1_weakened == FALSE);
245 g_assert (toggle_ref1_strengthened == FALSE);
246 g_assert (toggle_ref2_weakened == FALSE);
247 g_assert (toggle_ref2_strengthened == FALSE);
248 g_assert (object_destroyed == FALSE);
250 clear_flags ();
251 g_object_remove_toggle_ref (object, toggle_ref1, GUINT_TO_POINTER (42));
252 g_assert (toggle_ref1_weakened == FALSE);
253 g_assert (toggle_ref1_strengthened == FALSE);
254 g_assert (toggle_ref2_weakened == TRUE);
255 g_assert (toggle_ref2_strengthened == FALSE);
256 g_assert (object_destroyed == FALSE);
258 clear_flags ();
259 g_object_remove_toggle_ref (object, toggle_ref2, GUINT_TO_POINTER (24));
260 g_assert (toggle_ref1_weakened == FALSE);
261 g_assert (toggle_ref1_strengthened == FALSE);
262 g_assert (toggle_ref2_weakened == FALSE);
263 g_assert (toggle_ref2_strengthened == FALSE);
264 g_assert (object_destroyed == TRUE);
266 /* Test a toggle reference that removes itself
268 global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL);
270 g_object_add_toggle_ref (object, toggle_ref3, GUINT_TO_POINTER (34));
272 clear_flags ();
273 g_object_unref (object);
274 g_assert (toggle_ref3_weakened == TRUE);
275 g_assert (toggle_ref3_strengthened == FALSE);
276 g_assert (object_destroyed == TRUE);
278 return 0;