From b214fe66efb2d2d5e0d79bd5f27d3e4fdcdb8f4f Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Fri, 23 Jan 2015 23:32:19 +0100 Subject: [PATCH 1/4] linux: fix epoll_pwait() regression with < 2.6.19 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Linux before kernel 2.6.19 does not support epoll_pwait(). Due to a logic error in commit 2daf944 ("unix: add flag for blocking SIGPROF during poll"), the fallback path for ENOSYS was not taken. This commit also adds epoll_pwait() emulation using pthread_sigmask(). The block/unblock operations are not atomic but that is fine for our particular use case, to wit, sleep through SIGPROF signals. This is a back-port of commit 67bb2b5 from the v1.x branch. Original-PR-URL: https://github.com/libuv/libuv/pull/162 Reviewed-By: Saúl Ibarra Corretgé PR-URL: https://github.com/libuv/libuv/pull/165 Reviewed-By: Saúl Ibarra Corretgé --- src/unix/linux-core.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/unix/linux-core.c b/src/unix/linux-core.c index 86c74caa..6cd5a7f0 100644 --- a/src/unix/linux-core.c +++ b/src/unix/linux-core.c @@ -125,11 +125,14 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { void uv__io_poll(uv_loop_t* loop, int timeout) { + static int no_epoll_pwait; + static int no_epoll_wait; struct uv__epoll_event events[1024]; struct uv__epoll_event* pe; struct uv__epoll_event e; ngx_queue_t* q; uv__io_t* w; + sigset_t sigset; uint64_t sigmask; uint64_t base; uint64_t diff; @@ -139,7 +142,6 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { int fd; int op; int i; - static int no_epoll_wait; if (loop->nfds == 0) { assert(ngx_queue_empty(&loop->watcher_queue)); @@ -182,31 +184,42 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { } sigmask = 0; - if (loop->flags & UV_LOOP_BLOCK_SIGPROF) + if (loop->flags & UV_LOOP_BLOCK_SIGPROF) { + sigemptyset(&sigset); + sigaddset(&sigset, SIGPROF); sigmask |= 1 << (SIGPROF - 1); + } assert(timeout >= -1); base = loop->time; count = 48; /* Benchmarks suggest this gives the best throughput. */ for (;;) { - if (no_epoll_wait || sigmask) { + if (sigmask != 0 && no_epoll_pwait != 0) + if (pthread_sigmask(SIG_BLOCK, &sigset, NULL)) + abort(); + + if (sigmask != 0 && no_epoll_pwait == 0) { nfds = uv__epoll_pwait(loop->backend_fd, events, ARRAY_SIZE(events), timeout, sigmask); + if (nfds == -1 && errno == ENOSYS) + no_epoll_pwait = 1; } else { nfds = uv__epoll_wait(loop->backend_fd, events, ARRAY_SIZE(events), timeout); - if (nfds == -1 && errno == ENOSYS) { + if (nfds == -1 && errno == ENOSYS) no_epoll_wait = 1; - continue; - } } + if (sigmask != 0 && no_epoll_pwait != 0) + if (pthread_sigmask(SIG_UNBLOCK, &sigset, NULL)) + abort(); + /* Update loop->time unconditionally. It's tempting to skip the update when * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the * operating system didn't reschedule our process while in the syscall. @@ -219,6 +232,12 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { } if (nfds == -1) { + if (errno == ENOSYS) { + /* epoll_wait() or epoll_pwait() failed, try the other system call. */ + assert(no_epoll_wait == 0 || no_epoll_pwait == 0); + continue; + } + if (errno != EINTR) abort(); From 77e85b9f308fd615a8eafd1ab7d6d01c91310248 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sat, 24 Jan 2015 18:57:01 +0100 Subject: [PATCH 2/4] test: back-port uv_loop_configure() test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Back-port the uv_loop_configure() test from commit 751ac48 from the v1.x branch. PR-URL: https://github.com/libuv/libuv/pull/165 Reviewed-By: Saúl Ibarra Corretgé --- build.mk | 1 + test/test-list.h | 2 ++ test/test-loop-configure.c | 40 ++++++++++++++++++++++++++++++++++++++ uv.gyp | 1 + 4 files changed, 44 insertions(+) create mode 100644 test/test-loop-configure.c diff --git a/build.mk b/build.mk index a2fdac7d..ea0b8a91 100644 --- a/build.mk +++ b/build.mk @@ -91,6 +91,7 @@ TESTS= \ test/test-ipc-send-recv.o \ test/test-loop-handles.o \ test/test-loop-stop.o \ + test/test-loop-configure.o \ test/test-multiple-listen.o \ test/test-mutexes.o \ test/test-osx-select.o \ diff --git a/test/test-list.h b/test/test-list.h index fb4b438f..51d60aae 100644 --- a/test/test-list.h +++ b/test/test-list.h @@ -24,6 +24,7 @@ TEST_DECLARE (callback_order) TEST_DECLARE (run_once) TEST_DECLARE (run_nowait) TEST_DECLARE (loop_stop) +TEST_DECLARE (loop_configure) TEST_DECLARE (barrier_1) TEST_DECLARE (barrier_2) TEST_DECLARE (barrier_3) @@ -250,6 +251,7 @@ TASK_LIST_START TEST_ENTRY (run_once) TEST_ENTRY (run_nowait) TEST_ENTRY (loop_stop) + TEST_ENTRY (loop_configure) TEST_ENTRY (barrier_1) TEST_ENTRY (barrier_2) TEST_ENTRY (barrier_3) diff --git a/test/test-loop-configure.c b/test/test-loop-configure.c new file mode 100644 index 00000000..9fefc592 --- /dev/null +++ b/test/test-loop-configure.c @@ -0,0 +1,40 @@ +/* Copyright (c) 2014, Ben Noordhuis + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static void timer_cb(uv_timer_t* handle, int status) { + uv_close((uv_handle_t*) handle, NULL); +} + + +TEST_IMPL(loop_configure) { + uv_timer_t timer_handle; + uv_loop_t* loop; + + loop = uv_default_loop(); +#ifdef _WIN32 + ASSERT(UV_ENOSYS == uv_loop_configure(loop, UV_LOOP_BLOCK_SIGNAL, 0)); +#else + ASSERT(0 == uv_loop_configure(loop, UV_LOOP_BLOCK_SIGNAL, SIGPROF)); +#endif + ASSERT(0 == uv_timer_init(loop, &timer_handle)); + ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 10, 0)); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/uv.gyp b/uv.gyp index d64aa25f..043ec34c 100644 --- a/uv.gyp +++ b/uv.gyp @@ -311,6 +311,7 @@ 'test/test-list.h', 'test/test-loop-handles.c', 'test/test-loop-stop.c', + 'test/test-loop-configure.c', 'test/test-walk-handles.c', 'test/test-watcher-cross-stop.c', 'test/test-multiple-listen.c', From 7a2253d33ad8215a26c1b34f1952aee7242dd687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Wed, 28 Jan 2015 21:43:42 +0100 Subject: [PATCH 3/4] 2015.01.29, Version 0.10.33 (Stable) Changes since version 0.10.32: * linux: fix epoll_pwait() regression with < 2.6.19 (Ben Noordhuis) * test: back-port uv_loop_configure() test (Ben Noordhuis) --- ChangeLog | 9 +++++++++ src/version.c | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 02a866d7..3a7cb9dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2015.01.29, Version 0.10.33 (Stable) + +Changes since version 0.10.32: + +* linux: fix epoll_pwait() regression with < 2.6.19 (Ben Noordhuis) + +* test: back-port uv_loop_configure() test (Ben Noordhuis) + + 2015.01.06, Version 0.10.32 (Stable), 378de30c59aef5fdb6d130fa5cfcb0a68fce571c Changes since version 0.10.31: diff --git a/src/version.c b/src/version.c index bca13b14..d8c226b8 100644 --- a/src/version.c +++ b/src/version.c @@ -35,7 +35,7 @@ #define UV_VERSION_MAJOR 0 #define UV_VERSION_MINOR 10 #define UV_VERSION_PATCH 33 -#define UV_VERSION_IS_RELEASE 0 +#define UV_VERSION_IS_RELEASE 1 #define UV_VERSION ((UV_VERSION_MAJOR << 16) | \ From fb2dab826d69dabfec32f61e6d78ba36056f5d98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Wed, 28 Jan 2015 21:43:47 +0100 Subject: [PATCH 4/4] Now working on v0.10.34 --- ChangeLog | 2 +- src/version.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3a7cb9dd..7903ee08 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -2015.01.29, Version 0.10.33 (Stable) +2015.01.29, Version 0.10.33 (Stable), 7a2253d33ad8215a26c1b34f1952aee7242dd687 Changes since version 0.10.32: diff --git a/src/version.c b/src/version.c index d8c226b8..b0375aa5 100644 --- a/src/version.c +++ b/src/version.c @@ -34,8 +34,8 @@ #define UV_VERSION_MAJOR 0 #define UV_VERSION_MINOR 10 -#define UV_VERSION_PATCH 33 -#define UV_VERSION_IS_RELEASE 1 +#define UV_VERSION_PATCH 34 +#define UV_VERSION_IS_RELEASE 0 #define UV_VERSION ((UV_VERSION_MAJOR << 16) | \