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