diff options
| author | eunhhu <[email protected]> | 2026-09-29 18:04:24 +0100 |
|---|---|---|
| committer | eunhhu <[email protected]> | 2026-09-29 18:04:43 +0100 |
| commit | 8fe9ce66573be53ff56fe2a8afc693dabeae9585 (patch) | |
| tree | b556788225296e84a6a5082c2927295588a6955a /tests/clock-back.c | |
| parent | e710b93588782135365f01bb8351edb3bf4f95ac (diff) | |
| download | pure-8fe9ce66573be53ff56fe2a8afc693dabeae9585.tar.gz pure-8fe9ce66573be53ff56fe2a8afc693dabeae9585.zip | |
Tick a stateless app's timers, and wait for them on the monotonic clock
run_timers ticked nothing in an app without states, taking a timer to
be able to change nothing else; but a tick may send, and the outbox is
the app's state (the host gives such an app an owner for it). A timer
that only sends never ticked (review 004, F4). Now an app ticks when it
has states or outputs; one with neither runs on every connection thread
and has nothing a tick could do.
When a timer is due was reckoned on the wall clock: set back, a timer
waited for the time it had reached again (review 004, an earlier P2).
The next tick is now reckoned on the monotonic clock; events still see
the wall clock (now).
check.py's server_timers runs the review's heartbeat (a timer, an
output, no state) and sees it tick, then again with the wall clock set
back an hour 0.2 s in (build/clock-back.so, an LD_PRELOAD of
clock_gettime): 29 ticks in 0.6 s, where the server before this stops at
9.
Diffstat (limited to 'tests/clock-back.c')
| -rw-r--r-- | tests/clock-back.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/tests/clock-back.c b/tests/clock-back.c new file mode 100644 index 0000000..50870ca --- /dev/null +++ b/tests/clock-back.c @@ -0,0 +1,23 @@ +#define _GNU_SOURCE +/* LD_PRELOAD: the wall clock (CLOCK_REALTIME) set back an hour from + * CLOCK_BACK_MS milliseconds (200 unless given) after the process first + * asks for it, as a person or NTP may set it. A program's timers must go on + * all the same: they wait on the monotonic clock (tests/check.py). */ +#include <dlfcn.h> +#include <stdlib.h> +#include <time.h> + +int clock_gettime(clockid_t id, struct timespec *t) { + static int (*real)(clockid_t, struct timespec *); + static long long began = -1; + if (!real) *(void **)&real = dlsym(RTLD_NEXT, "clock_gettime"); /* as POSIX's dlsym example does */ + int result = real(id, t); + if (result || id != CLOCK_REALTIME) return result; + struct timespec now; + real(CLOCK_MONOTONIC, &now); + long long ms = (long long)now.tv_sec * 1000 + now.tv_nsec / 1000000; + if (began < 0) began = ms; + const char *after = getenv("CLOCK_BACK_MS"); + if (ms - began >= (after ? atoll(after) : 200)) t->tv_sec -= 3600; + return result; +} |
