Branch data Line data Source code
1 : : #include <glib-object.h>
2 : :
3 : : /* --------------------------------- */
4 : : /* test_object_constructor_singleton */
5 : :
6 : : typedef GObject MySingletonObject;
7 : : typedef GObjectClass MySingletonObjectClass;
8 : :
9 : : GType my_singleton_object_get_type (void);
10 : :
11 : 5 : G_DEFINE_TYPE (MySingletonObject, my_singleton_object, G_TYPE_OBJECT)
12 : :
13 : : static MySingletonObject *singleton;
14 : :
15 : : static void
16 : 1 : my_singleton_object_init (MySingletonObject *obj)
17 : : {
18 : 1 : }
19 : :
20 : : static GObject *
21 : 3 : my_singleton_object_constructor (GType type,
22 : : guint n_construct_properties,
23 : : GObjectConstructParam *construct_params)
24 : : {
25 : : GObject *object;
26 : :
27 : 3 : if (singleton)
28 : 2 : return g_object_ref (singleton);
29 : :
30 : 1 : object = G_OBJECT_CLASS (my_singleton_object_parent_class)->
31 : : constructor (type, n_construct_properties, construct_params);
32 : 1 : singleton = (MySingletonObject *)object;
33 : :
34 : 1 : return object;
35 : : }
36 : :
37 : : static void
38 : 1 : my_singleton_object_finalize (MySingletonObject *obj)
39 : : {
40 : 1 : singleton = NULL;
41 : :
42 : 1 : G_OBJECT_CLASS (my_singleton_object_parent_class)->finalize (obj);
43 : 1 : }
44 : :
45 : : static void
46 : 1 : my_singleton_object_class_init (MySingletonObjectClass *klass)
47 : : {
48 : 1 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
49 : :
50 : 1 : object_class->constructor = my_singleton_object_constructor;
51 : 1 : object_class->finalize = my_singleton_object_finalize;
52 : 1 : }
53 : :
54 : : static void
55 : 1 : test_object_constructor_singleton (void)
56 : : {
57 : : MySingletonObject *one, *two, *three;
58 : :
59 : 1 : one = g_object_new (my_singleton_object_get_type (), NULL);
60 : 1 : g_assert_cmpint (G_OBJECT (one)->ref_count, ==, 1);
61 : :
62 : 1 : two = g_object_new (my_singleton_object_get_type (), NULL);
63 : 1 : g_assert (one == two);
64 : 1 : g_assert_cmpint (G_OBJECT (two)->ref_count, ==, 2);
65 : :
66 : 1 : three = g_object_new (my_singleton_object_get_type (), NULL);
67 : 1 : g_assert (one == three);
68 : 1 : g_assert_cmpint (G_OBJECT (three)->ref_count, ==, 3);
69 : :
70 : 1 : g_object_add_weak_pointer (G_OBJECT (one), (gpointer *)&one);
71 : :
72 : 1 : g_object_unref (one);
73 : 1 : g_assert (one != NULL);
74 : :
75 : 1 : g_object_unref (three);
76 : 1 : g_object_unref (two);
77 : :
78 : 1 : g_assert (one == NULL);
79 : 1 : }
80 : :
81 : : /* ----------------------------------- */
82 : : /* test_object_constructor_infanticide */
83 : :
84 : : typedef GObject MyInfanticideObject;
85 : : typedef GObjectClass MyInfanticideObjectClass;
86 : :
87 : : GType my_infanticide_object_get_type (void);
88 : :
89 : 1002 : G_DEFINE_TYPE (MyInfanticideObject, my_infanticide_object, G_TYPE_OBJECT)
90 : :
91 : : static void
92 : 1000 : my_infanticide_object_init (MyInfanticideObject *obj)
93 : : {
94 : 1000 : }
95 : :
96 : : static GObject *
97 : 1000 : my_infanticide_object_constructor (GType type,
98 : : guint n_construct_properties,
99 : : GObjectConstructParam *construct_params)
100 : : {
101 : : GObject *object;
102 : :
103 : 1000 : object = G_OBJECT_CLASS (my_infanticide_object_parent_class)->
104 : : constructor (type, n_construct_properties, construct_params);
105 : :
106 : 1000 : g_object_unref (object);
107 : :
108 : 1000 : return NULL;
109 : : }
110 : :
111 : : static void
112 : 1 : my_infanticide_object_class_init (MyInfanticideObjectClass *klass)
113 : : {
114 : 1 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
115 : :
116 : 1 : object_class->constructor = my_infanticide_object_constructor;
117 : 1 : }
118 : :
119 : : static void
120 : 1 : test_object_constructor_infanticide (void)
121 : : {
122 : : GObject *obj;
123 : : int i;
124 : :
125 : : #ifndef G_ENABLE_DEBUG
126 : : g_test_skip ("skip tests that rely on debug-only warnings");
127 : : return;
128 : : #endif
129 : :
130 : 1 : g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=661576");
131 : :
132 : 1001 : for (i = 0; i < 1000; i++)
133 : : {
134 : 1000 : g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_CRITICAL,
135 : : "*finalized while still in-construction*");
136 : 1000 : g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_CRITICAL,
137 : : "*Custom constructor*returned NULL*");
138 : 1000 : obj = g_object_new (my_infanticide_object_get_type (), NULL);
139 : 1000 : g_assert_null (obj);
140 : 1000 : g_test_assert_expected_messages ();
141 : : }
142 : 1 : }
143 : :
144 : : /* --------------------------------- */
145 : :
146 : : int
147 : 1 : main (int argc, char *argv[])
148 : : {
149 : 1 : g_test_init (&argc, &argv, NULL);
150 : :
151 : 1 : g_test_add_func ("/object/constructor/singleton", test_object_constructor_singleton);
152 : 1 : g_test_add_func ("/object/constructor/infanticide", test_object_constructor_infanticide);
153 : :
154 : 1 : return g_test_run ();
155 : : }
|