event-loop-test.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  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. #define _GNU_SOURCE
  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. #include "wayland-private.h"
  35. #include "wayland-server.h"
  36. #include "test-runner.h"
  37. static int
  38. fd_dispatch(int fd, uint32_t mask, void *data)
  39. {
  40. int *p = data;
  41. assert(mask == 0);
  42. ++(*p);
  43. return 0;
  44. }
  45. TEST(event_loop_post_dispatch_check)
  46. {
  47. struct wl_event_loop *loop = wl_event_loop_create();
  48. struct wl_event_source *source;
  49. int dispatch_ran = 0;
  50. int p[2];
  51. assert(loop);
  52. assert(pipe(p) == 0);
  53. source = wl_event_loop_add_fd(loop, p[0], WL_EVENT_READABLE,
  54. fd_dispatch, &dispatch_ran);
  55. assert(source);
  56. wl_event_source_check(source);
  57. wl_event_loop_dispatch(loop, 0);
  58. assert(dispatch_ran == 1);
  59. assert(close(p[0]) == 0);
  60. assert(close(p[1]) == 0);
  61. wl_event_source_remove(source);
  62. wl_event_loop_destroy(loop);
  63. }
  64. struct free_source_context {
  65. struct wl_event_source *source1, *source2;
  66. int p1[2], p2[2];
  67. int count;
  68. };
  69. static int
  70. free_source_callback(int fd, uint32_t mask, void *data)
  71. {
  72. struct free_source_context *context = data;
  73. context->count++;
  74. /* Remove other source */
  75. if (fd == context->p1[0]) {
  76. wl_event_source_remove(context->source2);
  77. context->source2 = NULL;
  78. } else if (fd == context->p2[0]) {
  79. wl_event_source_remove(context->source1);
  80. context->source1 = NULL;
  81. } else {
  82. assert(0);
  83. }
  84. return 1;
  85. }
  86. TEST(event_loop_free_source_with_data)
  87. {
  88. struct wl_event_loop *loop = wl_event_loop_create();
  89. struct free_source_context context;
  90. int data;
  91. /* This test is a little tricky to get right, since we don't
  92. * have any guarantee from the event loop (ie epoll) on the
  93. * order of which it reports events. We want to have one
  94. * source free the other, but we don't know which one is going
  95. * to run first. So we add two fd sources with a callback
  96. * that frees the other source and check that only one of them
  97. * run (and that we don't crash, of course).
  98. */
  99. assert(loop);
  100. context.count = 0;
  101. assert(pipe(context.p1) == 0);
  102. assert(pipe(context.p2) == 0);
  103. context.source1 =
  104. wl_event_loop_add_fd(loop, context.p1[0], WL_EVENT_READABLE,
  105. free_source_callback, &context);
  106. assert(context.source1);
  107. context.source2 =
  108. wl_event_loop_add_fd(loop, context.p2[0], WL_EVENT_READABLE,
  109. free_source_callback, &context);
  110. assert(context.source2);
  111. data = 5;
  112. assert(write(context.p1[1], &data, sizeof data) == sizeof data);
  113. assert(write(context.p2[1], &data, sizeof data) == sizeof data);
  114. wl_event_loop_dispatch(loop, 0);
  115. assert(context.count == 1);
  116. if (context.source1)
  117. wl_event_source_remove(context.source1);
  118. if (context.source2)
  119. wl_event_source_remove(context.source2);
  120. wl_event_loop_destroy(loop);
  121. assert(close(context.p1[0]) == 0);
  122. assert(close(context.p1[1]) == 0);
  123. assert(close(context.p2[0]) == 0);
  124. assert(close(context.p2[1]) == 0);
  125. }
  126. static int
  127. signal_callback(int signal_number, void *data)
  128. {
  129. int *got_it = data;
  130. assert(signal_number == SIGUSR1);
  131. ++(*got_it);
  132. return 1;
  133. }
  134. TEST(event_loop_signal)
  135. {
  136. struct wl_event_loop *loop = wl_event_loop_create();
  137. struct wl_event_source *source;
  138. int got_it = 0;
  139. source = wl_event_loop_add_signal(loop, SIGUSR1,
  140. signal_callback, &got_it);
  141. assert(source);
  142. assert(wl_event_loop_dispatch(loop, 0) == 0);
  143. assert(!got_it);
  144. assert(kill(getpid(), SIGUSR1) == 0);
  145. /*
  146. * On Linux the signal will be immediately visible in the epoll_wait()
  147. * call. However, on FreeBSD we may need a small delay between kill()
  148. * call and the signal being visible to the kevent() call. This
  149. * sometimes happens when the signal processing and kevent processing
  150. * runs on different CPUs, so becomes more likely when the system is
  151. * under load (e.g. running all tests in parallel).
  152. * See https://github.com/jiixyj/epoll-shim/pull/32
  153. * Passing 1ms as the timeout appears to avoid this race condition in
  154. * all cases tested so far, but to be safe we use 1000ms which should
  155. * be enough time even on a really slow (or emulated) system.
  156. */
  157. assert(wl_event_loop_dispatch(loop, 1000) == 0);
  158. assert(got_it == 1);
  159. wl_event_source_remove(source);
  160. wl_event_loop_destroy(loop);
  161. }
  162. TEST(event_loop_multiple_same_signals)
  163. {
  164. struct wl_event_loop *loop = wl_event_loop_create();
  165. struct wl_event_source *s1, *s2;
  166. int calls_no = 0;
  167. int i;
  168. s1 = wl_event_loop_add_signal(loop, SIGUSR1,
  169. signal_callback, &calls_no);
  170. assert(s1);
  171. s2 = wl_event_loop_add_signal(loop, SIGUSR1,
  172. signal_callback, &calls_no);
  173. assert(s2);
  174. assert(wl_event_loop_dispatch(loop, 0) == 0);
  175. assert(!calls_no);
  176. /* Try it more times */
  177. for (i = 0; i < 5; ++i) {
  178. calls_no = 0;
  179. assert(kill(getpid(), SIGUSR1) == 0);
  180. /*
  181. * We need a non-zero timeout here to allow the test to pass
  182. * on non-Linux systems (see comment in event_loop_signal).
  183. */
  184. assert(wl_event_loop_dispatch(loop, 1000) == 0);
  185. assert(calls_no == 2);
  186. }
  187. wl_event_source_remove(s1);
  188. /* Try it again with one source */
  189. calls_no = 0;
  190. assert(kill(getpid(), SIGUSR1) == 0);
  191. /*
  192. * We need a non-zero timeout here to allow the test to pass
  193. * on non-Linux systems (see comment in event_loop_signal).
  194. */
  195. assert(wl_event_loop_dispatch(loop, 1000) == 0);
  196. assert(calls_no == 1);
  197. wl_event_source_remove(s2);
  198. wl_event_loop_destroy(loop);
  199. }
  200. #define MSEC_TO_USEC(msec) ((msec) * 1000)
  201. struct timer_update_context {
  202. struct wl_event_source *source1, *source2;
  203. int count;
  204. };
  205. static int
  206. timer_update_callback_1(void *data)
  207. {
  208. struct timer_update_context *context = data;
  209. context->count++;
  210. wl_event_source_timer_update(context->source2, 1000);
  211. return 1;
  212. }
  213. static int
  214. timer_update_callback_2(void *data)
  215. {
  216. struct timer_update_context *context = data;
  217. context->count++;
  218. wl_event_source_timer_update(context->source1, 1000);
  219. return 1;
  220. }
  221. TEST(event_loop_timer_updates)
  222. {
  223. struct wl_event_loop *loop = wl_event_loop_create();
  224. struct timer_update_context context;
  225. struct timeval start_time, end_time, interval;
  226. /* Create two timers that should expire at the same time (after 10ms).
  227. * The first timer to receive its expiry callback updates the other timer
  228. * with a much larger timeout (1s). This highlights a bug where
  229. * wl_event_source_timer_dispatch would block for this larger timeout
  230. * when reading from the timer fd, before calling the second timer's
  231. * callback.
  232. */
  233. context.source1 = wl_event_loop_add_timer(loop, timer_update_callback_1,
  234. &context);
  235. assert(context.source1);
  236. assert(wl_event_source_timer_update(context.source1, 10) == 0);
  237. context.source2 = wl_event_loop_add_timer(loop, timer_update_callback_2,
  238. &context);
  239. assert(context.source2);
  240. assert(wl_event_source_timer_update(context.source2, 10) == 0);
  241. context.count = 0;
  242. /* Since calling the functions between source2's update and
  243. * wl_event_loop_dispatch() takes some time, it may happen
  244. * that only one timer expires until we call epoll_wait.
  245. * This naturally means that only one source is dispatched
  246. * and the test fails. To fix that, sleep 15 ms before
  247. * calling wl_event_loop_dispatch(). That should be enough
  248. * for the second timer to expire.
  249. *
  250. * https://bugs.freedesktop.org/show_bug.cgi?id=80594
  251. */
  252. usleep(MSEC_TO_USEC(15));
  253. gettimeofday(&start_time, NULL);
  254. wl_event_loop_dispatch(loop, 20);
  255. gettimeofday(&end_time, NULL);
  256. assert(context.count == 2);
  257. /* Dispatching the events should not have taken much more than 20ms,
  258. * since this is the timeout passed to wl_event_loop_dispatch. If it
  259. * blocked, then it will have taken over 1s.
  260. * Of course, it could take over 1s anyway on a very slow or heavily
  261. * loaded system, so this test isn't 100% perfect.
  262. */
  263. timersub(&end_time, &start_time, &interval);
  264. assert(interval.tv_sec < 1);
  265. wl_event_source_remove(context.source1);
  266. wl_event_source_remove(context.source2);
  267. wl_event_loop_destroy(loop);
  268. }
  269. struct timer_order_data {
  270. struct wl_event_source *source;
  271. int *last_number;
  272. int number;
  273. };
  274. static int
  275. timer_order_callback(void *data)
  276. {
  277. struct timer_order_data *tod = data;
  278. /* Check that the timers have the correct sequence */
  279. assert(tod->number == *tod->last_number + 2);
  280. *tod->last_number = tod->number;
  281. return 0;
  282. }
  283. TEST(event_loop_timer_order)
  284. {
  285. struct wl_event_loop *loop = wl_event_loop_create();
  286. struct timer_order_data order[20];
  287. int i, j;
  288. int last = -1;
  289. /* Configure a set of timers so that only timers 1, 3, 5, ..., 19
  290. * (in that order) will be dispatched when the event loop is run */
  291. for (i = 0; i < 20; i++) {
  292. order[i].number = i;
  293. order[i].last_number = &last;
  294. order[i].source =
  295. wl_event_loop_add_timer(loop, timer_order_callback,
  296. &order[i]);
  297. assert(order[i].source);
  298. assert(wl_event_source_timer_update(order[i].source, 10) == 0);
  299. }
  300. for (i = 0; i < 20; i++) {
  301. /* Permute the order in which timers are updated, so as to
  302. * more exhaustively test the underlying priority queue code */
  303. j = ((i + 3) * 17) % 20;
  304. assert(wl_event_source_timer_update(order[j].source, j) == 0);
  305. }
  306. for (i = 0; i < 20; i += 2) {
  307. assert(wl_event_source_timer_update(order[i].source, 0) == 0);
  308. }
  309. /* Wait until all timers are due */
  310. usleep(MSEC_TO_USEC(21));
  311. wl_event_loop_dispatch(loop, 0);
  312. assert(last == 19);
  313. for (i = 0; i < 20; i++) {
  314. wl_event_source_remove(order[i].source);
  315. }
  316. wl_event_loop_destroy(loop);
  317. }
  318. struct timer_cancel_context {
  319. struct wl_event_source *timers[4];
  320. struct timer_cancel_context *back_refs[4];
  321. int order[4];
  322. int called, first;
  323. };
  324. static int
  325. timer_cancel_callback(void *data) {
  326. struct timer_cancel_context **context_ref = data;
  327. struct timer_cancel_context *context = *context_ref;
  328. int i = (int)(context_ref - context->back_refs);
  329. context->called++;
  330. context->order[i] = context->called;
  331. if (context->called == 1) {
  332. context->first = i;
  333. /* Removing a timer always prevents its callback from
  334. * being called ... */
  335. wl_event_source_remove(context->timers[(i + 1) % 4]);
  336. /* ... but disarming or rescheduling a timer does not,
  337. * (in the case where the modified timers had already expired
  338. * as of when `wl_event_loop_dispatch` was called.) */
  339. assert(wl_event_source_timer_update(context->timers[(i + 2) % 4],
  340. 0) == 0);
  341. assert(wl_event_source_timer_update(context->timers[(i + 3) % 4],
  342. 2000000000) == 0);
  343. }
  344. return 0;
  345. }
  346. TEST(event_loop_timer_cancellation)
  347. {
  348. struct wl_event_loop *loop = wl_event_loop_create();
  349. struct timer_cancel_context context;
  350. int i;
  351. memset(&context, 0, sizeof(context));
  352. /* Test that when multiple timers are dispatched in a single call
  353. * of `wl_event_loop_dispatch`, that having some timers run code
  354. * to modify the other timers only actually prevents the other timers
  355. * from running their callbacks when the those timers are removed, not
  356. * when they are disarmed or rescheduled. */
  357. for (i = 0; i < 4; i++) {
  358. context.back_refs[i] = &context;
  359. context.timers[i] =
  360. wl_event_loop_add_timer(loop, timer_cancel_callback,
  361. &context.back_refs[i]);
  362. assert(context.timers[i]);
  363. assert(wl_event_source_timer_update(context.timers[i], 1) == 0);
  364. }
  365. usleep(MSEC_TO_USEC(2));
  366. assert(wl_event_loop_dispatch(loop, 0) == 0);
  367. /* Tracking which timer was first makes this test independent of the
  368. * actual timer dispatch order, which is not guaranteed by the docs */
  369. assert(context.order[context.first] == 1);
  370. assert(context.order[(context.first + 1) % 4] == 0);
  371. assert(context.order[(context.first + 2) % 4] > 1);
  372. assert(context.order[(context.first + 3) % 4] > 1);
  373. wl_event_source_remove(context.timers[context.first]);
  374. wl_event_source_remove(context.timers[(context.first + 2) % 4]);
  375. wl_event_source_remove(context.timers[(context.first + 3) % 4]);
  376. wl_event_loop_destroy(loop);
  377. }
  378. struct event_loop_destroy_listener {
  379. struct wl_listener listener;
  380. int done;
  381. };
  382. static void
  383. event_loop_destroy_notify(struct wl_listener *l, void *data)
  384. {
  385. struct event_loop_destroy_listener *listener =
  386. wl_container_of(l, listener, listener);
  387. listener->done = 1;
  388. }
  389. TEST(event_loop_destroy)
  390. {
  391. struct wl_event_loop *loop;
  392. struct wl_display * display;
  393. struct event_loop_destroy_listener a, b;
  394. loop = wl_event_loop_create();
  395. assert(loop);
  396. a.listener.notify = &event_loop_destroy_notify;
  397. a.done = 0;
  398. wl_event_loop_add_destroy_listener(loop, &a.listener);
  399. assert(wl_event_loop_get_destroy_listener(loop,
  400. event_loop_destroy_notify) == &a.listener);
  401. b.listener.notify = &event_loop_destroy_notify;
  402. b.done = 0;
  403. wl_event_loop_add_destroy_listener(loop, &b.listener);
  404. wl_list_remove(&a.listener.link);
  405. wl_event_loop_destroy(loop);
  406. assert(!a.done);
  407. assert(b.done);
  408. /* Test to make sure it gets fired on display destruction */
  409. display = wl_display_create();
  410. assert(display);
  411. loop = wl_display_get_event_loop(display);
  412. assert(loop);
  413. a.done = 0;
  414. wl_event_loop_add_destroy_listener(loop, &a.listener);
  415. wl_display_destroy(display);
  416. assert(a.done);
  417. }