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:
parent
dbfea28313
commit
020cabc61e
|
@ -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()
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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; \
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue