commit d362fb231310a52a79c8b9f72165a708bfd8aa44 Author: Dylan Yudaken Date: Mon Jan 30 01:49:57 2023 -0800 multicqes_drain: make trigger event wait before reading trigger_event is used to generate CQEs on the poll requests. However there is a race if that poll request is running asynchronously, where the read_pipe will complete before the poll is run, and the poll result will be that there is no data ready. Instead sleep and force an io_uring_get_events in order to give the poll a chance to run before reading from the pipe. Signed-off-by: Dylan Yudaken diff --git a/test/multicqes_drain.c b/test/multicqes_drain.c index 3755beec42c7..6c4d5f2ba887 100644 --- a/test/multicqes_drain.c +++ b/test/multicqes_drain.c @@ -71,13 +71,15 @@ static void read_pipe(int pipe) perror("read"); } -static int trigger_event(int p[]) +static int trigger_event(struct io_uring *ring, int p[]) { int ret; if ((ret = write_pipe(p[1], "foo")) != 3) { fprintf(stderr, "bad write return %d\n", ret); return 1; } + usleep(1000); + io_uring_get_events(ring); read_pipe(p[0]); return 0; } @@ -236,10 +238,8 @@ static int test_generic_drain(struct io_uring *ring) if (si[i].op != multi && si[i].op != single) continue; - if (trigger_event(pipes[i])) + if (trigger_event(ring, pipes[i])) goto err; - - io_uring_get_events(ring); } sleep(1); i = 0; @@ -317,13 +317,11 @@ static int test_simple_drain(struct io_uring *ring) } for (i = 0; i < 2; i++) { - if (trigger_event(pipe1)) + if (trigger_event(ring, pipe1)) goto err; - io_uring_get_events(ring); } - if (trigger_event(pipe2)) - goto err; - io_uring_get_events(ring); + if (trigger_event(ring, pipe2)) + goto err; for (i = 0; i < 2; i++) { sqe[i] = io_uring_get_sqe(ring);