Code cleanup, make process termination more robust and add debugging output to tuxreaperd

This commit is contained in:
mrkmntal 2026-08-29 13:08:32 -04:00
commit 2f75d914ab
2 changed files with 35 additions and 19 deletions

View file

@ -196,11 +196,10 @@ static inline long sys_close(int fd) {
static inline long sys_clock_gettime(int clk_id, struct timespec *tp) {
long ret;
register long r10 __asm__("r10") = 0;
__asm__ volatile (
"syscall"
: "=a"(ret)
: "a"(228), "D"((long)clk_id), "S"(tp), "r"(r10)
: "a"(228), "D"((long)clk_id), "S"(tp)
: "rcx", "r11", "memory"
);
return ret;
@ -592,6 +591,7 @@ static const char * const apache_exes[] = {
#define DESCENDANT_TIMEOUT_SECONDS 60
#define BROADCAST_SCAN_DELAY_US 100000
#define DESCENDANT_POLL_INTERVAL_US 50000
#define AT_FDCWD -100
#define O_RDONLY 0
@ -793,7 +793,7 @@ static volatile int g_pending_signals = 0;
static void proxy_sig_handler(int sig) {
if (sig >= 1 && sig <= 31) {
g_pending_signals |= (1 << (sig - 1));
g_pending_signals |= (1U << (sig - 1));
}
}
@ -820,7 +820,7 @@ static void handle_pending_signals(void) {
g_pending_signals = 0;
for (int sig = 1; sig <= 31; sig++) {
if (!(pending & (1 << (sig - 1)))) continue;
if (!(pending & (1U << (sig - 1)))) continue;
#ifdef TUXREAPERD_DEBUG
debug_write("[tuxreaperd] handling pending signal ");
debug_write_int(sig);
@ -909,6 +909,7 @@ int main(int argc, char **argv, char **envp) {
debug_msg("main child exited, waiting up to 60s for descendants");
}
drain_zombies();
int descendants = count_descendants();
#ifdef TUXREAPERD_DEBUG
debug_write("[tuxreaperd] descendants=");
@ -923,13 +924,20 @@ int main(int argc, char **argv, char **envp) {
debug_msg("descendant timeout reached, exiting");
break;
}
}
/* Poll briefly so the 60-second deadline can tick even if no
SIGCHLD or external signal arrives. handle_pending_signals()
catches any signal that was delivered while we slept. */
sleep_us(DESCENDANT_POLL_INTERVAL_US);
handle_pending_signals();
} else {
/* Workload active: block atomically with zero CPU wakeups until a
signal arrives. */
sys_rt_sigsuspend(&old_mask, sizeof(old_mask));
drain_zombies();
handle_pending_signals();
}
}
drain_zombies();

View file

@ -46,6 +46,10 @@ static const char * const apache_exes[] = {
processes that spawned just after the first scan. */
#define BROADCAST_SCAN_DELAY_US 100000
/* How often to poll while waiting for descendants after the main child exits.
Short enough to react quickly, long enough to avoid burning CPU. */
#define DESCENDANT_POLL_INTERVAL_US 50000
static volatile pid_t g_main_child = 0;
static volatile sig_atomic_t g_child_exited = 0;
static volatile int g_main_status = 0;
@ -231,8 +235,6 @@ int main(int argc, char *argv[]) {
long long child_exit_time_ms = 0;
while (1) {
int descendants = 0;
if (g_child_exited) {
long long now = monotonic_ms();
if (child_exit_time_ms == 0) {
@ -241,7 +243,8 @@ int main(int argc, char *argv[]) {
DESCENDANT_TIMEOUT_SECONDS);
}
descendants = count_descendants();
drain_zombies();
int descendants = count_descendants();
debug("[tuxreaperd] descendants=%d", descendants);
if (descendants == 0) {
@ -253,15 +256,20 @@ int main(int argc, char *argv[]) {
debug("[tuxreaperd] descendant timeout reached, exiting");
break;
}
}
// Wait for a signal. When one arrives, reap and handle it, then loop
// back to re-evaluate descendants and timeouts.
// Poll briefly so the 60-second deadline can tick even if no
// SIGCHLD or external signal arrives. handle_pending_signals()
// catches any signal that was delivered while we slept.
usleep(DESCENDANT_POLL_INTERVAL_US);
handle_pending_signals();
} else {
// Workload active: block atomically with zero CPU wakeups until a
// signal arrives.
sigsuspend(&old_mask);
drain_zombies();
handle_pending_signals();
}
}
// Final sweep of any remaining lingering zombies.
drain_zombies();