diff options
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | docs/requirements.txt | 51 | ||||
-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 | ||||
-rw-r--r-- | test/test-process-title-threadsafe.c | 8 |
9 files changed, 143 insertions, 183 deletions
diff --git a/Makefile.am b/Makefile.am index 5f29adbf..8a41f18a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -61,7 +61,6 @@ AM_CPPFLAGS += -I$(top_srcdir)/src/win \ -DWIN32_LEAN_AND_MEAN \ -D_WIN32_WINNT=0x0A00 libuv_la_SOURCES += src/win/async.c \ - src/win/atomicops-inl.h \ src/win/core.c \ src/win/detect-wakeup.c \ src/win/dl.c \ diff --git a/docs/requirements.txt b/docs/requirements.txt index 2e310ebe..0319b308 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,36 +1,29 @@ # primary -furo==2023.5.20 -Sphinx==6.1.3 +furo==2024.8.6 +Sphinx==7.0.1 # dependencies -alabaster==0.7.13 -Babel==2.11.0 -beautifulsoup4==4.12.2 -certifi==2022.12.7 -charset-normalizer==3.0.1 -colorama==0.4.6 -docutils==0.19 -idna==3.4 +alabaster==0.7.16 +babel==2.17.0 +beautifulsoup4==4.13.3 +certifi==2025.1.31 +charset-normalizer==3.4.1 +docutils==0.20.1 +idna==3.10 imagesize==1.4.1 -importlib-metadata==6.0.0 -Jinja2==3.1.2 -livereload==2.6.3 -MarkupSafe==2.1.2 -packaging==23.0 -Pygments==2.14.0 -pytz==2022.7.1 -requests==2.28.2 -six==1.16.0 +Jinja2==3.1.6 +MarkupSafe==3.0.2 +packaging==24.2 +Pygments==2.19.1 +requests==2.32.3 snowballstemmer==2.2.0 -soupsieve==2.4.1 -sphinx-autobuild==2021.3.14 +soupsieve==2.6 sphinx-basic-ng==1.0.0b2 -sphinxcontrib-devhelp==1.0.2 -sphinxcontrib-htmlhelp==2.0.0 +sphinxcontrib-applehelp==2.0.0 +sphinxcontrib-devhelp==2.0.0 +sphinxcontrib-htmlhelp==2.1.0 sphinxcontrib-jsmath==1.0.1 -sphinxcontrib-qthelp==1.0.3 -sphinxcontrib-serializinghtml==1.1.5 -sphinxcontrib.applehelp==1.0.3 -tornado==6.3.2 -urllib3==1.26.14 -zipp==3.11.0 +sphinxcontrib-qthelp==2.0.0 +sphinxcontrib-serializinghtml==2.0.0 +typing_extensions==4.13.0 +urllib3==2.3.0 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_ */ diff --git a/test/test-process-title-threadsafe.c b/test/test-process-title-threadsafe.c index daa13b8c..212c715a 100644 --- a/test/test-process-title-threadsafe.c +++ b/test/test-process-title-threadsafe.c @@ -89,6 +89,14 @@ TEST_IMPL(process_title_threadsafe) { RETURN_SKIP("uv_(get|set)_process_title is not implemented."); #endif +#if defined(__ASAN__) && defined(__APPLE__) + /* uv_set_process_title loads and unloads a bunch of dynamic libraries, + * and that's quite slow and prone to time out when running concurrently + * under AddressSanitizer. + */ + RETURN_SKIP("too slow under ASAN"); +#endif + ASSERT_OK(uv_set_process_title(titles[0])); ASSERT_OK(uv_sem_init(&getter_sem, 0)); |