Enforce absolute Wasm invocation deadlines

This commit is contained in:
udo
2026-07-19 00:44:18 +00:00
parent fd6d472187
commit a7576f3db7
10 changed files with 591 additions and 92 deletions
+43
View File
@@ -1396,6 +1396,48 @@ std::map<pid_t, Worker> workers;
#include <sys/resource.h>
#include <sys/prctl.h>
// The process-wide reaper may run on a runtime thread while a request thread
// synchronously owns a child. Preserve unknown statuses until that owner takes
// them instead of forcing it to guess success after waitpid reports ECHILD.
static const size_t child_exit_status_capacity = 256;
static volatile sig_atomic_t child_exit_status_cursor = 0;
static volatile sig_atomic_t child_exit_status_pids[child_exit_status_capacity] = {0};
static volatile sig_atomic_t child_exit_status_values[child_exit_status_capacity] = {0};
static volatile sig_atomic_t child_exit_status_sequences[child_exit_status_capacity] = {0};
static void child_exit_status_publish(pid_t pid, int status)
{
sig_atomic_t cursor = __atomic_fetch_add(&child_exit_status_cursor, 1, __ATOMIC_RELAXED);
size_t slot = (size_t)(unsigned int)cursor % child_exit_status_capacity;
__atomic_store_n(&child_exit_status_pids[slot], 0, __ATOMIC_RELEASE);
__atomic_store_n(&child_exit_status_values[slot], (sig_atomic_t)status, __ATOMIC_RELAXED);
__atomic_store_n(&child_exit_status_sequences[slot], cursor + 1, __ATOMIC_RELAXED);
__atomic_store_n(&child_exit_status_pids[slot], (sig_atomic_t)pid, __ATOMIC_RELEASE);
}
unsigned int child_exit_status_snapshot()
{
return((unsigned int)__atomic_load_n(&child_exit_status_cursor, __ATOMIC_ACQUIRE));
}
bool child_exit_status_take(pid_t pid, int& status, unsigned int since)
{
for(size_t slot = 0; slot < child_exit_status_capacity; slot++)
{
unsigned int sequence = (unsigned int)__atomic_load_n(&child_exit_status_sequences[slot], __ATOMIC_ACQUIRE);
unsigned int distance = sequence - since;
if(sequence == 0 || distance == 0 || distance >= 0x80000000u)
continue;
sig_atomic_t expected = (sig_atomic_t)pid;
if(__atomic_compare_exchange_n(&child_exit_status_pids[slot], &expected, 0, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED))
{
status = (int)__atomic_load_n(&child_exit_status_values[slot], __ATOMIC_RELAXED);
return(true);
}
}
return(false);
}
pid_t spawn_subprocess(std::function<void()> exec_after_spawn)
{
parent_pid = getpid();
@@ -1648,6 +1690,7 @@ void on_child_exit(int sig)
}
else
{
child_exit_status_publish(pid, status);
printf("(P) task child reaped (PID:%i)\n", pid);
}
}
+2
View File
@@ -21,6 +21,8 @@ s32 usleep(u32 usec);
#else
#include <sys/file.h>
#include <signal.h>
unsigned int child_exit_status_snapshot();
bool child_exit_status_take(pid_t pid, int& status, unsigned int since);
#endif
#include <ctime>
#include <sstream>