[kdbus] KDBUS_ITEM_PAYLOAD_OFF items are (once again) relative to msg header
[platform/upstream/glib.git] / tests / gobject / references.c
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2  * Copyright (C) 2005 Red Hat, Inc.
3  *
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.
8  *
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.
13  *
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/>.
16  */
17
18 #undef  G_LOG_DOMAIN
19 #define G_LOG_DOMAIN "TestReferences"
20
21 #undef G_DISABLE_ASSERT
22 #undef G_DISABLE_CHECKS
23 #undef G_DISABLE_CAST_CHECKS
24
25 #include        <glib-object.h>
26
27 /* This test tests weak and toggle references
28  */
29
30 static GObject *global_object;
31
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;
41
42 /*
43  * TestObject, a parent class for TestObject
44  */
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;
49
50 struct _TestObject
51 {
52   GObject parent_instance;
53 };
54 struct _TestObjectClass
55 {
56   GObjectClass parent_class;
57 };
58
59 G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT);
60
61 static void
62 test_object_finalize (GObject *object)
63 {
64   object_destroyed = TRUE;
65   
66   G_OBJECT_CLASS (test_object_parent_class)->finalize (object);
67 }
68
69 static void
70 test_object_class_init (TestObjectClass *class)
71 {
72   GObjectClass *object_class = G_OBJECT_CLASS (class);
73
74   object_class->finalize = test_object_finalize;
75 }
76
77 static void
78 test_object_init (TestObject *test_object)
79 {
80 }
81
82 static void
83 clear_flags (void)
84 {
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;
94 }
95
96 static void
97 weak_ref1 (gpointer data,
98            GObject *object)
99 {
100   g_assert (object == global_object);
101   g_assert (data == GUINT_TO_POINTER (42));
102
103   weak_ref1_notified = TRUE;
104 }
105
106 static void
107 weak_ref2 (gpointer data,
108            GObject *object)
109 {
110   g_assert (object == global_object);
111   g_assert (data == GUINT_TO_POINTER (24));
112
113   weak_ref2_notified = TRUE;
114 }
115
116 static void
117 toggle_ref1 (gpointer data,
118              GObject *object,
119              gboolean is_last_ref)
120 {
121   g_assert (object == global_object);
122   g_assert (data == GUINT_TO_POINTER (42));
123
124   if (is_last_ref)
125     toggle_ref1_weakened = TRUE;
126   else
127     toggle_ref1_strengthened = TRUE;
128 }
129
130 static void
131 toggle_ref2 (gpointer data,
132              GObject *object,
133              gboolean is_last_ref)
134 {
135   g_assert (object == global_object);
136   g_assert (data == GUINT_TO_POINTER (24));
137
138   if (is_last_ref)
139     toggle_ref2_weakened = TRUE;
140   else
141     toggle_ref2_strengthened = TRUE;
142 }
143
144 static void
145 toggle_ref3 (gpointer data,
146              GObject *object,
147              gboolean is_last_ref)
148 {
149   g_assert (object == global_object);
150   g_assert (data == GUINT_TO_POINTER (34));
151
152   if (is_last_ref)
153     {
154       toggle_ref3_weakened = TRUE;
155       g_object_remove_toggle_ref (object, toggle_ref3, GUINT_TO_POINTER (34));
156     }
157   else
158     toggle_ref3_strengthened = TRUE;
159 }
160
161 int
162 main (int   argc,
163       char *argv[])
164 {
165   GObject *object;
166         
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);
170
171   /* Test basic weak reference operation
172    */
173   global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL);
174   
175   g_object_weak_ref (object, weak_ref1, GUINT_TO_POINTER (42));
176
177   clear_flags ();
178   g_object_unref (object);
179   g_assert (weak_ref1_notified == TRUE);
180   g_assert (object_destroyed == TRUE);
181
182   /* Test two weak references at once
183    */
184   global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL);
185   
186   g_object_weak_ref (object, weak_ref1, GUINT_TO_POINTER (42));
187   g_object_weak_ref (object, weak_ref2, GUINT_TO_POINTER (24));
188
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);
194
195   /* Test remove weak references
196    */
197   global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL);
198   
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));
202
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);
208
209   /* Test basic toggle reference operation
210    */
211   global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL);
212   
213   g_object_add_toggle_ref (object, toggle_ref1, GUINT_TO_POINTER (42));
214
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);
220
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);
226
227   g_object_unref (object);
228
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);
234
235   global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL);
236
237   /* Test two toggle references at once
238    */
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));
241
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);
249
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);
257
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);
265   
266   /* Test a toggle reference that removes itself
267    */
268   global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL);
269   
270   g_object_add_toggle_ref (object, toggle_ref3, GUINT_TO_POINTER (34));
271
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);
277
278   return 0;
279 }