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

source code of gtk/subprojects/glib/gobject/tests/object.c