Codebase list wayland / b6ed8e8
tests: Fix race condition in send overflow test This change ensures that the compositor process is not able to respond to any of the noop requests sent by the client process, by using the test compositor's `stop_display` mechanism to coordinate when the compositor should stop processing messages. (Before this change, it was possible that one of the calls of wl_event_loop_dispatch in the compositor process could respond to all the client's noop requests before returning.) Signed-off-by: Manuel Stoeckl <code@mstoeckl.com> Manuel Stoeckl authored 4 years ago Héctor Orón Martínez committed 4 years ago
3 changed file(s) with 34 addition(s) and 15 deletion(s). Raw diff Collapse all Expand all
14301430 int *pipes = data;
14311431 char tmp = '\0';
14321432
1433 /* Request to break out of 'display_run' in the main process */
1434 assert(stop_display(c, 1) >= 0);
1435
14331436 /* On Linux, the Unix socket default buffer size is <=256KB, and
14341437 * each noop request requires 8 bytes; the buffer should thus
14351438 * overflow within about 32K /unhandled/ iterations */
14561459 struct display *d;
14571460 char tmp;
14581461 int rpipe[2];
1459 int i;
1462 ssize_t ret;
14601463
14611464 assert(pipe(rpipe) != -1);
14621465
14681471 * interrupted if the client dies */
14691472 close(rpipe[1]);
14701473
1471 /* At least 2 loops of this are needed to respond for the client to
1472 * set up the test interface */
1473 for (i = 0; i < 5; i++) {
1474 wl_display_flush_clients(d->wl_display);
1475 wl_event_loop_dispatch(wl_display_get_event_loop(d->wl_display), -1);
1476 }
1477
1478 /* Wait until all noop requests have been sent, or until client
1479 * process aborts */
1480 (void)read(rpipe[0], &tmp, sizeof(tmp));
1474 /* Run the display until the client sends a `stop_display`, then
1475 * send a resume message but don't actually look at new messages */
1476 display_run(d);
1477 display_post_resume_events(d);
1478 wl_display_flush_clients(d->wl_display);
1479
1480 /* Wait until all noop requests have been sent (read returns 1), or
1481 * until client process aborts (read returns 0) */
1482 do {
1483 ret = read(rpipe[0], &tmp, sizeof(tmp));
1484 } while (ret == -1 && errno == EINTR);
1485 assert(ret != -1);
14811486 close(rpipe[0]);
14821487
14831488 /* For a clean shutdown */
365365 }
366366
367367 void
368 display_resume(struct display *d)
368 display_post_resume_events(struct display *d)
369369 {
370370 struct wfr *wfr, *next;
371371
379379
380380 assert(wl_list_empty(&d->waiting_for_resume));
381381 d->wfr_num = 0;
382
382 }
383
384 void
385 display_resume(struct display *d)
386 {
387 display_post_resume_events(d);
383388 wl_display_run(d->wl_display);
384389 }
385390
8989 void display_destroy(struct display *d);
9090 void display_run(struct display *d);
9191
92 /* This function posts the display_resumed event to all waiting clients,
93 * so that after flushing events the clients will stop waiting and continue.
94 *
95 * (Calling `display_run` after this function will resume the display loop.)
96 */
97 void display_post_resume_events(struct display *d);
9298 /* After n clients called stop_display(..., n), the display
9399 * is stopped and can process the code after display_run().
94 * This function rerun the display again and send display_resumed
95 * event to waiting clients, so the clients will stop waiting and continue */
100 *
101 * This function posts the display_resumed event to the waiting
102 * clients, so that the clients will stop waiting and continue;
103 * it then reruns the display. */
96104 void display_resume(struct display *d);
105
97106
98107 struct client_info *client_create_with_name(struct display *d,
99108 void (*client_main)(void *data),