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
39static int
40fd_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
50TEST(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
74struct free_source_context {
75 struct wl_event_source *source1, *source2;
76 int p1[2], p2[2];
77 int count;
78};
79
80static int
81free_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
101TEST(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
150static int
151signal_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
161TEST(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
193TEST(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
240static int
241timer_callback(void *data)
242{
243 int *got_it = data;
244
245 ++(*got_it);
246
247 return 1;
248}
249
250TEST(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
285struct timer_update_context {
286 struct wl_event_source *source1, *source2;
287 int count;
288};
289
290static int
291timer_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
300static int
301timer_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
310TEST(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
369struct timer_order_data {
370 struct wl_event_source *source;
371 int *last_number;
372 int number;
373};
374
375static int
376timer_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
386TEST(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
427struct 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
434static int
435timer_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
460TEST(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
501struct event_loop_destroy_listener {
502 struct wl_listener listener;
503 int done;
504};
505
506static void
507event_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
515TEST(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

source code of gtk/subprojects/wayland/tests/event-loop-test.c