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