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 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/>.
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
;
52 GObject parent_instance
;
54 struct _TestObjectClass
56 GObjectClass parent_class
;
59 G_DEFINE_TYPE (TestObject
, test_object
, G_TYPE_OBJECT
);
62 test_object_finalize (GObject
*object
)
64 object_destroyed
= TRUE
;
66 G_OBJECT_CLASS (test_object_parent_class
)->finalize (object
);
70 test_object_class_init (TestObjectClass
*class)
72 GObjectClass
*object_class
= G_OBJECT_CLASS (class);
74 object_class
->finalize
= test_object_finalize
;
78 test_object_init (TestObject
*test_object
)
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
;
97 weak_ref1 (gpointer data
,
100 g_assert (object
== global_object
);
101 g_assert (data
== GUINT_TO_POINTER (42));
103 weak_ref1_notified
= TRUE
;
107 weak_ref2 (gpointer data
,
110 g_assert (object
== global_object
);
111 g_assert (data
== GUINT_TO_POINTER (24));
113 weak_ref2_notified
= TRUE
;
117 toggle_ref1 (gpointer data
,
119 gboolean is_last_ref
)
121 g_assert (object
== global_object
);
122 g_assert (data
== GUINT_TO_POINTER (42));
125 toggle_ref1_weakened
= TRUE
;
127 toggle_ref1_strengthened
= TRUE
;
131 toggle_ref2 (gpointer data
,
133 gboolean is_last_ref
)
135 g_assert (object
== global_object
);
136 g_assert (data
== GUINT_TO_POINTER (24));
139 toggle_ref2_weakened
= TRUE
;
141 toggle_ref2_strengthened
= TRUE
;
145 toggle_ref3 (gpointer data
,
147 gboolean is_last_ref
)
149 g_assert (object
== global_object
);
150 g_assert (data
== GUINT_TO_POINTER (34));
154 toggle_ref3_weakened
= TRUE
;
155 g_object_remove_toggle_ref (object
, toggle_ref3
, GUINT_TO_POINTER (34));
158 toggle_ref3_strengthened
= TRUE
;
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));
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));
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));
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));
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
);
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
);
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));
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
);
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
);
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));
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
);