Fix g_autoptr_cleanup_gstring_free( ) argument to avoid of confliting arument name
[platform/upstream/glib.git] / gobject / tests / references.c
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2  * Copyright (C) 2005 Red Hat, Inc.
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General
17  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <glib-object.h>
21
22 /* This test tests weak and toggle references */
23
24 static GObject *global_object;
25
26 static gboolean object_destroyed;
27 static gboolean weak_ref1_notified;
28 static gboolean weak_ref2_notified;
29 static gboolean toggle_ref1_weakened;
30 static gboolean toggle_ref1_strengthened;
31 static gboolean toggle_ref2_weakened;
32 static gboolean toggle_ref2_strengthened;
33 static gboolean toggle_ref3_weakened;
34 static gboolean toggle_ref3_strengthened;
35
36 /* TestObject, a parent class for TestObject */
37 static GType test_object_get_type (void);
38 #define TEST_TYPE_OBJECT          (test_object_get_type ())
39 typedef struct _TestObject        TestObject;
40 typedef struct _TestObjectClass   TestObjectClass;
41
42 struct _TestObject
43 {
44   GObject parent_instance;
45 };
46 struct _TestObjectClass
47 {
48   GObjectClass parent_class;
49 };
50
51 G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT)
52
53 static void
54 test_object_finalize (GObject *object)
55 {
56   object_destroyed = TRUE;
57
58   G_OBJECT_CLASS (test_object_parent_class)->finalize (object);
59 }
60
61 static void
62 test_object_class_init (TestObjectClass *class)
63 {
64   GObjectClass *object_class = G_OBJECT_CLASS (class);
65
66   object_class->finalize = test_object_finalize;
67 }
68
69 static void
70 test_object_init (TestObject *test_object)
71 {
72 }
73
74 static void
75 clear_flags (void)
76 {
77   object_destroyed = FALSE;
78   weak_ref1_notified = FALSE;
79   weak_ref2_notified = FALSE;
80   toggle_ref1_weakened = FALSE;
81   toggle_ref1_strengthened = FALSE;
82   toggle_ref2_weakened = FALSE;
83   toggle_ref2_strengthened = FALSE;
84   toggle_ref3_weakened = FALSE;
85   toggle_ref3_strengthened = FALSE;
86 }
87
88 static void
89 weak_ref1 (gpointer data,
90            GObject *object)
91 {
92   g_assert_true (object == global_object);
93   g_assert_cmpint (GPOINTER_TO_INT (data), ==, 42);
94
95   weak_ref1_notified = TRUE;
96 }
97
98 static void
99 weak_ref2 (gpointer data,
100            GObject *object)
101 {
102   g_assert_true (object == global_object);
103   g_assert_cmpint (GPOINTER_TO_INT (data), ==, 24);
104
105   weak_ref2_notified = TRUE;
106 }
107
108 static void
109 toggle_ref1 (gpointer data,
110              GObject *object,
111              gboolean is_last_ref)
112 {
113   g_assert_true (object == global_object);
114   g_assert_cmpint (GPOINTER_TO_INT (data), ==, 42);
115
116   if (is_last_ref)
117     toggle_ref1_weakened = TRUE;
118   else
119     toggle_ref1_strengthened = TRUE;
120 }
121
122 static void
123 toggle_ref2 (gpointer data,
124              GObject *object,
125              gboolean is_last_ref)
126 {
127   g_assert_true (object == global_object);
128   g_assert_cmpint (GPOINTER_TO_INT (data), ==, 24);
129
130   if (is_last_ref)
131     toggle_ref2_weakened = TRUE;
132   else
133     toggle_ref2_strengthened = TRUE;
134 }
135
136 static void
137 toggle_ref3 (gpointer data,
138              GObject *object,
139              gboolean is_last_ref)
140 {
141   g_assert_true (object == global_object);
142   g_assert_cmpint (GPOINTER_TO_INT (data), ==, 34);
143
144   if (is_last_ref)
145     {
146       toggle_ref3_weakened = TRUE;
147       g_object_remove_toggle_ref (object, toggle_ref3, GUINT_TO_POINTER (34));
148     }
149   else
150     toggle_ref3_strengthened = TRUE;
151 }
152
153 static void
154 test_references (void)
155 {
156   GObject *object;
157
158   /* Test basic weak reference operation */
159   global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL);
160
161   g_object_weak_ref (object, weak_ref1, GUINT_TO_POINTER (42));
162
163   clear_flags ();
164   g_object_unref (object);
165   g_assert_true (weak_ref1_notified);
166   g_assert_true (object_destroyed);
167
168   /* Test two weak references at once
169    */
170   global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL);
171
172   g_object_weak_ref (object, weak_ref1, GUINT_TO_POINTER (42));
173   g_object_weak_ref (object, weak_ref2, GUINT_TO_POINTER (24));
174
175   clear_flags ();
176   g_object_unref (object);
177   g_assert_true (weak_ref1_notified);
178   g_assert_true (weak_ref2_notified);
179   g_assert_true (object_destroyed);
180
181   /* Test remove weak references */
182   global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL);
183
184   g_object_weak_ref (object, weak_ref1, GUINT_TO_POINTER (42));
185   g_object_weak_ref (object, weak_ref2, GUINT_TO_POINTER (24));
186   g_object_weak_unref (object, weak_ref1, GUINT_TO_POINTER (42));
187
188   clear_flags ();
189   g_object_unref (object);
190   g_assert_false (weak_ref1_notified);
191   g_assert_true (weak_ref2_notified);
192   g_assert_true (object_destroyed);
193
194   /* Test basic toggle reference operation */
195   global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL);
196
197   g_object_add_toggle_ref (object, toggle_ref1, GUINT_TO_POINTER (42));
198
199   clear_flags ();
200   g_object_unref (object);
201   g_assert_true (toggle_ref1_weakened);
202   g_assert_false (toggle_ref1_strengthened);
203   g_assert_false (object_destroyed);
204
205   clear_flags ();
206   g_object_ref (object);
207   g_assert_false (toggle_ref1_weakened);
208   g_assert_true (toggle_ref1_strengthened);
209   g_assert_false (object_destroyed);
210
211   g_object_unref (object);
212
213   clear_flags ();
214   g_object_remove_toggle_ref (object, toggle_ref1, GUINT_TO_POINTER (42));
215   g_assert_false (toggle_ref1_weakened);
216   g_assert_false (toggle_ref1_strengthened);
217   g_assert_true (object_destroyed);
218
219   global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL);
220
221   /* Test two toggle references at once */
222   g_object_add_toggle_ref (object, toggle_ref1, GUINT_TO_POINTER (42));
223   g_object_add_toggle_ref (object, toggle_ref2, GUINT_TO_POINTER (24));
224
225   clear_flags ();
226   g_object_unref (object);
227   g_assert_false (toggle_ref1_weakened);
228   g_assert_false (toggle_ref1_strengthened);
229   g_assert_false (toggle_ref2_weakened);
230   g_assert_false (toggle_ref2_strengthened);
231   g_assert_false (object_destroyed);
232
233   clear_flags ();
234   g_object_remove_toggle_ref (object, toggle_ref1, GUINT_TO_POINTER (42));
235   g_assert_false (toggle_ref1_weakened);
236   g_assert_false (toggle_ref1_strengthened);
237   g_assert_true (toggle_ref2_weakened);
238   g_assert_false (toggle_ref2_strengthened);
239   g_assert_false (object_destroyed);
240
241   clear_flags ();
242   /* Check that removing a toggle ref with %NULL data works fine. */
243   g_object_remove_toggle_ref (object, toggle_ref2, NULL);
244   g_assert_false (toggle_ref1_weakened);
245   g_assert_false (toggle_ref1_strengthened);
246   g_assert_false (toggle_ref2_weakened);
247   g_assert_false (toggle_ref2_strengthened);
248   g_assert_true (object_destroyed);
249
250   /* Test a toggle reference that removes itself */
251   global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL);
252
253   g_object_add_toggle_ref (object, toggle_ref3, GUINT_TO_POINTER (34));
254
255   clear_flags ();
256   g_object_unref (object);
257   g_assert_true (toggle_ref3_weakened);
258   g_assert_false (toggle_ref3_strengthened);
259   g_assert_true (object_destroyed);
260 }
261
262 int
263 main (int   argc,
264       char *argv[])
265 {
266   g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) |
267                           G_LOG_LEVEL_WARNING |
268                           G_LOG_LEVEL_CRITICAL);
269
270   g_test_init (&argc, &argv, NULL);
271
272   g_test_add_func ("/gobject/references", test_references);
273
274   return g_test_run ();
275 }