Enforce absolute Wasm invocation deadlines
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user