Settled the PostThreadMessage() TODOs in the Windows testing code.

This commit is contained in:
Pietro Gagliardi 2019-04-30 02:31:08 -04:00
parent 848c3813ee
commit 965dec0157
1 changed files with 21 additions and 3 deletions

View File

@ -72,6 +72,17 @@ static HRESULT WINAPI hrSetThreadContext(HANDLE thread, CONST CONTEXT *ctx)
return S_OK; return S_OK;
} }
static HRESULT WINAPI hrPostThreadMessageW(DWORD threadID, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
BOOL ret;
SetLastError(0);
ret = PostThreadMessageW(threadID, uMsg, wParam, lParam);
if (ret == 0)
return lastErrorToHRESULT();
return S_OK;
}
static HRESULT WINAPI hrResumeThread(HANDLE thread) static HRESULT WINAPI hrResumeThread(HANDLE thread)
{ {
DWORD ret; DWORD ret;
@ -215,6 +226,7 @@ static void onTimeout(void)
static HANDLE timeout_timer; static HANDLE timeout_timer;
static HANDLE timeout_finished; static HANDLE timeout_finished;
static HANDLE timeout_targetThread; static HANDLE timeout_targetThread;
static DWORD timeout_targetThreadID;
static HRESULT timeout_hr; static HRESULT timeout_hr;
static void setContextForGet(CONTEXT *ctx) static void setContextForGet(CONTEXT *ctx)
@ -272,9 +284,10 @@ static unsigned __stdcall timerThreadProc(void *data)
if (hr != S_OK) if (hr != S_OK)
testingprivInternalError("error calling SetThreadContext() after timeout: 0x%08I32X", hr); testingprivInternalError("error calling SetThreadContext() after timeout: 0x%08I32X", hr);
// and force the thread to return from GetMessage(), if we are indeed in that // and force the thread to return from GetMessage(), if we are indeed in that
// TODO decide whether to check errors // and yes, this is the way to do it (https://devblogs.microsoft.com/oldnewthing/?p=16553, https://devblogs.microsoft.com/oldnewthing/20050405-46/?p=35973, https://devblogs.microsoft.com/oldnewthing/20080528-00/?p=22163)
// TODO either way, check errors in GetThreadId() hr = hrPostThreadMessageW(timeout_targetThreadID, WM_NULL, 0, 0);
PostThreadMessage(GetThreadId(timeout_targetThread), WM_NULL, 0, 0); if (hr != S_OK)
testingprivInternalError("error calling PostThreadMessage() after timeout: 0x%08I32X", hr);
hr = hrResumeThread(timeout_targetThread); hr = hrResumeThread(timeout_targetThread);
if (hr != S_OK) if (hr != S_OK)
testingprivInternalError("error calling ResumeThread() after timeout: 0x%08I32X", hr); testingprivInternalError("error calling ResumeThread() after timeout: 0x%08I32X", hr);
@ -284,6 +297,7 @@ static unsigned __stdcall timerThreadProc(void *data)
void testingprivRunWithTimeout(testingT *t, const char *file, long line, int64_t timeout, void (*f)(testingT *t, void *data), void *data, const char *comment, int failNowOnError) void testingprivRunWithTimeout(testingT *t, const char *file, long line, int64_t timeout, void (*f)(testingT *t, void *data), void *data, const char *comment, int failNowOnError)
{ {
char *timeoutstr; char *timeoutstr;
MSG msg;
int closeTargetThread = 0; int closeTargetThread = 0;
uintptr_t timerThread = 0; uintptr_t timerThread = 0;
LARGE_INTEGER timer; LARGE_INTEGER timer;
@ -292,6 +306,9 @@ void testingprivRunWithTimeout(testingT *t, const char *file, long line, int64_t
timeoutstr = testingNsecString(timeout); timeoutstr = testingNsecString(timeout);
// to ensure that the PostThreadMessage() above will not fail because the thread doesn't have a message queue
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
hr = hrDuplicateHandle(GetCurrentProcess(), GetCurrentThread(), hr = hrDuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
GetCurrentProcess(), &timeout_targetThread, GetCurrentProcess(), &timeout_targetThread,
0, FALSE, DUPLICATE_SAME_ACCESS); 0, FALSE, DUPLICATE_SAME_ACCESS);
@ -301,6 +318,7 @@ void testingprivRunWithTimeout(testingT *t, const char *file, long line, int64_t
goto out; goto out;
} }
closeTargetThread = 1; closeTargetThread = 1;
timeout_targetThreadID = GetCurrentThreadId();
hr = hrCreateWaitableTimerW(NULL, TRUE, NULL, &timeout_timer); hr = hrCreateWaitableTimerW(NULL, TRUE, NULL, &timeout_timer);
if (hr != S_OK) { if (hr != S_OK) {