1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <thread>
#include <chrono>
#include <atomic>
static std::atomic<bool> stopSignal;
HANDLE ghEvents[3];
HANDLE thread_handle;
DWORD WINAPI run(LPVOID lpParam)
{
// Wait for the thread to signal one of the event objects
DWORD dwEvent;
while (stopSignal.load() == false)
{
dwEvent = MsgWaitForMultipleObjectsEx(3, ghEvents, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);
if (dwEvent != WAIT_IO_COMPLETION)
{
switch (dwEvent)
{
// ghEvents[0] was signaled
case WAIT_OBJECT_0 + 0:
printf("First event was signaled.\n");
break;
// ghEvents[1] was signaled
case WAIT_OBJECT_0 + 1:
printf("Second event was signaled.\n");
break;
// Return value is invalid.
default:
printf("Wait error: %d\n", GetLastError());
ExitProcess(0);
}
}
}
return 0;
}
VOID CALLBACK apc_function_1(ULONG_PTR dwParam)
{
size_t* obj = (size_t*)dwParam;
printf("processing %d\n", *obj);
}
int main(void)
{
int i;
stopSignal.exchange(false);
DWORD thread_id;
for (i = 0; i < 2; i++)
{
ghEvents[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
}
printf("0 to stop\n");
printf("> 0 to send 50 events\n\n");
thread_handle = CreateThread(NULL, 0, run, NULL, 0, &thread_id);
ghEvents[2] = thread_handle;
size_t* value;
while (stopSignal.load() == false)
{
std::cin >> i;
if (i == 0)
{
stopSignal.exchange(true);
SetEvent(ghEvents[0]);
}
else
{
for (size_t j = 0; j < 50; ++j)
{
value = new size_t;
*value = j + 1;
QueueUserAPC(apc_function_1, thread_handle, (ULONG_PTR)value);
}
}
}
WaitForMultipleObjects(1, &thread_handle, TRUE, INFINITE);
// Close event handles
for (i = 0; i < 3; i++)
CloseHandle(ghEvents[i]);
return 0;
}
|