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 | G_DEFINE_TYPE (MySingletonObject, my_singleton_object, G_TYPE_OBJECT) |
12 | |
13 | static MySingletonObject *singleton; |
14 | |
15 | static void |
16 | my_singleton_object_init (MySingletonObject *obj) |
17 | { |
18 | } |
19 | |
20 | static GObject * |
21 | my_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 | |
37 | static void |
38 | my_singleton_object_finalize (MySingletonObject *obj) |
39 | { |
40 | singleton = NULL; |
41 | |
42 | G_OBJECT_CLASS (my_singleton_object_parent_class)->finalize (obj); |
43 | } |
44 | |
45 | static void |
46 | my_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 | |
54 | static void |
55 | test_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 | |
84 | typedef GObject MyInfanticideObject; |
85 | typedef GObjectClass MyInfanticideObjectClass; |
86 | |
87 | GType my_infanticide_object_get_type (void); |
88 | |
89 | G_DEFINE_TYPE (MyInfanticideObject, my_infanticide_object, G_TYPE_OBJECT) |
90 | |
91 | static void |
92 | my_infanticide_object_init (MyInfanticideObject *obj) |
93 | { |
94 | } |
95 | |
96 | static GObject * |
97 | my_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 | |
111 | static void |
112 | my_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 | |
119 | static void |
120 | test_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 | |
141 | int |
142 | main (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 | |