Changed the windows worker waiting code as well

This commit is contained in:
Snaipe 2015-09-17 04:35:47 +02:00
parent 75b9e7dae2
commit 0850658785
2 changed files with 83 additions and 36 deletions

View file

@ -48,8 +48,47 @@
# define WRITE_PROCESS_(Proc, What, Size) \
WriteProcessMemory(Proc, &What, &What, Size, NULL);
static int get_win_status(HANDLE handle) {
DWORD exit_code;
GetExitCodeProcess(handle, &exit_code);
unsigned int sig = 0;
switch (exit_code) {
case STATUS_FLOAT_DENORMAL_OPERAND:
case STATUS_FLOAT_DIVIDE_BY_ZERO:
case STATUS_FLOAT_INEXACT_RESULT:
case STATUS_FLOAT_INVALID_OPERATION:
case STATUS_FLOAT_OVERFLOW:
case STATUS_FLOAT_STACK_CHECK:
case STATUS_FLOAT_UNDERFLOW:
case STATUS_INTEGER_DIVIDE_BY_ZERO:
case STATUS_INTEGER_OVERFLOW: sig = SIGFPE; break;
case STATUS_ILLEGAL_INSTRUCTION:
case STATUS_PRIVILEGED_INSTRUCTION:
case STATUS_NONCONTINUABLE_EXCEPTION: sig = SIGILL; break;
case CR_EXCEPTION_TIMEOUT: sig = SIGPROF; break;
case STATUS_ACCESS_VIOLATION:
case STATUS_DATATYPE_MISALIGNMENT:
case STATUS_ARRAY_BOUNDS_EXCEEDED:
case STATUS_GUARD_PAGE_VIOLATION:
case STATUS_IN_PAGE_ERROR:
case STATUS_NO_MEMORY:
case STATUS_INVALID_DISPOSITION:
case STATUS_STACK_OVERFLOW: sig = SIGSEGV; break;
case STATUS_CONTROL_C_EXIT: sig = SIGINT; break;
default: break;
}
return sig ? sig : exit_code << 8;
}
#endif
struct worker_context g_worker_context = {.test = NULL};
#ifdef VANILLA_WIN32
@ -95,6 +134,37 @@ static void handle_sigchld(int sig) {
}
#endif
#ifdef VANILLA_WIN32
struct wait_context {
HANDLE wait_handle;
HANDLE proc_handle;
};
static void handle_child_terminated(PVOID lpParameter,
BOOLEAN TimerOrWaitFired) {
assert(!TimerOrWaitFired);
struct wait_context *wctx = lpParameter;
int status = get_win_status(wctx->proc_handle);
int kind = WORKER_TERMINATED;
struct worker_status ws = {
(s_proc_handle) { wctx->proc_handle }, get_status(status)
};
char buf[sizeof (int) + sizeof (struct worker_status)];
memcpy(buf, &kind, sizeof (kind));
memcpy(buf + sizeof (kind), &ws, sizeof (ws));
WriteFile(g_worker_pipe->fhs[1], buf, sizeof (buf), NULL, NULL);
HANDLE whandle = wctx->wait_handle;
free(lpParameter);
UnregisterWaitEx(whandle, NULL);
}
#endif
int resume_child(void) {
#ifdef VANILLA_WIN32
HANDLE sharedMem = OpenFileMapping(
@ -206,6 +276,17 @@ s_proc_handle *fork_process() {
UnmapViewOfFile(ctx);
CloseHandle(sharedMem);
struct wait_context *wctx = malloc(sizeof (struct wait_context));
*wctx = {}
RegisterWaitForSingleObject(
&wctx->wait_handle,
info.hProcess,
handle_child_terminated,
wctx,
INFINITE,
WT_EXECUTELONGFUNCTION | WT_EXECUTEONLYONCE);
s_proc_handle *handle = smalloc(sizeof (s_proc_handle));
*handle = (s_proc_handle) { info.hProcess };
return handle;
@ -225,43 +306,8 @@ s_proc_handle *fork_process() {
void wait_process(s_proc_handle *handle, int *status) {
#ifdef VANILLA_WIN32
WaitForSingleObject(handle->handle, INFINITE);
DWORD exit_code;
GetExitCodeProcess(handle->handle, &exit_code);
*status = get_win_status(handle->handle);
CloseHandle(handle->handle);
unsigned int sig = 0;
switch (exit_code) {
case STATUS_FLOAT_DENORMAL_OPERAND:
case STATUS_FLOAT_DIVIDE_BY_ZERO:
case STATUS_FLOAT_INEXACT_RESULT:
case STATUS_FLOAT_INVALID_OPERATION:
case STATUS_FLOAT_OVERFLOW:
case STATUS_FLOAT_STACK_CHECK:
case STATUS_FLOAT_UNDERFLOW:
case STATUS_INTEGER_DIVIDE_BY_ZERO:
case STATUS_INTEGER_OVERFLOW: sig = SIGFPE; break;
case STATUS_ILLEGAL_INSTRUCTION:
case STATUS_PRIVILEGED_INSTRUCTION:
case STATUS_NONCONTINUABLE_EXCEPTION: sig = SIGILL; break;
case CR_EXCEPTION_TIMEOUT: sig = SIGPROF; break;
case STATUS_ACCESS_VIOLATION:
case STATUS_DATATYPE_MISALIGNMENT:
case STATUS_ARRAY_BOUNDS_EXCEEDED:
case STATUS_GUARD_PAGE_VIOLATION:
case STATUS_IN_PAGE_ERROR:
case STATUS_NO_MEMORY:
case STATUS_INVALID_DISPOSITION:
case STATUS_STACK_OVERFLOW: sig = SIGSEGV; break;
case STATUS_CONTROL_C_EXIT: sig = SIGINT; break;
default: break;
}
*status = sig ? sig : exit_code << 8;
#else
waitpid(handle->pid, status, 0);
#endif

View file

@ -26,6 +26,7 @@
# include "criterion/types.h"
# include "compat/posix.h"
# include "internal.h"
struct proc_handle {
#ifdef VANILLA_WIN32