Fixed build issues. Now to fix runtime issues: we'll have to use reentrancy everywhere, because rcx is clobbered by GetMessage().

This commit is contained in:
Pietro Gagliardi 2019-05-03 10:32:31 -04:00
parent dbfea28313
commit 020cabc61e
5 changed files with 44 additions and 34 deletions

View File

@ -52,7 +52,7 @@ static void queued(void *data)
int *flag = (int *) data; int *flag = (int *) data;
*flag = 1; *flag = 1;
uiQuit(); // uiQuit();
} }
// TODO the timing for this is strange because it is the first to call uiMain() // TODO the timing for this is strange because it is the first to call uiMain()

View File

@ -1,7 +1,7 @@
// 10 april 2019 // 10 april 2019
#include "test.h" #include "test.h"
void timeoutMain(testingT *t, void *data) void timeoutMain(void *data)
{ {
uiMain(); uiMain();
} }

View File

@ -4,7 +4,7 @@
#include "timer.h" #include "timer.h"
// main.c // main.c
extern void timeoutMain(testingT *t, void *data); extern void timeoutMain(void *data);
#define timeout_uiMain(t, d) { \ #define timeout_uiMain(t, d) { \
timerSysError err; \ timerSysError err; \
int timedOut; \ int timedOut; \

View File

@ -11,7 +11,6 @@
#include <windows.h> #include <windows.h>
#include <process.h> #include <process.h>
#include <errno.h> #include <errno.h>
#include <setjmp.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>

View File

@ -9,6 +9,11 @@
#define _WIN32_IE 0x0700 #define _WIN32_IE 0x0700
#define NTDDI_VERSION 0x06000000 #define NTDDI_VERSION 0x06000000
#include <windows.h> #include <windows.h>
#include <errno.h>
#include <process.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include "timer.h" #include "timer.h"
static HRESULT lastErrorCodeToHRESULT(DWORD lastError) static HRESULT lastErrorCodeToHRESULT(DWORD lastError)
@ -228,7 +233,6 @@ struct timeoutParams {
static void timerprivCall onTimeout(struct timeoutParams *p) static void timerprivCall onTimeout(struct timeoutParams *p)
{ {
longjmp(p->retpos, 1); longjmp(p->retpos, 1);
// TODO flag this code should not be reached
} }
static HRESULT setupNonReentrance(struct timeoutParams *p) static HRESULT setupNonReentrance(struct timeoutParams *p)
@ -253,7 +257,6 @@ static void timerprivCall onTimeout(void)
p = (struct timeoutParams *) TlsGetValue(timeoutParamsSlot); p = (struct timeoutParams *) TlsGetValue(timeoutParamsSlot);
longjmp(p->retpos, 1); longjmp(p->retpos, 1);
// TODO flag this code should not be reached
} }
static BOOL CALLBACK timeoutParamsSlotInit(PINIT_ONCE once, PVOID param, PVOID *ctx) static BOOL CALLBACK timeoutParamsSlotInit(PINIT_ONCE once, PVOID param, PVOID *ctx)
@ -356,17 +359,20 @@ static unsigned __stdcall timerThreadProc(void *data)
timerSysError timerRunWithTimeout(timerDuration d, void (*f)(void *data), void *data, int *timedOut) timerSysError timerRunWithTimeout(timerDuration d, void (*f)(void *data), void *data, int *timedOut)
{ {
volatile struct timeoutParams p; struct timeoutParams *p;
MSG msg; MSG msg;
volatile uintptr_t timerThreadValue = 0;
volatile HANDLE timerThread = NULL; volatile HANDLE timerThread = NULL;
LARGE_INTEGER duration; LARGE_INTEGER duration;
HRESULT hr; HRESULT hr;
*timedOut = 0; *timedOut = 0;
ZeroMemory(&p, sizeof (struct timeoutParams)); // we use a pointer to heap memory here to avoid volatile kludges
p = (struct timeoutParams *) malloc(sizeof (struct timeoutParams));
if (p == NULL)
return (timerSysError) E_OUTOFMEMORY;
ZeroMemory(p, sizeof (struct timeoutParams));
hr = setupNonReentrance(&p); hr = setupNonReentrance(p);
if (hr != S_OK) if (hr != S_OK)
goto out; goto out;
@ -374,27 +380,29 @@ timerSysError timerRunWithTimeout(timerDuration d, void (*f)(void *data), void *
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
hr = hrDuplicateHandle(GetCurrentProcess(), GetCurrentThread(), hr = hrDuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
GetCurrentProcess(), &(p.targetThread), GetCurrentProcess(), &(p->targetThread),
0, FALSE, DUPLICATE_SAME_ACCESS); 0, FALSE, DUPLICATE_SAME_ACCESS);
if (hr != S_OK) { if (hr != S_OK) {
p.targetThread = NULL; p->targetThread = NULL;
goto out; goto out;
} }
p.targetThreadID = GetCurrentThreadId(); p->targetThreadID = GetCurrentThreadId();
hr = hrCreateWaitableTimerW(NULL, TRUE, NULL, &(p.timer)); hr = hrCreateWaitableTimerW(NULL, TRUE, NULL, &(p->timer));
if (hr != S_OK) { if (hr != S_OK) {
p.timer = NULL; p->timer = NULL;
goto out; goto out;
} }
hr = hrCreateEventW(NULL, TRUE, FALSE, NULL, &(p.finished)); hr = hrCreateEventW(NULL, TRUE, FALSE, NULL, &(p->finished));
if (hr != S_OK) { if (hr != S_OK) {
p.finished = NULL; p->finished = NULL;
goto out; goto out;
} }
if (setjmp(p.retpos) == 0) { if (setjmp(p->retpos) == 0) {
uintptr_t timerThreadValue = 0;
hr = hr_beginthreadex(NULL, 0, timerThreadProc, p, 0, NULL, &timerThreadValue); hr = hr_beginthreadex(NULL, 0, timerThreadProc, p, 0, NULL, &timerThreadValue);
if (hr != S_OK) { if (hr != S_OK) {
timerThread = NULL; timerThread = NULL;
@ -404,14 +412,14 @@ timerSysError timerRunWithTimeout(timerDuration d, void (*f)(void *data), void *
duration.QuadPart = d / 100; duration.QuadPart = d / 100;
duration.QuadPart = -duration.QuadPart; duration.QuadPart = -duration.QuadPart;
hr = hrSetWaitableTimer(p.timer, &duration, 0, NULL, NULL, FALSE); hr = hrSetWaitableTimer(p->timer, &duration, 0, NULL, NULL, FALSE);
if (hr != S_OK) if (hr != S_OK)
goto out; goto out;
(*f)(t, data); (*f)(data);
*timedOut = 0; *timedOut = 0;
} else if (p.hr != S_OK) { } else if (p->hr != S_OK) {
hr = p.hr; hr = p->hr;
goto out; goto out;
} else } else
*timedOut = 1; *timedOut = 1;
@ -419,22 +427,25 @@ timerSysError timerRunWithTimeout(timerDuration d, void (*f)(void *data), void *
out: out:
if (timerThread != NULL) { if (timerThread != NULL) {
HRESULT xhr; // don't overwrite hr below
// if either of these two fail, we cannot continue because the timer thread might interrupt us later, screwing everything up // if either of these two fail, we cannot continue because the timer thread might interrupt us later, screwing everything up
hr = hrSetEvent(p.finished); xhr = hrSetEvent(p->finished);
if (hr != S_OK) if (xhr != S_OK)
criticalCallFailed("SetEvent()", hr); criticalCallFailed("SetEvent()", xhr);
hr = hrWaitForSingleObject(timerThread, INFINITE); xhr = hrWaitForSingleObject(timerThread, INFINITE);
if (hr != S_OK) if (xhr != S_OK)
criticalCallFailed("WaitForSingleObject()", hr); criticalCallFailed("WaitForSingleObject()", xhr);
CloseHandle(timerThread); CloseHandle(timerThread);
} }
if (p.finished != NULL) if (p->finished != NULL)
CloseHandle(p.finished); CloseHandle(p->finished);
if (p.timer != NULL) if (p->timer != NULL)
CloseHandle(p.timer); CloseHandle(p->timer);
if (p.targetThread != NULL) if (p->targetThread != NULL)
CloseHandle(p.targetThread); CloseHandle(p->targetThread);
teardownNonReentrance(); teardownNonReentrance();
free(p);
return (timerSysError) hr; return (timerSysError) hr;
} }