Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <winsock2.h>
- #include <mswsock.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <time.h>
- #pragma comment(lib,"ws2_32") // Standard socket API.
- #pragma comment(lib,"mswsock") // AcceptEx, TransmitFile, etc,.
- #pragma comment(lib,"shlwapi") // UrlUnescape.
- #define WORKER_MAX_THREAD_COUNT 256
- #define DATA_BUFSIZE 4096
- enum
- {
- COMPLETION_KEY_NONE = 0,
- COMPLETION_KEY_SHUTDOWN = 1,
- COMPLETION_KEY_USER_TASK = 2,
- COMPLETION_KEY_USER_DATA_LOAD = 3
- };
- static void dump_error(int err) {
- LPSTR messageBuffer = 0;
- size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, WSAGetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
- fprintf(stderr, "--- [err: %d] %s\n", err, messageBuffer);
- LocalFree(messageBuffer);
- }
- static unsigned int __stdcall WorkerProc(void* IoPort) {
- fprintf(stderr, "- Event loop started [id: %d]\n", GetCurrentThreadId());
- for (;;)
- {
- BOOL Status = 0;
- DWORD NumTransferred = 0;
- ULONG_PTR CompKey = COMPLETION_KEY_NONE;
- LPOVERLAPPED pOver = 0;
- Status = GetQueuedCompletionStatus((HANDLE)IoPort, &NumTransferred, &CompKey, &pOver, INFINITE);
- if (Status == FALSE) {
- int err = WSAGetLastError();
- if (err != WSA_IO_PENDING) {
- dump_error(err);
- }
- continue;
- }
- //-
- if (COMPLETION_KEY_SHUTDOWN == CompKey)
- break;
- if (COMPLETION_KEY_USER_TASK == CompKey) {
- //fprintf(stderr, "- Processing [id: %d]\n", GetCurrentThreadId());
- time_t endTime = time(NULL) + 5;
- while (time(NULL) < endTime) {
- // do work here.
- }
- //fprintf(stderr, "- Done processing [id: %d]\n", GetCurrentThreadId());
- }
- if (COMPLETION_KEY_USER_DATA_LOAD == CompKey) {
- //fprintf(stderr, "- Loading [id: %d]\n", GetCurrentThreadId());
- time_t endTime = time(NULL) + 5;
- while (time(NULL) < endTime) {
- // do work here.
- }
- }
- }
- fprintf(stderr, "- Event loop done [id: %d]\n", GetCurrentThreadId());
- return 0;
- }
- static void hang_in_there(void) {
- fprintf(stderr, "*** Press enter to exit ...");
- fgetc(stdin);
- }
- int main(int argc, char **argv) {
- atexit(hang_in_there);
- WSADATA wsaData = { 0 };
- WSAStartup(MAKEWORD(2, 2), &wsaData);
- SYSTEM_INFO sysinfo;
- GetSystemInfo(&sysinfo);
- int numCPU = sysinfo.dwNumberOfProcessors;
- HANDLE IoPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);
- HANDLE IoLoadPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);
- HANDLE Workers[WORKER_MAX_THREAD_COUNT] = { 0 };
- unsigned int WorkerIds[WORKER_MAX_THREAD_COUNT] = { 0 };
- Workers[0] = (HANDLE)_beginthreadex(0, 0, WorkerProc, IoLoadPort, 0, WorkerIds);
- SetThreadAffinityMask(Workers[0], 0x01);
- for (size_t i = 1; i < numCPU; i++) {
- Workers[i] = (HANDLE)_beginthreadex(0, 0, WorkerProc, IoPort, 0, WorkerIds + i);
- SetThreadAffinityMask(Workers[i], 0xFE);
- }
- for(;;)
- {
- fgetc(stdin);
- PostQueuedCompletionStatus(IoPort, 0, COMPLETION_KEY_USER_TASK, 0);
- //PostQueuedCompletionStatus(IoLoadPort, 0, COMPLETION_KEY_USER_DATA_LOAD, 0);
- }
- for (size_t i = 0; i<numCPU; i++)
- PostQueuedCompletionStatus(IoPort, 0, COMPLETION_KEY_SHUTDOWN, 0);
- WaitForMultipleObjects(numCPU, Workers, TRUE, INFINITE);
- for (size_t i = 0; i<numCPU; i++)
- CloseHandle(Workers[i]);
- CloseHandle(IoPort);
- WSACleanup();
- return 0;
- }
Add Comment
Please, Sign In to add comment