diff options
author | Brad King <brad.king@kitware.com> | 2020-04-08 12:47:53 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2020-04-08 12:48:01 (GMT) |
commit | 12cdb3692dbf33eb61bd42f7b1b01fa5d6a7b474 (patch) | |
tree | 5cf0fa0b193df95cfc958d1e4fc961f289b767e6 /Utilities/cmlibuv/src/win/pipe.c | |
parent | 09d28262bf3cadaf3e556d7554c28379dc6d7216 (diff) | |
parent | 630e501f8bb0a1d2e54e799a0c7e27b9264ecf86 (diff) | |
download | CMake-12cdb3692dbf33eb61bd42f7b1b01fa5d6a7b474.zip CMake-12cdb3692dbf33eb61bd42f7b1b01fa5d6a7b474.tar.gz CMake-12cdb3692dbf33eb61bd42f7b1b01fa5d6a7b474.tar.bz2 |
Merge topic 'update-libuv'
630e501f8b libuv: Restore compilation on Apple i386 architecture
02a28f1d44 libuv: Restore compilation with XLClang 16.1 on AIX
82a06d5cb4 CTestCustom: Suppress scanbuild warning in libuv
722d6b4105 Merge branch 'upstream-libuv' into update-libuv
394b07af40 libuv 2020-04-06 (d21f5aea)
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !4576
Diffstat (limited to 'Utilities/cmlibuv/src/win/pipe.c')
-rw-r--r-- | Utilities/cmlibuv/src/win/pipe.c | 151 |
1 files changed, 80 insertions, 71 deletions
diff --git a/Utilities/cmlibuv/src/win/pipe.c b/Utilities/cmlibuv/src/win/pipe.c index 277f649..fc0112a 100644 --- a/Utilities/cmlibuv/src/win/pipe.c +++ b/Utilities/cmlibuv/src/win/pipe.c @@ -264,8 +264,9 @@ static int uv_set_pipe_handle(uv_loop_t* loop, DWORD current_mode = 0; DWORD err = 0; - if (!(handle->flags & UV_HANDLE_PIPESERVER) && - handle->handle != INVALID_HANDLE_VALUE) + if (handle->flags & UV_HANDLE_PIPESERVER) + return UV_EINVAL; + if (handle->handle != INVALID_HANDLE_VALUE) return UV_EBUSY; if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) { @@ -312,7 +313,7 @@ static int uv_set_pipe_handle(uv_loop_t* loop, /* Overlapped pipe. Try to associate with IOCP. */ if (CreateIoCompletionPort(pipeHandle, loop->iocp, - (ULONG_PTR)handle, + (ULONG_PTR) handle, 0) == NULL) { handle->flags |= UV_HANDLE_EMULATE_IOCP; } @@ -326,6 +327,38 @@ static int uv_set_pipe_handle(uv_loop_t* loop, } +static int pipe_alloc_accept(uv_loop_t* loop, uv_pipe_t* handle, + uv_pipe_accept_t* req, BOOL firstInstance) { + assert(req->pipeHandle == INVALID_HANDLE_VALUE); + + req->pipeHandle = + CreateNamedPipeW(handle->name, + PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | WRITE_DAC | + (firstInstance ? FILE_FLAG_FIRST_PIPE_INSTANCE : 0), + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, + PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL); + + if (req->pipeHandle == INVALID_HANDLE_VALUE) { + return 0; + } + + /* Associate it with IOCP so we can get events. */ + if (CreateIoCompletionPort(req->pipeHandle, + loop->iocp, + (ULONG_PTR) handle, + 0) == NULL) { + uv_fatal_error(GetLastError(), "CreateIoCompletionPort"); + } + + /* Stash a handle in the server object for use from places such as + * getsockname and chmod. As we transfer ownership of these to client + * objects, we'll allocate new ones here. */ + handle->handle = req->pipeHandle; + + return 1; +} + + static DWORD WINAPI pipe_shutdown_thread_proc(void* parameter) { uv_loop_t* loop; uv_pipe_t* handle; @@ -458,7 +491,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) { UnregisterWait(handle->read_req.wait_handle); handle->read_req.wait_handle = INVALID_HANDLE_VALUE; } - if (handle->read_req.event_handle) { + if (handle->read_req.event_handle != NULL) { CloseHandle(handle->read_req.event_handle); handle->read_req.event_handle = NULL; } @@ -540,13 +573,10 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) { * Attempt to create the first pipe with FILE_FLAG_FIRST_PIPE_INSTANCE. * If this fails then there's already a pipe server for the given pipe name. */ - handle->pipe.serv.accept_reqs[0].pipeHandle = CreateNamedPipeW(handle->name, - PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | - FILE_FLAG_FIRST_PIPE_INSTANCE | WRITE_DAC, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, - PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL); - - if (handle->pipe.serv.accept_reqs[0].pipeHandle == INVALID_HANDLE_VALUE) { + if (!pipe_alloc_accept(loop, + handle, + &handle->pipe.serv.accept_reqs[0], + TRUE)) { err = GetLastError(); if (err == ERROR_ACCESS_DENIED) { err = WSAEADDRINUSE; /* Translates to UV_EADDRINUSE. */ @@ -556,15 +586,6 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) { goto error; } - if (uv_set_pipe_handle(loop, - handle, - handle->pipe.serv.accept_reqs[0].pipeHandle, - -1, - 0)) { - err = GetLastError(); - goto error; - } - handle->pipe.serv.pending_accepts = NULL; handle->flags |= UV_HANDLE_PIPESERVER; handle->flags |= UV_HANDLE_BOUND; @@ -577,11 +598,6 @@ error: handle->name = NULL; } - if (handle->pipe.serv.accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE) { - CloseHandle(handle->pipe.serv.accept_reqs[0].pipeHandle); - handle->pipe.serv.accept_reqs[0].pipeHandle = INVALID_HANDLE_VALUE; - } - return uv_translate_sys_error(err); } @@ -827,29 +843,11 @@ static void uv_pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle, uv_pipe_accept_t* req, BOOL firstInstance) { assert(handle->flags & UV_HANDLE_LISTENING); - if (!firstInstance) { - assert(req->pipeHandle == INVALID_HANDLE_VALUE); - - req->pipeHandle = CreateNamedPipeW(handle->name, - PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | WRITE_DAC, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, - PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL); - - if (req->pipeHandle == INVALID_HANDLE_VALUE) { - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*) req); - handle->reqs_pending++; - return; - } - - if (uv_set_pipe_handle(loop, handle, req->pipeHandle, -1, 0)) { - CloseHandle(req->pipeHandle); - req->pipeHandle = INVALID_HANDLE_VALUE; - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*) req); - handle->reqs_pending++; - return; - } + if (!firstInstance && !pipe_alloc_accept(loop, handle, req, FALSE)) { + SET_REQ_ERROR(req, GetLastError()); + uv_insert_pending_req(loop, (uv_req_t*) req); + handle->reqs_pending++; + return; } assert(req->pipeHandle != INVALID_HANDLE_VALUE); @@ -904,7 +902,7 @@ int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) { uv__free(item); } else { - pipe_client = (uv_pipe_t*)client; + pipe_client = (uv_pipe_t*) client; /* Find a connection instance that has been connected, but not yet * accepted. */ @@ -925,6 +923,7 @@ int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) { req->next_pending = NULL; req->pipeHandle = INVALID_HANDLE_VALUE; + server->handle = INVALID_HANDLE_VALUE; if (!(server->flags & UV_HANDLE_CLOSING)) { uv_pipe_queue_accept(loop, server, req, FALSE); } @@ -955,6 +954,10 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) { return ERROR_NOT_SUPPORTED; } + if (handle->ipc) { + return WSAEINVAL; + } + handle->flags |= UV_HANDLE_LISTENING; INCREASE_ACTIVE_COUNT(loop, handle); handle->stream.serv.connection_cb = cb; @@ -1131,6 +1134,7 @@ static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) { } else { memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); if (handle->flags & UV_HANDLE_EMULATE_IOCP) { + assert(req->event_handle != NULL); req->u.io.overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1); } @@ -1148,15 +1152,9 @@ static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) { } if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - if (!req->event_handle) { - req->event_handle = CreateEvent(NULL, 0, 0, NULL); - if (!req->event_handle) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - } if (req->wait_handle == INVALID_HANDLE_VALUE) { if (!RegisterWaitForSingleObject(&req->wait_handle, - req->u.io.overlapped.hEvent, post_completion_read_wait, (void*) req, + req->event_handle, post_completion_read_wait, (void*) req, INFINITE, WT_EXECUTEINWAITTHREAD)) { SET_REQ_ERROR(req, GetLastError()); goto error; @@ -1190,8 +1188,16 @@ int uv_pipe_read_start(uv_pipe_t* handle, /* If reading was stopped and then started again, there could still be a read * request pending. */ - if (!(handle->flags & UV_HANDLE_READ_PENDING)) + if (!(handle->flags & UV_HANDLE_READ_PENDING)) { + if (handle->flags & UV_HANDLE_EMULATE_IOCP && + handle->read_req.event_handle == NULL) { + handle->read_req.event_handle = CreateEvent(NULL, 0, 0, NULL); + if (handle->read_req.event_handle == NULL) { + uv_fatal_error(GetLastError(), "CreateEvent"); + } + } uv_pipe_queue_read(loop, handle); + } return 0; } @@ -1326,7 +1332,16 @@ static int uv__pipe_write_data(uv_loop_t* loop, req->coalesced = 0; req->event_handle = NULL; req->wait_handle = INVALID_HANDLE_VALUE; + + /* Prepare the overlapped structure. */ memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); + if (handle->flags & (UV_HANDLE_EMULATE_IOCP | UV_HANDLE_BLOCKING_WRITES)) { + req->event_handle = CreateEvent(NULL, 0, 0, NULL); + if (req->event_handle == NULL) { + uv_fatal_error(GetLastError(), "CreateEvent"); + } + req->u.io.overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1); + } req->write_buffer = uv_null_buf_; if (nbufs == 0) { @@ -1375,11 +1390,6 @@ static int uv__pipe_write_data(uv_loop_t* loop, handle->write_queue_size += req->u.io.queued_bytes; } else if (handle->flags & UV_HANDLE_BLOCKING_WRITES) { /* Using overlapped IO, but wait for completion before returning */ - req->u.io.overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL); - if (!req->u.io.overlapped.hEvent) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - result = WriteFile(handle->handle, write_buf.base, write_buf.len, @@ -1388,7 +1398,8 @@ static int uv__pipe_write_data(uv_loop_t* loop, if (!result && GetLastError() != ERROR_IO_PENDING) { err = GetLastError(); - CloseHandle(req->u.io.overlapped.hEvent); + CloseHandle(req->event_handle); + req->event_handle = NULL; return err; } @@ -1399,14 +1410,16 @@ static int uv__pipe_write_data(uv_loop_t* loop, /* Request queued by the kernel. */ req->u.io.queued_bytes = write_buf.len; handle->write_queue_size += req->u.io.queued_bytes; - if (WaitForSingleObject(req->u.io.overlapped.hEvent, INFINITE) != + if (WaitForSingleObject(req->event_handle, INFINITE) != WAIT_OBJECT_0) { err = GetLastError(); - CloseHandle(req->u.io.overlapped.hEvent); + CloseHandle(req->event_handle); + req->event_handle = NULL; return err; } } - CloseHandle(req->u.io.overlapped.hEvent); + CloseHandle(req->event_handle); + req->event_handle = NULL; REGISTER_HANDLE_REQ(loop, handle, req); handle->reqs_pending++; @@ -1433,12 +1446,8 @@ static int uv__pipe_write_data(uv_loop_t* loop, } if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - req->event_handle = CreateEvent(NULL, 0, 0, NULL); - if (!req->event_handle) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } if (!RegisterWaitForSingleObject(&req->wait_handle, - req->u.io.overlapped.hEvent, post_completion_write_wait, (void*) req, + req->event_handle, post_completion_write_wait, (void*) req, INFINITE, WT_EXECUTEINWAITTHREAD)) { return GetLastError(); } |