diff options
Diffstat (limited to 'src/platform/windows/win_iocp.c')
| -rw-r--r-- | src/platform/windows/win_iocp.c | 309 |
1 files changed, 0 insertions, 309 deletions
diff --git a/src/platform/windows/win_iocp.c b/src/platform/windows/win_iocp.c deleted file mode 100644 index 38807e30..00000000 --- a/src/platform/windows/win_iocp.c +++ /dev/null @@ -1,309 +0,0 @@ -// -// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> -// Copyright 2018 Capitar IT Group BV <info@capitar.com> -// -// 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 NNG_PLATFORM_WINDOWS - -#define NNI_WIN_IOCP_NTHREADS 4 -#include <stdio.h> - -// Windows IO Completion Port support. We basically create 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_thr nni_win_iocp_thrs[NNI_WIN_IOCP_NTHREADS]; -static nni_mtx nni_win_iocp_mtx; - -static void nni_win_event_start(nni_win_event *); - -static void -nni_win_event_finish(nni_win_event *evt) -{ - nni_aio *aio; - evt->run = 0; - - if ((aio = evt->active) != NULL) { - evt->active = NULL; - evt->ops.wev_finish(evt, aio); - } - if (evt->fini) { - nni_cv_wake(&evt->cv); - } -} - -static void -nni_win_iocp_handler(void *arg) -{ - HANDLE iocp; - DWORD cnt; - ULONG_PTR key; - OVERLAPPED * olpd; - nni_win_event *evt; - BOOL ok; - - NNI_ARG_UNUSED(arg); - - iocp = nni_win_global_iocp; - - for (;;) { - key = 0; - olpd = NULL; - - ok = GetQueuedCompletionStatus( - iocp, &cnt, &key, &olpd, INFINITE); - - if (olpd == NULL) { - // Completion port closed... - NNI_ASSERT(ok == FALSE); - break; - } - - evt = CONTAINING_RECORD(olpd, nni_win_event, olpd); - - nni_mtx_lock(&evt->mtx); - - if (ok) { - evt->status = 0; - } else if (evt->status == 0) { - evt->status = nni_win_error(GetLastError()); - } - - evt->count = cnt; - - nni_win_event_finish(evt); - nni_win_event_start(evt); - nni_mtx_unlock(&evt->mtx); - } -} - -static void -nni_win_event_cancel(nni_aio *aio, void *arg, int rv) -{ - nni_win_event *evt = arg; - - nni_mtx_lock(&evt->mtx); - if (aio == evt->active) { - evt->status = rv; - - // Use provider specific cancellation. - evt->ops.wev_cancel(evt); - } else if (nni_aio_list_active(aio)) { - nni_aio_list_remove(aio); - nni_aio_finish_error(aio, rv); - } - nni_mtx_unlock(&evt->mtx); -} - -void -nni_win_event_start(nni_win_event *evt) -{ - nni_aio *aio; - - // Lock held. - - if (evt->run) { - // Already running. - return; - } - - // Abort operation -- no further activity. - if (evt->fini || evt->closed) { - while ((aio = nni_list_first(&evt->aios)) != NULL) { - nni_aio_list_remove(aio); - nni_aio_finish_error(aio, NNG_ECLOSED); - } - return; - } - - if ((aio = nni_list_first(&evt->aios)) == NULL) { - return; - } - - nni_aio_list_remove(aio); - evt->active = aio; - evt->status = 0; - evt->count = 0; - if (!ResetEvent(evt->olpd.hEvent)) { - evt->active = NULL; - nni_aio_finish_error(aio, nni_win_error(GetLastError())); - return; - } - - evt->run = 1; - if (evt->ops.wev_start(evt, aio) != 0) { - // Start completed synchronously. It will have stored - // the count and status in the evt. - nni_win_event_finish(evt); - } -} - -void -nni_win_event_submit(nni_win_event *evt, nni_aio *aio) -{ - int rv; - if (nni_aio_begin(aio) != 0) { - return; - } - nni_mtx_lock(&evt->mtx); - if ((rv = nni_aio_schedule(aio, nni_win_event_cancel, evt)) != 0) { - nni_mtx_unlock(&evt->mtx); - nni_aio_finish_error(aio, rv); - return; - } - nni_aio_list_append(&evt->aios, aio); - nni_win_event_start(evt); - nni_mtx_unlock(&evt->mtx); -} - -void -nni_win_event_complete(nni_win_event *evt, int cnt) -{ - PostQueuedCompletionStatus(nni_win_global_iocp, cnt, 0, &evt->olpd); -} - -void -nni_win_event_close(nni_win_event *evt) -{ - nni_aio *aio; - - if (evt->ptr == NULL) { - return; // Never initialized - } - nni_mtx_lock(&evt->mtx); - evt->closed = 1; - evt->status = NNG_ECLOSED; - evt->ops.wev_cancel(evt); - while ((aio = nni_list_first(&evt->aios)) != NULL) { - nni_aio_list_remove(aio); - nni_aio_finish_error(aio, NNG_ECLOSED); - } - nni_mtx_unlock(&evt->mtx); -} - -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_event_init(nni_win_event *evt, nni_win_event_ops *ops, void *ptr) -{ - ZeroMemory(&evt->olpd, sizeof(evt->olpd)); - nni_mtx_init(&evt->mtx); - nni_cv_init(&evt->cv, &evt->mtx); - nni_aio_list_init(&evt->aios); - evt->ops = *ops; - evt->ptr = ptr; - evt->fini = 0; - evt->run = 0; - - evt->olpd.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - if (evt->olpd.hEvent == NULL) { - return (nni_win_error(GetLastError())); - } - - return (0); -} - -void -nni_win_event_fini(nni_win_event *evt) -{ - nni_aio *aio; - - if (evt->ptr == NULL) { - return; // Never initialized - } - nni_mtx_lock(&evt->mtx); - - evt->fini = 1; - - // Use provider specific cancellation. - evt->ops.wev_cancel(evt); - - // Wait for everything to stop referencing this. - while (evt->run) { - nni_cv_wait(&evt->cv); - } - - while ((aio = nni_list_first(&evt->aios)) != NULL) { - nni_aio_list_remove(aio); - nni_aio_finish_error(aio, NNG_ECLOSED); - } - - if (evt->olpd.hEvent != NULL) { - (void) CloseHandle(evt->olpd.hEvent); - evt->olpd.hEvent = NULL; - } - nni_mtx_unlock(&evt->mtx); - nni_cv_fini(&evt->cv); - nni_mtx_fini(&evt->mtx); -} - -int -nni_win_iocp_sysinit(void) -{ - HANDLE h; - int i; - int rv; - - 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; - } - } - nni_mtx_init(&nni_win_iocp_mtx); - 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) { - 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) { - CloseHandle(h); - nni_win_global_iocp = NULL; - } - for (i = 0; i < NNI_WIN_IOCP_NTHREADS; i++) { - nni_thr_fini(&nni_win_iocp_thrs[i]); - } - nni_mtx_fini(&nni_win_iocp_mtx); -} - -#endif // NNG_PLATFORM_WINDOWS |
