1 | /* |
2 | * Copyright © 2012 Intel Corporation |
3 | * Copyright © 2012 Jason Ekstrand |
4 | * |
5 | * Permission is hereby granted, free of charge, to any person obtaining |
6 | * a copy of this software and associated documentation files (the |
7 | * "Software"), to deal in the Software without restriction, including |
8 | * without limitation the rights to use, copy, modify, merge, publish, |
9 | * distribute, sublicense, and/or sell copies of the Software, and to |
10 | * permit persons to whom the Software is furnished to do so, subject to |
11 | * the following conditions: |
12 | * |
13 | * The above copyright notice and this permission notice (including the |
14 | * next paragraph) shall be included in all copies or substantial |
15 | * portions of the Software. |
16 | * |
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
21 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
22 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
23 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
24 | * SOFTWARE. |
25 | */ |
26 | |
27 | #include <stdlib.h> |
28 | #include <stdint.h> |
29 | #include <assert.h> |
30 | #include <unistd.h> |
31 | #include <signal.h> |
32 | #include <string.h> |
33 | #include <sys/time.h> |
34 | |
35 | #include "wayland-private.h" |
36 | #include "wayland-server.h" |
37 | #include "test-runner.h" |
38 | |
39 | static int |
40 | fd_dispatch(int fd, uint32_t mask, void *data) |
41 | { |
42 | int *p = data; |
43 | |
44 | assert(mask == 0); |
45 | ++(*p); |
46 | |
47 | return 0; |
48 | } |
49 | |
50 | TEST(event_loop_post_dispatch_check) |
51 | { |
52 | struct wl_event_loop *loop = wl_event_loop_create(); |
53 | struct wl_event_source *source; |
54 | int dispatch_ran = 0; |
55 | int p[2]; |
56 | |
57 | assert(loop); |
58 | assert(pipe(p) == 0); |
59 | |
60 | source = wl_event_loop_add_fd(loop, fd: p[0], mask: WL_EVENT_READABLE, |
61 | func: fd_dispatch, data: &dispatch_ran); |
62 | assert(source); |
63 | wl_event_source_check(source); |
64 | |
65 | wl_event_loop_dispatch(loop, timeout: 0); |
66 | assert(dispatch_ran == 1); |
67 | |
68 | assert(close(p[0]) == 0); |
69 | assert(close(p[1]) == 0); |
70 | wl_event_source_remove(source); |
71 | wl_event_loop_destroy(loop); |
72 | } |
73 | |
74 | struct free_source_context { |
75 | struct wl_event_source *source1, *source2; |
76 | int p1[2], p2[2]; |
77 | int count; |
78 | }; |
79 | |
80 | static int |
81 | free_source_callback(int fd, uint32_t mask, void *data) |
82 | { |
83 | struct free_source_context *context = data; |
84 | |
85 | context->count++; |
86 | |
87 | /* Remove other source */ |
88 | if (fd == context->p1[0]) { |
89 | wl_event_source_remove(source: context->source2); |
90 | context->source2 = NULL; |
91 | } else if (fd == context->p2[0]) { |
92 | wl_event_source_remove(source: context->source1); |
93 | context->source1 = NULL; |
94 | } else { |
95 | assert(0); |
96 | } |
97 | |
98 | return 1; |
99 | } |
100 | |
101 | TEST(event_loop_free_source_with_data) |
102 | { |
103 | struct wl_event_loop *loop = wl_event_loop_create(); |
104 | struct free_source_context context; |
105 | int data; |
106 | |
107 | /* This test is a little tricky to get right, since we don't |
108 | * have any guarantee from the event loop (ie epoll) on the |
109 | * order of which it reports events. We want to have one |
110 | * source free the other, but we don't know which one is going |
111 | * to run first. So we add two fd sources with a callback |
112 | * that frees the other source and check that only one of them |
113 | * run (and that we don't crash, of course). |
114 | */ |
115 | |
116 | assert(loop); |
117 | |
118 | context.count = 0; |
119 | assert(pipe(context.p1) == 0); |
120 | assert(pipe(context.p2) == 0); |
121 | context.source1 = |
122 | wl_event_loop_add_fd(loop, fd: context.p1[0], mask: WL_EVENT_READABLE, |
123 | func: free_source_callback, data: &context); |
124 | assert(context.source1); |
125 | context.source2 = |
126 | wl_event_loop_add_fd(loop, fd: context.p2[0], mask: WL_EVENT_READABLE, |
127 | func: free_source_callback, data: &context); |
128 | assert(context.source2); |
129 | |
130 | data = 5; |
131 | assert(write(context.p1[1], &data, sizeof data) == sizeof data); |
132 | assert(write(context.p2[1], &data, sizeof data) == sizeof data); |
133 | |
134 | wl_event_loop_dispatch(loop, timeout: 0); |
135 | |
136 | assert(context.count == 1); |
137 | |
138 | if (context.source1) |
139 | wl_event_source_remove(source: context.source1); |
140 | if (context.source2) |
141 | wl_event_source_remove(source: context.source2); |
142 | wl_event_loop_destroy(loop); |
143 | |
144 | assert(close(context.p1[0]) == 0); |
145 | assert(close(context.p1[1]) == 0); |
146 | assert(close(context.p2[0]) == 0); |
147 | assert(close(context.p2[1]) == 0); |
148 | } |
149 | |
150 | static int |
151 | signal_callback(int signal_number, void *data) |
152 | { |
153 | int *got_it = data; |
154 | |
155 | assert(signal_number == SIGUSR1); |
156 | ++(*got_it); |
157 | |
158 | return 1; |
159 | } |
160 | |
161 | TEST(event_loop_signal) |
162 | { |
163 | struct wl_event_loop *loop = wl_event_loop_create(); |
164 | struct wl_event_source *source; |
165 | int got_it = 0; |
166 | |
167 | source = wl_event_loop_add_signal(loop, SIGUSR1, |
168 | func: signal_callback, data: &got_it); |
169 | assert(source); |
170 | |
171 | assert(wl_event_loop_dispatch(loop, 0) == 0); |
172 | assert(!got_it); |
173 | assert(kill(getpid(), SIGUSR1) == 0); |
174 | /* |
175 | * On Linux the signal will be immediately visible in the epoll_wait() |
176 | * call. However, on FreeBSD we may need a small delay between kill() |
177 | * call and the signal being visible to the kevent() call. This |
178 | * sometimes happens when the signal processing and kevent processing |
179 | * runs on different CPUs, so becomes more likely when the system is |
180 | * under load (e.g. running all tests in parallel). |
181 | * See https://github.com/jiixyj/epoll-shim/pull/32 |
182 | * Passing 1ms as the timeout appears to avoid this race condition in |
183 | * all cases tested so far, but to be safe we use 1000ms which should |
184 | * be enough time even on a really slow (or emulated) system. |
185 | */ |
186 | assert(wl_event_loop_dispatch(loop, 1000) == 0); |
187 | assert(got_it == 1); |
188 | |
189 | wl_event_source_remove(source); |
190 | wl_event_loop_destroy(loop); |
191 | } |
192 | |
193 | TEST(event_loop_multiple_same_signals) |
194 | { |
195 | struct wl_event_loop *loop = wl_event_loop_create(); |
196 | struct wl_event_source *s1, *s2; |
197 | int calls_no = 0; |
198 | int i; |
199 | |
200 | s1 = wl_event_loop_add_signal(loop, SIGUSR1, |
201 | func: signal_callback, data: &calls_no); |
202 | assert(s1); |
203 | |
204 | s2 = wl_event_loop_add_signal(loop, SIGUSR1, |
205 | func: signal_callback, data: &calls_no); |
206 | assert(s2); |
207 | |
208 | assert(wl_event_loop_dispatch(loop, 0) == 0); |
209 | assert(!calls_no); |
210 | |
211 | /* Try it more times */ |
212 | for (i = 0; i < 5; ++i) { |
213 | calls_no = 0; |
214 | assert(kill(getpid(), SIGUSR1) == 0); |
215 | /* |
216 | * We need a non-zero timeout here to allow the test to pass |
217 | * on non-Linux systems (see comment in event_loop_signal). |
218 | */ |
219 | assert(wl_event_loop_dispatch(loop, 1000) == 0); |
220 | assert(calls_no == 2); |
221 | } |
222 | |
223 | wl_event_source_remove(source: s1); |
224 | |
225 | /* Try it again with one source */ |
226 | calls_no = 0; |
227 | assert(kill(getpid(), SIGUSR1) == 0); |
228 | /* |
229 | * We need a non-zero timeout here to allow the test to pass |
230 | * on non-Linux systems (see comment in event_loop_signal). |
231 | */ |
232 | assert(wl_event_loop_dispatch(loop, 1000) == 0); |
233 | assert(calls_no == 1); |
234 | |
235 | wl_event_source_remove(source: s2); |
236 | |
237 | wl_event_loop_destroy(loop); |
238 | } |
239 | |
240 | static int |
241 | timer_callback(void *data) |
242 | { |
243 | int *got_it = data; |
244 | |
245 | ++(*got_it); |
246 | |
247 | return 1; |
248 | } |
249 | |
250 | TEST(event_loop_timer) |
251 | { |
252 | struct wl_event_loop *loop = wl_event_loop_create(); |
253 | struct wl_event_source *source1, *source2; |
254 | int got_it = 0; |
255 | |
256 | source1 = wl_event_loop_add_timer(loop, func: timer_callback, data: &got_it); |
257 | assert(source1); |
258 | wl_event_source_timer_update(source: source1, ms_delay: 20); |
259 | |
260 | source2 = wl_event_loop_add_timer(loop, func: timer_callback, data: &got_it); |
261 | assert(source2); |
262 | wl_event_source_timer_update(source: source2, ms_delay: 100); |
263 | |
264 | /* Check that the timer marked for 20 msec from now fires within 30 |
265 | * msec, and that the timer marked for 100 msec is expected to fire |
266 | * within an additional 90 msec. (Some extra wait time is provided to |
267 | * account for reasonable code execution / thread preemption delays.) */ |
268 | |
269 | wl_event_loop_dispatch(loop, timeout: 0); |
270 | assert(got_it == 0); |
271 | wl_event_loop_dispatch(loop, timeout: 30); |
272 | assert(got_it == 1); |
273 | wl_event_loop_dispatch(loop, timeout: 0); |
274 | assert(got_it == 1); |
275 | wl_event_loop_dispatch(loop, timeout: 90); |
276 | assert(got_it == 2); |
277 | |
278 | wl_event_source_remove(source: source1); |
279 | wl_event_source_remove(source: source2); |
280 | wl_event_loop_destroy(loop); |
281 | } |
282 | |
283 | #define MSEC_TO_USEC(msec) ((msec) * 1000) |
284 | |
285 | struct timer_update_context { |
286 | struct wl_event_source *source1, *source2; |
287 | int count; |
288 | }; |
289 | |
290 | static int |
291 | timer_update_callback_1(void *data) |
292 | { |
293 | struct timer_update_context *context = data; |
294 | |
295 | context->count++; |
296 | wl_event_source_timer_update(source: context->source2, ms_delay: 1000); |
297 | return 1; |
298 | } |
299 | |
300 | static int |
301 | timer_update_callback_2(void *data) |
302 | { |
303 | struct timer_update_context *context = data; |
304 | |
305 | context->count++; |
306 | wl_event_source_timer_update(source: context->source1, ms_delay: 1000); |
307 | return 1; |
308 | } |
309 | |
310 | TEST(event_loop_timer_updates) |
311 | { |
312 | struct wl_event_loop *loop = wl_event_loop_create(); |
313 | struct timer_update_context context; |
314 | struct timeval start_time, end_time, interval; |
315 | |
316 | /* Create two timers that should expire at the same time (after 10ms). |
317 | * The first timer to receive its expiry callback updates the other timer |
318 | * with a much larger timeout (1s). This highlights a bug where |
319 | * wl_event_source_timer_dispatch would block for this larger timeout |
320 | * when reading from the timer fd, before calling the second timer's |
321 | * callback. |
322 | */ |
323 | |
324 | context.source1 = wl_event_loop_add_timer(loop, func: timer_update_callback_1, |
325 | data: &context); |
326 | assert(context.source1); |
327 | assert(wl_event_source_timer_update(context.source1, 10) == 0); |
328 | |
329 | context.source2 = wl_event_loop_add_timer(loop, func: timer_update_callback_2, |
330 | data: &context); |
331 | assert(context.source2); |
332 | assert(wl_event_source_timer_update(context.source2, 10) == 0); |
333 | |
334 | context.count = 0; |
335 | |
336 | /* Since calling the functions between source2's update and |
337 | * wl_event_loop_dispatch() takes some time, it may happen |
338 | * that only one timer expires until we call epoll_wait. |
339 | * This naturally means that only one source is dispatched |
340 | * and the test fails. To fix that, sleep 15 ms before |
341 | * calling wl_event_loop_dispatch(). That should be enough |
342 | * for the second timer to expire. |
343 | * |
344 | * https://bugs.freedesktop.org/show_bug.cgi?id=80594 |
345 | */ |
346 | usleep(MSEC_TO_USEC(15)); |
347 | |
348 | gettimeofday(tv: &start_time, NULL); |
349 | wl_event_loop_dispatch(loop, timeout: 20); |
350 | gettimeofday(tv: &end_time, NULL); |
351 | |
352 | assert(context.count == 2); |
353 | |
354 | /* Dispatching the events should not have taken much more than 20ms, |
355 | * since this is the timeout passed to wl_event_loop_dispatch. If it |
356 | * blocked, then it will have taken over 1s. |
357 | * Of course, it could take over 1s anyway on a very slow or heavily |
358 | * loaded system, so this test isn't 100% perfect. |
359 | */ |
360 | |
361 | timersub(&end_time, &start_time, &interval); |
362 | assert(interval.tv_sec < 1); |
363 | |
364 | wl_event_source_remove(source: context.source1); |
365 | wl_event_source_remove(source: context.source2); |
366 | wl_event_loop_destroy(loop); |
367 | } |
368 | |
369 | struct timer_order_data { |
370 | struct wl_event_source *source; |
371 | int *last_number; |
372 | int number; |
373 | }; |
374 | |
375 | static int |
376 | timer_order_callback(void *data) |
377 | { |
378 | struct timer_order_data *tod = data; |
379 | |
380 | /* Check that the timers have the correct sequence */ |
381 | assert(tod->number == *tod->last_number + 2); |
382 | *tod->last_number = tod->number; |
383 | return 0; |
384 | } |
385 | |
386 | TEST(event_loop_timer_order) |
387 | { |
388 | struct wl_event_loop *loop = wl_event_loop_create(); |
389 | struct timer_order_data order[20]; |
390 | int i, j; |
391 | int last = -1; |
392 | |
393 | /* Configure a set of timers so that only timers 1, 3, 5, ..., 19 |
394 | * (in that order) will be dispatched when the event loop is run */ |
395 | |
396 | for (i = 0; i < 20; i++) { |
397 | order[i].number = i; |
398 | order[i].last_number = &last; |
399 | order[i].source = |
400 | wl_event_loop_add_timer(loop, func: timer_order_callback, |
401 | data: &order[i]); |
402 | assert(order[i].source); |
403 | assert(wl_event_source_timer_update(order[i].source, 10) == 0); |
404 | } |
405 | |
406 | for (i = 0; i < 20; i++) { |
407 | /* Permute the order in which timers are updated, so as to |
408 | * more exhaustively test the underlying priority queue code */ |
409 | j = ((i + 3) * 17) % 20; |
410 | assert(wl_event_source_timer_update(order[j].source, j) == 0); |
411 | } |
412 | for (i = 0; i < 20; i += 2) { |
413 | assert(wl_event_source_timer_update(order[i].source, 0) == 0); |
414 | } |
415 | |
416 | /* Wait until all timers are due */ |
417 | usleep(MSEC_TO_USEC(21)); |
418 | wl_event_loop_dispatch(loop, timeout: 0); |
419 | assert(last == 19); |
420 | |
421 | for (i = 0; i < 20; i++) { |
422 | wl_event_source_remove(source: order[i].source); |
423 | } |
424 | wl_event_loop_destroy(loop); |
425 | } |
426 | |
427 | struct timer_cancel_context { |
428 | struct wl_event_source *timers[4]; |
429 | struct timer_cancel_context *back_refs[4]; |
430 | int order[4]; |
431 | int called, first; |
432 | }; |
433 | |
434 | static int |
435 | timer_cancel_callback(void *data) { |
436 | struct timer_cancel_context **context_ref = data; |
437 | struct timer_cancel_context *context = *context_ref; |
438 | int i = (int)(context_ref - context->back_refs); |
439 | |
440 | context->called++; |
441 | context->order[i] = context->called; |
442 | |
443 | if (context->called == 1) { |
444 | context->first = i; |
445 | /* Removing a timer always prevents its callback from |
446 | * being called ... */ |
447 | wl_event_source_remove(source: context->timers[(i + 1) % 4]); |
448 | /* ... but disarming or rescheduling a timer does not, |
449 | * (in the case where the modified timers had already expired |
450 | * as of when `wl_event_loop_dispatch` was called.) */ |
451 | assert(wl_event_source_timer_update(context->timers[(i + 2) % 4], |
452 | 0) == 0); |
453 | assert(wl_event_source_timer_update(context->timers[(i + 3) % 4], |
454 | 2000000000) == 0); |
455 | } |
456 | |
457 | return 0; |
458 | } |
459 | |
460 | TEST(event_loop_timer_cancellation) |
461 | { |
462 | struct wl_event_loop *loop = wl_event_loop_create(); |
463 | struct timer_cancel_context context; |
464 | int i; |
465 | |
466 | memset(s: &context, c: 0, n: sizeof(context)); |
467 | |
468 | /* Test that when multiple timers are dispatched in a single call |
469 | * of `wl_event_loop_dispatch`, that having some timers run code |
470 | * to modify the other timers only actually prevents the other timers |
471 | * from running their callbacks when the those timers are removed, not |
472 | * when they are disarmed or rescheduled. */ |
473 | |
474 | for (i = 0; i < 4; i++) { |
475 | context.back_refs[i] = &context; |
476 | context.timers[i] = |
477 | wl_event_loop_add_timer(loop, func: timer_cancel_callback, |
478 | data: &context.back_refs[i]); |
479 | assert(context.timers[i]); |
480 | |
481 | assert(wl_event_source_timer_update(context.timers[i], 1) == 0); |
482 | } |
483 | |
484 | usleep(MSEC_TO_USEC(2)); |
485 | assert(wl_event_loop_dispatch(loop, 0) == 0); |
486 | |
487 | /* Tracking which timer was first makes this test independent of the |
488 | * actual timer dispatch order, which is not guaranteed by the docs */ |
489 | assert(context.order[context.first] == 1); |
490 | assert(context.order[(context.first + 1) % 4] == 0); |
491 | assert(context.order[(context.first + 2) % 4] > 1); |
492 | assert(context.order[(context.first + 3) % 4] > 1); |
493 | |
494 | wl_event_source_remove(source: context.timers[context.first]); |
495 | wl_event_source_remove(source: context.timers[(context.first + 2) % 4]); |
496 | wl_event_source_remove(source: context.timers[(context.first + 3) % 4]); |
497 | |
498 | wl_event_loop_destroy(loop); |
499 | } |
500 | |
501 | struct event_loop_destroy_listener { |
502 | struct wl_listener listener; |
503 | int done; |
504 | }; |
505 | |
506 | static void |
507 | event_loop_destroy_notify(struct wl_listener *l, void *data) |
508 | { |
509 | struct event_loop_destroy_listener *listener = |
510 | wl_container_of(l, listener, listener); |
511 | |
512 | listener->done = 1; |
513 | } |
514 | |
515 | TEST(event_loop_destroy) |
516 | { |
517 | struct wl_event_loop *loop; |
518 | struct wl_display * display; |
519 | struct event_loop_destroy_listener a, b; |
520 | |
521 | loop = wl_event_loop_create(); |
522 | assert(loop); |
523 | |
524 | a.listener.notify = &event_loop_destroy_notify; |
525 | a.done = 0; |
526 | wl_event_loop_add_destroy_listener(loop, listener: &a.listener); |
527 | |
528 | assert(wl_event_loop_get_destroy_listener(loop, |
529 | event_loop_destroy_notify) == &a.listener); |
530 | |
531 | b.listener.notify = &event_loop_destroy_notify; |
532 | b.done = 0; |
533 | wl_event_loop_add_destroy_listener(loop, listener: &b.listener); |
534 | |
535 | wl_list_remove(elm: &a.listener.link); |
536 | wl_event_loop_destroy(loop); |
537 | |
538 | assert(!a.done); |
539 | assert(b.done); |
540 | |
541 | /* Test to make sure it gets fired on display destruction */ |
542 | display = wl_display_create(); |
543 | assert(display); |
544 | loop = wl_display_get_event_loop(display); |
545 | assert(loop); |
546 | |
547 | a.done = 0; |
548 | wl_event_loop_add_destroy_listener(loop, listener: &a.listener); |
549 | |
550 | wl_display_destroy(display); |
551 | |
552 | assert(a.done); |
553 | } |
554 | |
555 | |