summaryrefslogtreecommitdiff
path: root/tests/common/test_loop.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/common/test_loop.c')
-rw-r--r--tests/common/test_loop.c45
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();