aboutsummaryrefslogtreecommitdiff
path: root/src/platform/windows/win_iocp.c
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2017-07-07 18:17:51 -0700
committerGarrett D'Amore <garrett@damore.org>2017-07-07 18:17:51 -0700
commit021d09af1375834fe9aaca916e60dcd2ad3be845 (patch)
treee3a4c8d2e0eddd69b79308b67922725901752ee9 /src/platform/windows/win_iocp.c
parentc6df64d90ff9799b9f5970c4897e2b9a55e2ce69 (diff)
downloadnng-021d09af1375834fe9aaca916e60dcd2ad3be845.tar.gz
nng-021d09af1375834fe9aaca916e60dcd2ad3be845.tar.bz2
nng-021d09af1375834fe9aaca916e60dcd2ad3be845.zip
Start of progress on Windows. Name resolution and IOCP work begins.
Diffstat (limited to 'src/platform/windows/win_iocp.c')
-rw-r--r--src/platform/windows/win_iocp.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/src/platform/windows/win_iocp.c b/src/platform/windows/win_iocp.c
new file mode 100644
index 00000000..06feb62e
--- /dev/null
+++ b/src/platform/windows/win_iocp.c
@@ -0,0 +1,145 @@
+//
+// Copyright 2017 Garrett D'Amore <garrett@damore.org>
+//
+// This software is supplied under the terms of the MIT License, a
+// copy of which should be located in the distribution where this
+// file was obtained (LICENSE.txt). A copy of the license may also be
+// found online at https://opensource.org/licenses/MIT.
+//
+
+#include "core/nng_impl.h"
+
+#ifdef PLATFORM_WINDOWS
+
+#define NNI_WIN_IOCP_NTHREADS 4
+#include <stdio.h>
+
+// Windows IO Completion Port support. We basically creaet a single
+// IO completion port, then start threads on it. Handles are added
+// to the port on an as needed basis. We use a single IO completion
+// port for pretty much everything.
+
+static HANDLE nni_win_global_iocp = NULL;
+static nni_win_event nni_win_iocp_exit;
+static nni_thr nni_win_iocp_thrs[NNI_WIN_IOCP_NTHREADS];
+
+static void
+nni_win_iocp_handler(void *arg)
+{
+ HANDLE iocp;
+ DWORD nbytes;
+ ULONG_PTR key;
+ OVERLAPPED *olpd;
+ nni_win_event *evt;
+ int status;
+ BOOL rv;
+
+ NNI_ARG_UNUSED(arg);
+
+ iocp = nni_win_global_iocp;
+
+ for (;;) {
+ key = 0;
+ olpd = NULL;
+ status = 0;
+ rv = GetQueuedCompletionStatus(iocp, &nbytes, &key, &olpd,
+ INFINITE);
+
+ if (rv == FALSE) {
+ if (olpd == NULL) {
+ // Completion port bailed...
+ break;
+ }
+ nbytes = 0;
+ key = 0;
+ status = nni_win_error(GetLastError());
+ }
+
+ NNI_ASSERT(olpd != NULL);
+ evt = (void *) olpd;
+ if (evt == &nni_win_iocp_exit) {
+ // Exit requested.
+ break;
+ }
+
+ NNI_ASSERT(evt->cb != NULL);
+ evt->nbytes = nbytes;
+ evt->status = status;
+ evt->cb(evt->ptr);
+ }
+}
+
+
+int
+nni_win_iocp_register(HANDLE h)
+{
+ if (CreateIoCompletionPort(h, nni_win_global_iocp, 0, 0) == NULL) {
+ return (nni_win_error(GetLastError()));
+ }
+ return (0);
+}
+
+
+int
+nni_win_iocp_sysinit(void)
+{
+ HANDLE h;
+ int i;
+ int rv;
+
+ ZeroMemory(&nni_win_iocp_exit, sizeof (nni_win_iocp_exit));
+ h = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0,
+ NNI_WIN_IOCP_NTHREADS);
+ if (h == NULL) {
+ return (nni_win_error(GetLastError()));
+ }
+ nni_win_global_iocp = h;
+ for (i = 0; i < NNI_WIN_IOCP_NTHREADS; i++) {
+ rv = nni_thr_init(&nni_win_iocp_thrs[i], nni_win_iocp_handler,
+ NULL);
+ if (rv != 0) {
+ goto fail;
+ }
+ }
+ for (i = 0; i < NNI_WIN_IOCP_NTHREADS; i++) {
+ nni_thr_run(&nni_win_iocp_thrs[i]);
+ }
+ return (0);
+
+fail:
+ if ((h = nni_win_global_iocp) != NULL) {
+ PostQueuedCompletionStatus(h, 0, 0, &nni_win_iocp_exit.olpd);
+ CloseHandle(h);
+ nni_win_global_iocp = NULL;
+ }
+ for (i = 0; i < NNI_WIN_IOCP_NTHREADS; i++) {
+ nni_thr_fini(&nni_win_iocp_thrs[i]);
+ }
+ return (rv);
+}
+
+
+void
+nni_win_iocp_sysfini(void)
+{
+ int i;
+ HANDLE h;
+
+ if ((h = nni_win_global_iocp) != NULL) {
+ // Signal the iocp poller to exit.
+ PostQueuedCompletionStatus(h, 0, 0, &nni_win_iocp_exit.olpd);
+ CloseHandle(h);
+ nni_win_global_iocp = NULL;
+ for (i = 0; i < NNI_WIN_IOCP_NTHREADS; i++) {
+ nni_thr_fini(&nni_win_iocp_thrs[i]);
+ }
+ }
+}
+
+
+#else
+
+// Suppress empty symbols warnings in ranlib.
+int nni_win_iocp_not_used = 0;
+
+#endif // PLATFORM_WINDOWS