Skip to content

Instantly share code, notes, and snippets.

@mmozeiko mmozeiko/icop_test.c
Last active Dec 24, 2018

Embed
What would you like to do?
Trying out wait on IOCP handle & messages ** WARNING** works only on Windows 10
#include <windows.h>
#include <stdio.h>
#include <stdarg.h>
static LARGE_INTEGER start;
static LARGE_INTEGER freq;
static void LOG(const char* thread, const char* format, ...)
{
char message[1024];
va_list args;
va_start(args, format);
vsnprintf(message, sizeof(message), format, args);
va_end(args);
LARGE_INTEGER now;
QueryPerformanceCounter(&now);
float time = (float)(now.QuadPart - start.QuadPart) / freq.QuadPart;
fprintf(stderr, "[%.3f] %s: %s\n", time, thread, message);
}
static DWORD WINAPI iocp_post_thread(LPVOID arg)
{
HANDLE iocp = arg;
LOG("iocp", "sleeping for 1 second");
Sleep(1000);
unsigned data = 111;
LOG("iocp", "posting ICOP data = %u", data);
if (!PostQueuedCompletionStatus(iocp, 0, (ULONG_PTR)data, NULL))
{
LOG("iocp", "PostQueuedCompletionStatus error");
return 0;
}
LOG("iocp", "sleeping for 2 seconds");
Sleep(2000);
data = 333;
LOG("iocp", "posting ICOP data = %u", data);
if (!PostQueuedCompletionStatus(iocp, 0, (ULONG_PTR)data, NULL))
{
LOG("iocp", "PostQueuedCompletionStatus error");
return 0;
}
return 0;
}
static DWORD WINAPI iocp2_post_thread(LPVOID arg)
{
HANDLE iocp = arg;
LOG("iocp2", "sleeping for 1.1 seconds");
Sleep(1100);
unsigned data = 200111;
LOG("iocp2", "posting ICOP data = %u", data);
if (!PostQueuedCompletionStatus(iocp, 0, (ULONG_PTR)data, NULL))
{
LOG("iocp2", "PostQueuedCompletionStatus error");
return 0;
}
LOG("iocp2", "sleeping for 1 second");
Sleep(1000);
data = 200333;
LOG("iocp2", "posting ICOP data = %u", data);
if (!PostQueuedCompletionStatus(iocp, 0, (ULONG_PTR)data, NULL))
{
LOG("iocp2", "PostQueuedCompletionStatus error");
return 0;
}
return 0;
}
static DWORD WINAPI message_post_thread(LPVOID arg)
{
DWORD main_thread = (DWORD)(ULONG_PTR)arg;
LOG("message", "sleeping for 2 seconds");
Sleep(2000);
unsigned data = 222;
LOG("message", "posting message data = %u", data);
if (!PostThreadMessage(main_thread, WM_USER, (WPARAM)data, 0))
{
LOG("message", "PostThreadMessage error");
return 0;
}
LOG("message", "sleeping for 2 seconds");
Sleep(2000);
data = 444;
LOG("message", "posting message data = %u", data);
if (!PostThreadMessage(main_thread, WM_USER, (WPARAM)data, 0))
{
LOG("message", "PostThreadMessage error");
return 0;
}
return 0;
}
static DWORD WINAPI event_thread(LPVOID arg)
{
HANDLE event = arg;
LOG("event", "sleeping for 5 seconds");
Sleep(5000);
LOG("event", "raising event");
if (!SetEvent(event))
{
LOG("event", "SetEvent failed");
return 0;
}
return 0;
}
int main()
{
QueryPerformanceCounter(&start);
QueryPerformanceFrequency(&freq);
LOG("main", "creating IOCP");
HANDLE iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
if (iocp == NULL)
{
LOG("main", "CreateIoCompletionPort error");
return 0;
}
LOG("main", "creating second IOCP");
HANDLE iocp2 = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
if (iocp2 == NULL)
{
LOG("main", "CreateIoCompletionPort error");
return 0;
}
LOG("main", "creating event");
HANDLE event = CreateEventW(NULL, FALSE, FALSE, NULL);
if (event == NULL)
{
LOG("main", "CreateEventW error");
return 0;
}
LOG("main", "creating thread for posting IOCP event");
CreateThread(NULL, 0, &iocp_post_thread, iocp, 0, NULL);
LOG("main", "creating thread for posting second IOCP event");
CreateThread(NULL, 0, &iocp2_post_thread, iocp2, 0, NULL);
LOG("main", "creating thread for posting message");
DWORD main_thread = GetThreadId(GetCurrentThread());
CreateThread(NULL, 0, &message_post_thread, (LPVOID)(ULONG_PTR)main_thread, 0, NULL);
LOG("main", "creating thread for setting event");
CreateThread(NULL, 0, &event_thread, event, 0, NULL);
for (;;)
{
LOG("main", "waiting on IOCP or message");
HANDLE handles[] = { iocp, iocp2, event };
DWORD wait = MsgWaitForMultipleObjects(3, handles, FALSE, INFINITE, QS_ALLEVENTS);
if (wait == WAIT_OBJECT_0 || wait == WAIT_OBJECT_0 + 1)
{
LOG("main", "IOCP event nr %d", wait - WAIT_OBJECT_0);
DWORD count;
ULONG_PTR key;
OVERLAPPED* ov;
if (!GetQueuedCompletionStatus(wait == WAIT_OBJECT_0 ? iocp : iocp2, &count, &key, &ov, INFINITE))
{
LOG("main", "GetQueuedCompletionStatus error");
break;
}
unsigned data = (unsigned)key;
LOG("main", "received IOCP data = %u", data);
}
else if (wait == WAIT_OBJECT_0 + 2)
{
LOG("main", "event raised, terminating");
break;
}
else if (wait == WAIT_OBJECT_0 + 3)
{
LOG("main", "message available");
MSG msg;
if (!GetMessage(&msg, NULL, 0, 0))
{
LOG("main", "GetMessage error");
break;
}
unsigned data = (unsigned)msg.wParam;
LOG("main", "received message data = %u", data);
}
else
{
LOG("main", "MsgWaitForMultipleObjects error");
break;
}
}
LOG("main", "done");
}
[0.000] main: creating IOCP
[0.001] main: creating second IOCP
[0.001] main: creating event
[0.002] main: creating thread for posting IOCP event
[0.002] main: creating thread for posting second IOCP event
[0.002] iocp: sleeping for 1 second
[0.002] iocp2: sleeping for 1.1 seconds
[0.002] main: creating thread for posting message
[0.003] main: creating thread for setting event
[0.003] message: sleeping for 2 seconds
[0.003] main: waiting on IOCP or message
[0.003] event: sleeping for 5 seconds
[1.003] iocp: posting ICOP data = 111
[1.003] iocp: sleeping for 2 seconds
[1.003] main: IOCP event nr 0
[1.003] main: received IOCP data = 111
[1.003] main: waiting on IOCP or message
[1.104] iocp2: posting ICOP data = 200111
[1.104] iocp2: sleeping for 1 second
[1.104] main: IOCP event nr 1
[1.104] main: received IOCP data = 200111
[1.105] main: waiting on IOCP or message
[2.004] message: posting message data = 222
[2.004] message: sleeping for 2 seconds
[2.004] main: message available
[2.004] main: received message data = 222
[2.005] main: waiting on IOCP or message
[2.105] iocp2: posting ICOP data = 200333
[2.105] main: IOCP event nr 1
[2.105] main: received IOCP data = 200333
[2.105] main: waiting on IOCP or message
[3.004] iocp: posting ICOP data = 333
[3.004] main: IOCP event nr 0
[3.004] main: received IOCP data = 333
[3.004] main: waiting on IOCP or message
[4.005] message: posting message data = 444
[4.007] main: message available
[4.008] main: received message data = 444
[4.008] main: waiting on IOCP or message
[5.005] event: raising event
[5.005] main: event raised, terminating
[5.005] main: done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.