gkdbus: Fix underflow and unreachable code bug
[platform/upstream/glib.git] / gobject / tests / signal-handler.c
1 #include <glib-object.h>
2
3 typedef struct {
4   GObject instance;
5 } MyObj;
6
7 typedef struct {
8   GObjectClass parent_class;
9 } MyObjClass;
10
11 enum {
12   SIGNAL1,
13   SIGNAL2,
14   LAST_SIGNAL
15 };
16
17 guint signals[LAST_SIGNAL];
18
19 GType my_obj_get_type (void);
20
21 G_DEFINE_TYPE (MyObj, my_obj, G_TYPE_OBJECT)
22
23 static void
24 my_obj_init (MyObj *o)
25 {
26 }
27
28 static void
29 my_obj_class_init (MyObjClass *class)
30 {
31   signals[SIGNAL1] =
32     g_signal_new ("signal1",
33                   G_TYPE_FROM_CLASS (class),
34                   G_SIGNAL_RUN_LAST,
35                   0, NULL, NULL, NULL, G_TYPE_NONE, 0);
36   signals[SIGNAL2] =
37     g_signal_new ("signal2",
38                   G_TYPE_FROM_CLASS (class),
39                   G_SIGNAL_RUN_LAST,
40                   0, NULL, NULL, NULL, G_TYPE_NONE, 0);
41 }
42
43 static void
44 nop (void)
45 {
46 }
47
48 static guint n_handlers = 0;
49
50 static void
51 test_connect_many (void)
52 {
53   MyObj *o;
54   gdouble time_elapsed;
55   guint i;
56
57   o = g_object_new (my_obj_get_type (), NULL);
58
59   g_test_timer_start ();
60
61   for (i = 0; i < n_handlers; i++)
62     g_signal_connect (o, "signal1", G_CALLBACK (nop), NULL); 
63
64   time_elapsed = g_test_timer_elapsed ();
65
66   g_object_unref (o);
67
68   g_test_minimized_result (time_elapsed, "connected %u handlers in %6.3f seconds", n_handlers, time_elapsed);
69 }
70
71 static void
72 test_disconnect_many_ordered (void)
73 {
74   MyObj *o;
75   gulong *handlers;
76   gdouble time_elapsed;
77   guint i;
78
79   handlers = g_malloc_n (n_handlers, sizeof (*handlers));
80   o = g_object_new (my_obj_get_type (), NULL);
81
82   for (i = 0; i < n_handlers; i++)
83     handlers[i] = g_signal_connect (o, "signal1", G_CALLBACK (nop), NULL); 
84
85   g_test_timer_start ();
86
87   for (i = 0; i < n_handlers; i++)
88     g_signal_handler_disconnect (o, handlers[i]); 
89
90   time_elapsed = g_test_timer_elapsed ();
91
92   g_object_unref (o);
93   g_free (handlers);
94
95   g_test_minimized_result (time_elapsed, "disconnected %u handlers in %6.3f seconds", n_handlers, time_elapsed);
96 }
97
98 static void
99 test_disconnect_many_inverse (void)
100 {
101   MyObj *o;
102   gulong *handlers;
103   gdouble time_elapsed;
104   guint i;
105
106   handlers = g_malloc_n (n_handlers, sizeof (*handlers));
107   o = g_object_new (my_obj_get_type (), NULL);
108
109   for (i = 0; i < n_handlers; i++)
110     handlers[i] = g_signal_connect (o, "signal1", G_CALLBACK (nop), NULL); 
111
112   g_test_timer_start ();
113
114   for (i = n_handlers; i > 0; i--)
115     g_signal_handler_disconnect (o, handlers[i - 1]);
116
117   time_elapsed = g_test_timer_elapsed ();
118
119   g_object_unref (o);
120   g_free (handlers);
121
122   g_test_minimized_result (time_elapsed, "disconnected %u handlers in %6.3f seconds", n_handlers, time_elapsed);
123 }
124
125 static void
126 test_disconnect_many_random (void)
127 {
128   MyObj *o;
129   gulong *handlers;
130   gulong id;
131   gdouble time_elapsed;
132   guint i, j;
133
134   handlers = g_malloc_n (n_handlers, sizeof (*handlers));
135   o = g_object_new (my_obj_get_type (), NULL);
136
137   for (i = 0; i < n_handlers; i++)
138     handlers[i] = g_signal_connect (o, "signal1", G_CALLBACK (nop), NULL); 
139
140   for (i = 0; i < n_handlers; i++)
141     {
142       j = g_test_rand_int_range (0, n_handlers);
143       id = handlers[i];
144       handlers[i] = handlers[j];
145       handlers[j] = id;
146     }
147
148   g_test_timer_start ();
149
150   for (i = 0; i < n_handlers; i++)
151     g_signal_handler_disconnect (o, handlers[i]); 
152
153   time_elapsed = g_test_timer_elapsed ();
154
155   g_object_unref (o);
156   g_free (handlers);
157
158   g_test_minimized_result (time_elapsed, "disconnected %u handlers in %6.3f seconds", n_handlers, time_elapsed);
159 }
160
161 static void
162 test_disconnect_2_signals (void)
163 {
164   MyObj *o;
165   gulong *handlers;
166   gulong id;
167   gdouble time_elapsed;
168   guint i, j;
169
170   handlers = g_malloc_n (n_handlers, sizeof (*handlers));
171   o = g_object_new (my_obj_get_type (), NULL);
172
173   for (i = 0; i < n_handlers; i++)
174     {
175       if (i % 2 == 0)
176         handlers[i] = g_signal_connect (o, "signal1", G_CALLBACK (nop), NULL); 
177       else
178         handlers[i] = g_signal_connect (o, "signal2", G_CALLBACK (nop), NULL); 
179     }
180
181   for (i = 0; i < n_handlers; i++)
182     {
183       j = g_test_rand_int_range (0, n_handlers);
184       id = handlers[i];
185       handlers[i] = handlers[j];
186       handlers[j] = id;
187     }
188
189   g_test_timer_start ();
190
191   for (i = 0; i < n_handlers; i++)
192     g_signal_handler_disconnect (o, handlers[i]); 
193
194   time_elapsed = g_test_timer_elapsed ();
195
196   g_object_unref (o);
197   g_free (handlers);
198
199   g_test_minimized_result (time_elapsed, "disconnected %u handlers in %6.3f seconds", n_handlers, time_elapsed);
200 }
201
202 static void
203 test_disconnect_2_objects (void)
204 {
205   MyObj *o1, *o2, *o;
206   gulong *handlers;
207   MyObj **objects;
208   gulong id;
209   gdouble time_elapsed;
210   guint i, j;
211
212   handlers = g_malloc_n (n_handlers, sizeof (*handlers));
213   objects = g_malloc_n (n_handlers, sizeof (*objects));
214   o1 = g_object_new (my_obj_get_type (), NULL);
215   o2 = g_object_new (my_obj_get_type (), NULL);
216
217   for (i = 0; i < n_handlers; i++)
218     {
219       if (i % 2 == 0)
220         {
221           handlers[i] = g_signal_connect (o1, "signal1", G_CALLBACK (nop), NULL); 
222           objects[i] = o1;
223         }
224       else
225         {
226           handlers[i] = g_signal_connect (o2, "signal1", G_CALLBACK (nop), NULL); 
227           objects[i] = o2;
228         }
229     }
230
231   for (i = 0; i < n_handlers; i++)
232     {
233       j = g_test_rand_int_range (0, n_handlers);
234       id = handlers[i];
235       handlers[i] = handlers[j];
236       handlers[j] = id;
237       o = objects[i];
238       objects[i] = objects[j];
239       objects[j] = o;
240     }
241
242   g_test_timer_start ();
243
244   for (i = 0; i < n_handlers; i++)
245     g_signal_handler_disconnect (objects[i], handlers[i]); 
246
247   time_elapsed = g_test_timer_elapsed ();
248
249   g_object_unref (o1);
250   g_object_unref (o2);
251   g_free (objects);
252   g_free (handlers);
253
254   g_test_minimized_result (time_elapsed, "disconnected %u handlers in %6.3f seconds", n_handlers, time_elapsed);
255 }
256
257 static void
258 test_block_many (void)
259 {
260   MyObj *o;
261   gulong *handlers;
262   gulong id;
263   gdouble time_elapsed;
264   guint i, j;
265
266   handlers = g_malloc_n (n_handlers, sizeof (*handlers));
267   o = g_object_new (my_obj_get_type (), NULL);
268
269   for (i = 0; i < n_handlers; i++)
270     handlers[i] = g_signal_connect (o, "signal1", G_CALLBACK (nop), NULL); 
271
272   for (i = 0; i < n_handlers; i++)
273     {
274       j = g_test_rand_int_range (0, n_handlers);
275       id = handlers[i];
276       handlers[i] = handlers[j];
277       handlers[j] = id;
278     }
279
280   g_test_timer_start ();
281
282   for (i = 0; i < n_handlers; i++)
283     g_signal_handler_block (o, handlers[i]); 
284
285   for (i = n_handlers; i > 0; i--)
286     g_signal_handler_unblock (o, handlers[i - 1]);
287
288   time_elapsed = g_test_timer_elapsed ();
289
290   g_object_unref (o);
291   g_free (handlers);
292
293   g_test_minimized_result (time_elapsed, "blocked and unblocked %u handlers in %6.3f seconds", n_handlers, time_elapsed);
294 }
295
296 int
297 main (int argc, char *argv[])
298 {
299   g_test_init (&argc, &argv, NULL);
300
301   n_handlers = g_test_perf () ? 500000 : 1;
302
303   g_test_add_func ("/signal/handler/connect-many", test_connect_many);
304   g_test_add_func ("/signal/handler/disconnect-many-ordered", test_disconnect_many_ordered);
305   g_test_add_func ("/signal/handler/disconnect-many-inverse", test_disconnect_many_inverse);
306   g_test_add_func ("/signal/handler/disconnect-many-random", test_disconnect_many_random);
307   g_test_add_func ("/signal/handler/disconnect-2-signals", test_disconnect_2_signals);
308   g_test_add_func ("/signal/handler/disconnect-2-objects", test_disconnect_2_objects);
309   g_test_add_func ("/signal/handler/block-many", test_block_many);
310
311   return g_test_run ();
312 }