Home | History | Annotate | Download | only in tests
      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 <sys/time.h>
     33 
     34 #include "wayland-private.h"
     35 #include "wayland-server.h"
     36 #include "test-runner.h"
     37 
     38 static int
     39 fd_dispatch(int fd, uint32_t mask, void *data)
     40 {
     41 	int *p = data;
     42 
     43 	assert(mask == 0);
     44 	++(*p);
     45 
     46 	return 0;
     47 }
     48 
     49 TEST(event_loop_post_dispatch_check)
     50 {
     51 	struct wl_event_loop *loop = wl_event_loop_create();
     52 	struct wl_event_source *source;
     53 	int dispatch_ran = 0;
     54 	int p[2];
     55 
     56 	assert(loop);
     57 	assert(pipe(p) == 0);
     58 
     59 	source = wl_event_loop_add_fd(loop, p[0], WL_EVENT_READABLE,
     60 				      fd_dispatch, &dispatch_ran);
     61 	assert(source);
     62 	wl_event_source_check(source);
     63 
     64 	wl_event_loop_dispatch(loop, 0);
     65 	assert(dispatch_ran == 1);
     66 
     67 	assert(close(p[0]) == 0);
     68 	assert(close(p[1]) == 0);
     69 	wl_event_source_remove(source);
     70 	wl_event_loop_destroy(loop);
     71 }
     72 
     73 struct free_source_context {
     74 	struct wl_event_source *source1, *source2;
     75 	int p1[2], p2[2];
     76 	int count;
     77 };
     78 
     79 static int
     80 free_source_callback(int fd, uint32_t mask, void *data)
     81 {
     82 	struct free_source_context *context = data;
     83 
     84 	context->count++;
     85 
     86 	/* Remove other source */
     87 	if (fd == context->p1[0]) {
     88 		wl_event_source_remove(context->source2);
     89 		context->source2 = NULL;
     90 	} else if (fd == context->p2[0]) {
     91 		wl_event_source_remove(context->source1);
     92 		context->source1 = NULL;
     93 	} else {
     94 		assert(0);
     95 	}
     96 
     97 	return 1;
     98 }
     99 
    100 TEST(event_loop_free_source_with_data)
    101 {
    102 	struct wl_event_loop *loop = wl_event_loop_create();
    103 	struct free_source_context context;
    104 	int data;
    105 
    106 	/* This test is a little tricky to get right, since we don't
    107 	 * have any guarantee from the event loop (ie epoll) on the
    108 	 * order of which it reports events.  We want to have one
    109 	 * source free the other, but we don't know which one is going
    110 	 * to run first.  So we add two fd sources with a callback
    111 	 * that frees the other source and check that only one of them
    112 	 * run (and that we don't crash, of course).
    113 	 */
    114 
    115 	assert(loop);
    116 
    117 	context.count = 0;
    118 	assert(pipe(context.p1) == 0);
    119 	assert(pipe(context.p2) == 0);
    120 	context.source1 =
    121 		wl_event_loop_add_fd(loop, context.p1[0], WL_EVENT_READABLE,
    122 				     free_source_callback, &context);
    123 	assert(context.source1);
    124 	context.source2 =
    125 		wl_event_loop_add_fd(loop, context.p2[0], WL_EVENT_READABLE,
    126 				     free_source_callback, &context);
    127 	assert(context.source2);
    128 
    129 	data = 5;
    130 	assert(write(context.p1[1], &data, sizeof data) == sizeof data);
    131 	assert(write(context.p2[1], &data, sizeof data) == sizeof data);
    132 
    133 	wl_event_loop_dispatch(loop, 0);
    134 
    135 	assert(context.count == 1);
    136 
    137 	if (context.source1)
    138 		wl_event_source_remove(context.source1);
    139 	if (context.source2)
    140 		wl_event_source_remove(context.source2);
    141 	wl_event_loop_destroy(loop);
    142 
    143 	assert(close(context.p1[0]) == 0);
    144 	assert(close(context.p1[1]) == 0);
    145 	assert(close(context.p2[0]) == 0);
    146 	assert(close(context.p2[1]) == 0);
    147 }
    148 
    149 static int
    150 signal_callback(int signal_number, void *data)
    151 {
    152 	int *got_it = data;
    153 
    154 	assert(signal_number == SIGUSR1);
    155 	++(*got_it);
    156 
    157 	return 1;
    158 }
    159 
    160 TEST(event_loop_signal)
    161 {
    162 	struct wl_event_loop *loop = wl_event_loop_create();
    163 	struct wl_event_source *source;
    164 	int got_it = 0;
    165 
    166 	source = wl_event_loop_add_signal(loop, SIGUSR1,
    167 					  signal_callback, &got_it);
    168 	assert(source);
    169 
    170 	wl_event_loop_dispatch(loop, 0);
    171 	assert(!got_it);
    172 	kill(getpid(), SIGUSR1);
    173 	wl_event_loop_dispatch(loop, 0);
    174 	assert(got_it == 1);
    175 
    176 	wl_event_source_remove(source);
    177 	wl_event_loop_destroy(loop);
    178 }
    179 
    180 TEST(event_loop_multiple_same_signals)
    181 {
    182 	struct wl_event_loop *loop = wl_event_loop_create();
    183 	struct wl_event_source *s1, *s2;
    184 	int calls_no = 0;
    185 	int i;
    186 
    187 	s1 = wl_event_loop_add_signal(loop, SIGUSR1,
    188 				      signal_callback, &calls_no);
    189 	assert(s1);
    190 
    191 	s2 = wl_event_loop_add_signal(loop, SIGUSR1,
    192 				      signal_callback, &calls_no);
    193 	assert(s2);
    194 
    195 	assert(wl_event_loop_dispatch(loop, 0) == 0);
    196 	assert(!calls_no);
    197 
    198 	/* Try it more times */
    199 	for (i = 0; i < 5; ++i) {
    200 		calls_no = 0;
    201 		kill(getpid(), SIGUSR1);
    202 		assert(wl_event_loop_dispatch(loop, 0) == 0);
    203 		assert(calls_no == 2);
    204 	}
    205 
    206 	wl_event_source_remove(s1);
    207 
    208 	/* Try it again  with one source */
    209 	calls_no = 0;
    210 	kill(getpid(), SIGUSR1);
    211 	assert(wl_event_loop_dispatch(loop, 0) == 0);
    212 	assert(calls_no == 1);
    213 
    214 	wl_event_source_remove(s2);
    215 
    216 	wl_event_loop_destroy(loop);
    217 }
    218 
    219 static int
    220 timer_callback(void *data)
    221 {
    222 	int *got_it = data;
    223 
    224 	++(*got_it);
    225 
    226 	return 1;
    227 }
    228 
    229 TEST(event_loop_timer)
    230 {
    231 	struct wl_event_loop *loop = wl_event_loop_create();
    232 	struct wl_event_source *source;
    233 	int got_it = 0;
    234 
    235 	source = wl_event_loop_add_timer(loop, timer_callback, &got_it);
    236 	assert(source);
    237 	wl_event_source_timer_update(source, 10);
    238 	wl_event_loop_dispatch(loop, 0);
    239 	assert(!got_it);
    240 	wl_event_loop_dispatch(loop, 20);
    241 	assert(got_it == 1);
    242 
    243 	wl_event_source_remove(source);
    244 	wl_event_loop_destroy(loop);
    245 }
    246 
    247 #define MSEC_TO_USEC(msec) ((msec) * 1000)
    248 
    249 struct timer_update_context {
    250 	struct wl_event_source *source1, *source2;
    251 	int count;
    252 };
    253 
    254 static int
    255 timer_update_callback_1(void *data)
    256 {
    257 	struct timer_update_context *context = data;
    258 
    259 	context->count++;
    260 	wl_event_source_timer_update(context->source2, 1000);
    261 	return 1;
    262 }
    263 
    264 static int
    265 timer_update_callback_2(void *data)
    266 {
    267 	struct timer_update_context *context = data;
    268 
    269 	context->count++;
    270 	wl_event_source_timer_update(context->source1, 1000);
    271 	return 1;
    272 }
    273 
    274 TEST(event_loop_timer_updates)
    275 {
    276 	struct wl_event_loop *loop = wl_event_loop_create();
    277 	struct timer_update_context context;
    278 	struct timeval start_time, end_time, interval;
    279 
    280 	/* Create two timers that should expire at the same time (after 10ms).
    281 	 * The first timer to receive its expiry callback updates the other timer
    282 	 * with a much larger timeout (1s). This highlights a bug where
    283 	 * wl_event_source_timer_dispatch would block for this larger timeout
    284 	 * when reading from the timer fd, before calling the second timer's
    285 	 * callback.
    286 	 */
    287 
    288 	context.source1 = wl_event_loop_add_timer(loop, timer_update_callback_1,
    289 						  &context);
    290 	assert(context.source1);
    291 	assert(wl_event_source_timer_update(context.source1, 10) == 0);
    292 
    293 	context.source2 = wl_event_loop_add_timer(loop, timer_update_callback_2,
    294 						  &context);
    295 	assert(context.source2);
    296 	assert(wl_event_source_timer_update(context.source2, 10) == 0);
    297 
    298 	context.count = 0;
    299 
    300 	/* Since calling the functions between source2's update and
    301 	 * wl_event_loop_dispatch() takes some time, it may happen
    302 	 * that only one timer expires until we call epoll_wait.
    303 	 * This naturally means that only one source is dispatched
    304 	 * and the test fails. To fix that, sleep 15 ms before
    305 	 * calling wl_event_loop_dispatch(). That should be enough
    306 	 * for the second timer to expire.
    307 	 *
    308 	 * https://bugs.freedesktop.org/show_bug.cgi?id=80594
    309 	 */
    310 	usleep(MSEC_TO_USEC(15));
    311 
    312 	gettimeofday(&start_time, NULL);
    313 	wl_event_loop_dispatch(loop, 20);
    314 	gettimeofday(&end_time, NULL);
    315 
    316 	assert(context.count == 2);
    317 
    318 	/* Dispatching the events should not have taken much more than 20ms,
    319 	 * since this is the timeout passed to wl_event_loop_dispatch. If it
    320 	 * blocked, then it will have taken over 1s.
    321 	 * Of course, it could take over 1s anyway on a very slow or heavily
    322 	 * loaded system, so this test isn't 100% perfect.
    323 	 */
    324 
    325 	timersub(&end_time, &start_time, &interval);
    326 	assert(interval.tv_sec < 1);
    327 
    328 	wl_event_source_remove(context.source1);
    329 	wl_event_source_remove(context.source2);
    330 	wl_event_loop_destroy(loop);
    331 }
    332 
    333 struct event_loop_destroy_listener {
    334 	struct wl_listener listener;
    335 	int done;
    336 };
    337 
    338 static void
    339 event_loop_destroy_notify(struct wl_listener *l, void *data)
    340 {
    341 	struct event_loop_destroy_listener *listener =
    342 		container_of(l, struct event_loop_destroy_listener, listener);
    343 
    344 	listener->done = 1;
    345 }
    346 
    347 TEST(event_loop_destroy)
    348 {
    349 	struct wl_event_loop *loop;
    350 	struct wl_display * display;
    351 	struct event_loop_destroy_listener a, b;
    352 
    353 	loop = wl_event_loop_create();
    354 	assert(loop);
    355 
    356 	a.listener.notify = &event_loop_destroy_notify;
    357 	a.done = 0;
    358 	wl_event_loop_add_destroy_listener(loop, &a.listener);
    359 
    360 	assert(wl_event_loop_get_destroy_listener(loop,
    361 	       event_loop_destroy_notify) == &a.listener);
    362 
    363 	b.listener.notify = &event_loop_destroy_notify;
    364 	b.done = 0;
    365 	wl_event_loop_add_destroy_listener(loop, &b.listener);
    366 
    367 	wl_list_remove(&a.listener.link);
    368 	wl_event_loop_destroy(loop);
    369 
    370 	assert(!a.done);
    371 	assert(b.done);
    372 
    373 	/* Test to make sure it gets fired on display destruction */
    374 	display = wl_display_create();
    375 	assert(display);
    376 	loop = wl_display_get_event_loop(display);
    377 	assert(loop);
    378 
    379 	a.done = 0;
    380 	wl_event_loop_add_destroy_listener(loop, &a.listener);
    381 
    382 	wl_display_destroy(display);
    383 
    384 	assert(a.done);
    385 }
    386 
    387