diff options
Diffstat (limited to 'tests/common/test_loop.c')
| -rw-r--r-- | tests/common/test_loop.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/tests/common/test_loop.c b/tests/common/test_loop.c index bdc33b7..a77b6a5 100644 --- a/tests/common/test_loop.c +++ b/tests/common/test_loop.c @@ -237,6 +237,47 @@ static void test_signals(void) sigaction(SIGUSR2, &dfl, NULL); } +struct order_log { + char order[8]; + int count; +}; + +static void order_signal(void *ud, int signo) +{ + (void)signo; + struct order_log *log = ud; + log->order[log->count++] = 's'; +} + +static void order_fd(void *ud, int fd, short revents) +{ + (void)revents; + struct order_log *log = ud; + char b; + assert(read(fd, &b, 1) == 1); + log->order[log->count++] = 'f'; +} + +/* A signal runs after the descriptors of its step, so a child's last output + * is read before its exit is handled. */ +static void test_signal_order(void) +{ + yasl_loop *l = yasl_loop_create(); + assert(l); + struct order_log log = {0}; + assert(yasl_loop_watch_signals(l, (const int[]){SIGUSR1}, 1, order_signal, &log) == 0); + int p[2]; + assert(pipe(p) == 0); + assert(yasl_loop_add_fd(l, p[0], POLLIN, order_fd, &log) > 0); + assert(write(p[1], "x", 1) == 1); + raise(SIGUSR1); + assert(yasl_loop_step(l, 0) >= 1); + assert(log.count == 2 && memcmp(log.order, "fs", 2) == 0); + close(p[0]); + close(p[1]); + assert(yasl_loop_destroy(l) == 0); +} + struct fd_log { int calls; short revents; @@ -364,7 +405,8 @@ static void test_interrupted_wait(void) assert(yasl_loop_step(l, 100) == 0); uint64_t elapsed_ms = (yasl_time_ns() - start) / 1000000u; pthread_join(t, NULL); - assert(elapsed_ms >= 90 && elapsed_ms < 140); + /* Lateness under load is not the bug; an early return is. */ + assert(elapsed_ms >= 90 && elapsed_ms < 1000); assert(yasl_loop_destroy(l) == 0); sigaction(SIGUSR2, &old, NULL); } @@ -376,6 +418,7 @@ int main(void) test_post_order(); test_cross_thread(); test_signals(); + test_signal_order(); test_fds(); test_reentry_and_quit(); test_interrupted_wait(); |
