Skip to content

Instantly share code, notes, and snippets.

@vSzemkel
Created July 1, 2017 08:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vSzemkel/533d793d1135f52b331f11fafe506b62 to your computer and use it in GitHub Desktop.
Save vSzemkel/533d793d1135f52b331f11fafe506b62 to your computer and use it in GitHub Desktop.
MsgWaitForMultipleObjectsEx with MWMO_ALERTABLE
// MsgWaitForMultipleObjectsEx.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <Windows.h>
VOID CALLBACK APCProc(ULONG_PTR dwParam) {
printf("Worker thread in APCProc\n");
};
DWORD WINAPI WorkerThreadProc(LPVOID ev) {
printf("Worker thread entry\n");
DWORD ret = ::MsgWaitForMultipleObjectsEx(1, (HANDLE*)ev, 10000, 0, MWMO_ALERTABLE);
switch (ret)
{
case WAIT_OBJECT_0:
printf("Wait object signalled");
break;
case WAIT_IO_COMPLETION:
printf("APC received in alertable wait state");
break;
case WAIT_TIMEOUT:
printf("Wait timeout");
break;
default:
break;
}
printf(" - Worker thread waiting ended\n");
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
printf("Main thread entry\n");
HANDLE ev = ::CreateEvent(NULL, TRUE, FALSE, NULL);
HANDLE th = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WorkerThreadProc, &ev, 0, NULL);
// wait for the worker thread to go into alertable wait state
::Sleep(3000);
// alert waiting thread
printf("Main thread queues APC\n");
DWORD ii = ::QueueUserAPC(APCProc, th, 0);
printf("Main thread joins worker thread\n");
::WaitForSingleObject(th, INFINITE);
::CloseHandle(ev);
::CloseHandle(th);
printf("Main thread exits\n");
return 0;
}
/*
When worker thread is in alertable wait state (dwFlags == MWMO_ALERTABLE) the sequecne is as follows:
Main thread entry
Worker thread entry
Main thread queues APC
Main thread joins worker thread
Worker thread in APCProc
APC received in alertable wait state - Worker thread waiting ended
Main thread exits
When worker thread is in non alertable wait state (dwFlags == 0) the sequecne is as follows:
Main thread entry
Worker thread entry
Main thread queues APC -- note this is ignored as "the thread is not directed to call the APC function unless it is in an alertable state"!
Main thread joins worker thread
Wait timeout - Worker thread waiting ended
Main thread exits
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment