diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/win/async.c | 20 | ||||
-rw-r--r-- | src/win/atomicops-inl.h | 61 | ||||
-rw-r--r-- | src/win/core.c | 91 | ||||
-rw-r--r-- | src/win/handle-inl.h | 68 | ||||
-rw-r--r-- | src/win/pipe.c | 3 | ||||
-rw-r--r-- | src/win/req-inl.h | 23 |
6 files changed, 113 insertions, 153 deletions
diff --git a/src/win/async.c b/src/win/async.c index b904676e..4c2cd265 100644 --- a/src/win/async.c +++ b/src/win/async.c @@ -23,10 +23,28 @@ #include "uv.h" #include "internal.h" -#include "atomicops-inl.h" #include "handle-inl.h" #include "req-inl.h" +#ifdef _MSC_VER /* MSVC */ + +/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less + * efficient than InterlockedExchange, but InterlockedExchange8 does not exist, + * and interlocked operations on larger targets might require the target to be + * aligned. */ +#pragma intrinsic(_InterlockedOr8) + +static char uv__atomic_exchange_set(char volatile* target) { + return _InterlockedOr8(target, 1); +} + +#else /* GCC, Clang in mingw mode */ + +static char uv__atomic_exchange_set(char volatile* target) { + return __sync_fetch_and_or(target, 1); +} + +#endif /* _MSC_VER */ void uv__async_endgame(uv_loop_t* loop, uv_async_t* handle) { if (handle->flags & UV_HANDLE_CLOSING && diff --git a/src/win/atomicops-inl.h b/src/win/atomicops-inl.h deleted file mode 100644 index 2f984c6d..00000000 --- a/src/win/atomicops-inl.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef UV_WIN_ATOMICOPS_INL_H_ -#define UV_WIN_ATOMICOPS_INL_H_ - -#include "uv.h" -#include "internal.h" - - -/* Atomic set operation on char */ -#ifdef _MSC_VER /* MSVC */ - -/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less - * efficient than InterlockedExchange, but InterlockedExchange8 does not exist, - * and interlocked operations on larger targets might require the target to be - * aligned. */ -#pragma intrinsic(_InterlockedOr8) - -static char INLINE uv__atomic_exchange_set(char volatile* target) { - return _InterlockedOr8(target, 1); -} - -#else /* GCC, Clang in mingw mode */ - -static inline char uv__atomic_exchange_set(char volatile* target) { -#if defined(__i386__) || defined(__x86_64__) - /* Mingw-32 version, hopefully this works for 64-bit gcc as well. */ - const char one = 1; - char old_value; - __asm__ __volatile__ ("lock xchgb %0, %1\n\t" - : "=r"(old_value), "=m"(*target) - : "0"(one), "m"(*target) - : "memory"); - return old_value; -#else - return __sync_fetch_and_or(target, 1); -#endif -} - -#endif - -#endif /* UV_WIN_ATOMICOPS_INL_H_ */ diff --git a/src/win/core.c b/src/win/core.c index ec50ec47..317238fd 100644 --- a/src/win/core.c +++ b/src/win/core.c @@ -629,6 +629,74 @@ static void uv__process_reqs(uv_loop_t* loop) { #undef DELEGATE_STREAM_REQ +static void uv__process_endgames(uv_loop_t* loop) { + uv_handle_t* handle; + + while (loop->endgame_handles) { + handle = loop->endgame_handles; + loop->endgame_handles = handle->endgame_next; + + handle->flags &= ~UV_HANDLE_ENDGAME_QUEUED; + + switch (handle->type) { + case UV_TCP: + uv__tcp_endgame(loop, (uv_tcp_t*) handle); + break; + + case UV_NAMED_PIPE: + uv__pipe_endgame(loop, (uv_pipe_t*) handle); + break; + + case UV_TTY: + uv__tty_endgame(loop, (uv_tty_t*) handle); + break; + + case UV_UDP: + uv__udp_endgame(loop, (uv_udp_t*) handle); + break; + + case UV_POLL: + uv__poll_endgame(loop, (uv_poll_t*) handle); + break; + + case UV_TIMER: + uv__timer_close((uv_timer_t*) handle); + uv__handle_close(handle); + break; + + case UV_PREPARE: + case UV_CHECK: + case UV_IDLE: + uv__loop_watcher_endgame(loop, handle); + break; + + case UV_ASYNC: + uv__async_endgame(loop, (uv_async_t*) handle); + break; + + case UV_SIGNAL: + uv__signal_endgame(loop, (uv_signal_t*) handle); + break; + + case UV_PROCESS: + uv__process_endgame(loop, (uv_process_t*) handle); + break; + + case UV_FS_EVENT: + uv__fs_event_endgame(loop, (uv_fs_event_t*) handle); + break; + + case UV_FS_POLL: + uv__fs_poll_endgame(loop, (uv_fs_poll_t*) handle); + break; + + default: + assert(0); + break; + } + } +} + int uv_run(uv_loop_t *loop, uv_run_mode mode) { DWORD timeout; @@ -786,3 +854,26 @@ int uv__getsockpeername(const uv_handle_t* handle, return 0; } + +void uv__insert_pending_req(uv_loop_t* loop, uv_req_t* req) { + req->next_req = NULL; + if (loop->pending_reqs_tail) { +#ifdef _DEBUG + /* Ensure the request is not already in the queue, or the queue + * will get corrupted. + */ + uv_req_t* current = loop->pending_reqs_tail; + do { + assert(req != current); + current = current->next_req; + } while (current != loop->pending_reqs_tail); +#endif + + req->next_req = loop->pending_reqs_tail->next_req; + loop->pending_reqs_tail->next_req = req; + loop->pending_reqs_tail = req; + } else { + req->next_req = req; + loop->pending_reqs_tail = req; + } +} diff --git a/src/win/handle-inl.h b/src/win/handle-inl.h index 4722e857..e30d148c 100644 --- a/src/win/handle-inl.h +++ b/src/win/handle-inl.h @@ -95,74 +95,6 @@ INLINE static void uv__want_endgame(uv_loop_t* loop, uv_handle_t* handle) { } -INLINE static void uv__process_endgames(uv_loop_t* loop) { - uv_handle_t* handle; - - while (loop->endgame_handles) { - handle = loop->endgame_handles; - loop->endgame_handles = handle->endgame_next; - - handle->flags &= ~UV_HANDLE_ENDGAME_QUEUED; - - switch (handle->type) { - case UV_TCP: - uv__tcp_endgame(loop, (uv_tcp_t*) handle); - break; - - case UV_NAMED_PIPE: - uv__pipe_endgame(loop, (uv_pipe_t*) handle); - break; - - case UV_TTY: - uv__tty_endgame(loop, (uv_tty_t*) handle); - break; - - case UV_UDP: - uv__udp_endgame(loop, (uv_udp_t*) handle); - break; - - case UV_POLL: - uv__poll_endgame(loop, (uv_poll_t*) handle); - break; - - case UV_TIMER: - uv__timer_close((uv_timer_t*) handle); - uv__handle_close(handle); - break; - - case UV_PREPARE: - case UV_CHECK: - case UV_IDLE: - uv__loop_watcher_endgame(loop, handle); - break; - - case UV_ASYNC: - uv__async_endgame(loop, (uv_async_t*) handle); - break; - - case UV_SIGNAL: - uv__signal_endgame(loop, (uv_signal_t*) handle); - break; - - case UV_PROCESS: - uv__process_endgame(loop, (uv_process_t*) handle); - break; - - case UV_FS_EVENT: - uv__fs_event_endgame(loop, (uv_fs_event_t*) handle); - break; - - case UV_FS_POLL: - uv__fs_poll_endgame(loop, (uv_fs_poll_t*) handle); - break; - - default: - assert(0); - break; - } - } -} - INLINE static HANDLE uv__get_osfhandle(int fd) { /* _get_osfhandle() raises an assert in debug builds if the FD is invalid. diff --git a/src/win/pipe.c b/src/win/pipe.c index d05bfd28..8f86a1fe 100644 --- a/src/win/pipe.c +++ b/src/win/pipe.c @@ -2149,7 +2149,8 @@ void uv__process_pipe_read_req(uv_loop_t* loop, } else { /* The zero-read completed without error, indicating there is data * available in the kernel buffer. */ - while (handle->flags & UV_HANDLE_READING) { + while (handle->flags & UV_HANDLE_READING && + !(handle->flags & UV_HANDLE_READ_PENDING)) { bytes_requested = 65536; /* Depending on the type of pipe, read either IPC frames or raw data. */ if (handle->ipc) diff --git a/src/win/req-inl.h b/src/win/req-inl.h index c1ca8ea4..af6fb752 100644 --- a/src/win/req-inl.h +++ b/src/win/req-inl.h @@ -81,27 +81,6 @@ uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); \ } -INLINE static void uv__insert_pending_req(uv_loop_t* loop, uv_req_t* req) { - req->next_req = NULL; - if (loop->pending_reqs_tail) { -#ifdef _DEBUG - /* Ensure the request is not already in the queue, or the queue - * will get corrupted. - */ - uv_req_t* current = loop->pending_reqs_tail; - do { - assert(req != current); - current = current->next_req; - } while(current != loop->pending_reqs_tail); -#endif - - req->next_req = loop->pending_reqs_tail->next_req; - loop->pending_reqs_tail->next_req = req; - loop->pending_reqs_tail = req; - } else { - req->next_req = req; - loop->pending_reqs_tail = req; - } -} +void uv__insert_pending_req(uv_loop_t* loop, uv_req_t* req); #endif /* UV_WIN_REQ_INL_H_ */ |