linux: fix epoll_pwait() sigmask size calculation
Revisit the fix from commit b705b53. The problem with using sigset_t
and _NSIG is that the size of sigset_t and the value of _NSIG depend
on what headers libuv picks up first, <signal.h> or <asm/signal.h>.
With the former, sizeof(sigset_t) = 128; with the latter, it's 8.
Simply sidestep the issue by calculating the signal mask as a 64 bits
integer, without using sigset_t or _NSIG.
PR-URL: https://github.com/libuv/libuv/pull/83
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
This commit is contained in:
parent
a6d3d5a0f5
commit
751ac48baa
@ -159,6 +159,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
|||||||
test/test-loop-close.c \
|
test/test-loop-close.c \
|
||||||
test/test-loop-stop.c \
|
test/test-loop-stop.c \
|
||||||
test/test-loop-time.c \
|
test/test-loop-time.c \
|
||||||
|
test/test-loop-configure.c \
|
||||||
test/test-multiple-listen.c \
|
test/test-multiple-listen.c \
|
||||||
test/test-mutexes.c \
|
test/test-mutexes.c \
|
||||||
test/test-osx-select.c \
|
test/test-osx-select.c \
|
||||||
|
|||||||
@ -33,7 +33,6 @@
|
|||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
#include <sys/sysinfo.h>
|
#include <sys/sysinfo.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
@ -142,8 +141,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
|||||||
struct uv__epoll_event e;
|
struct uv__epoll_event e;
|
||||||
QUEUE* q;
|
QUEUE* q;
|
||||||
uv__io_t* w;
|
uv__io_t* w;
|
||||||
sigset_t* pset;
|
uint64_t sigmask;
|
||||||
sigset_t set;
|
|
||||||
uint64_t base;
|
uint64_t base;
|
||||||
uint64_t diff;
|
uint64_t diff;
|
||||||
int nevents;
|
int nevents;
|
||||||
@ -194,24 +192,21 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
|||||||
w->events = w->pevents;
|
w->events = w->pevents;
|
||||||
}
|
}
|
||||||
|
|
||||||
pset = NULL;
|
sigmask = 0;
|
||||||
if (loop->flags & UV_LOOP_BLOCK_SIGPROF) {
|
if (loop->flags & UV_LOOP_BLOCK_SIGPROF)
|
||||||
pset = &set;
|
sigmask |= 1 << (SIGPROF - 1);
|
||||||
sigemptyset(pset);
|
|
||||||
sigaddset(pset, SIGPROF);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(timeout >= -1);
|
assert(timeout >= -1);
|
||||||
base = loop->time;
|
base = loop->time;
|
||||||
count = 48; /* Benchmarks suggest this gives the best throughput. */
|
count = 48; /* Benchmarks suggest this gives the best throughput. */
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (no_epoll_wait || pset != NULL) {
|
if (no_epoll_wait || sigmask) {
|
||||||
nfds = uv__epoll_pwait(loop->backend_fd,
|
nfds = uv__epoll_pwait(loop->backend_fd,
|
||||||
events,
|
events,
|
||||||
ARRAY_SIZE(events),
|
ARRAY_SIZE(events),
|
||||||
timeout,
|
timeout,
|
||||||
pset);
|
sigmask);
|
||||||
} else {
|
} else {
|
||||||
nfds = uv__epoll_wait(loop->backend_fd,
|
nfds = uv__epoll_wait(loop->backend_fd,
|
||||||
events,
|
events,
|
||||||
|
|||||||
@ -321,15 +321,15 @@ int uv__epoll_pwait(int epfd,
|
|||||||
struct uv__epoll_event* events,
|
struct uv__epoll_event* events,
|
||||||
int nevents,
|
int nevents,
|
||||||
int timeout,
|
int timeout,
|
||||||
const sigset_t* sigmask) {
|
uint64_t sigmask) {
|
||||||
#if defined(__NR_epoll_pwait)
|
#if defined(__NR_epoll_pwait)
|
||||||
return syscall(__NR_epoll_pwait,
|
return syscall(__NR_epoll_pwait,
|
||||||
epfd,
|
epfd,
|
||||||
events,
|
events,
|
||||||
nevents,
|
nevents,
|
||||||
timeout,
|
timeout,
|
||||||
sigmask,
|
&sigmask,
|
||||||
_NSIG / 8);
|
sizeof(sigmask));
|
||||||
#else
|
#else
|
||||||
return errno = ENOSYS, -1;
|
return errno = ENOSYS, -1;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -131,7 +131,7 @@ int uv__epoll_pwait(int epfd,
|
|||||||
struct uv__epoll_event* events,
|
struct uv__epoll_event* events,
|
||||||
int nevents,
|
int nevents,
|
||||||
int timeout,
|
int timeout,
|
||||||
const sigset_t* sigmask);
|
uint64_t sigmask);
|
||||||
int uv__eventfd2(unsigned int count, int flags);
|
int uv__eventfd2(unsigned int count, int flags);
|
||||||
int uv__inotify_init(void);
|
int uv__inotify_init(void);
|
||||||
int uv__inotify_init1(int flags);
|
int uv__inotify_init1(int flags);
|
||||||
|
|||||||
@ -29,6 +29,7 @@ TEST_DECLARE (loop_close)
|
|||||||
TEST_DECLARE (loop_stop)
|
TEST_DECLARE (loop_stop)
|
||||||
TEST_DECLARE (loop_update_time)
|
TEST_DECLARE (loop_update_time)
|
||||||
TEST_DECLARE (loop_backend_timeout)
|
TEST_DECLARE (loop_backend_timeout)
|
||||||
|
TEST_DECLARE (loop_configure)
|
||||||
TEST_DECLARE (default_loop_close)
|
TEST_DECLARE (default_loop_close)
|
||||||
TEST_DECLARE (barrier_1)
|
TEST_DECLARE (barrier_1)
|
||||||
TEST_DECLARE (barrier_2)
|
TEST_DECLARE (barrier_2)
|
||||||
@ -313,6 +314,7 @@ TASK_LIST_START
|
|||||||
TEST_ENTRY (loop_stop)
|
TEST_ENTRY (loop_stop)
|
||||||
TEST_ENTRY (loop_update_time)
|
TEST_ENTRY (loop_update_time)
|
||||||
TEST_ENTRY (loop_backend_timeout)
|
TEST_ENTRY (loop_backend_timeout)
|
||||||
|
TEST_ENTRY (loop_configure)
|
||||||
TEST_ENTRY (default_loop_close)
|
TEST_ENTRY (default_loop_close)
|
||||||
TEST_ENTRY (barrier_1)
|
TEST_ENTRY (barrier_1)
|
||||||
TEST_ENTRY (barrier_2)
|
TEST_ENTRY (barrier_2)
|
||||||
|
|||||||
38
test/test-loop-configure.c
Normal file
38
test/test-loop-configure.c
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/* Copyright (c) 2014, Ben Noordhuis <info@bnoordhuis.nl>
|
||||||
|
*
|
||||||
|
* 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) {
|
||||||
|
uv_close((uv_handle_t*) handle, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_IMPL(loop_configure) {
|
||||||
|
uv_timer_t timer_handle;
|
||||||
|
uv_loop_t loop;
|
||||||
|
ASSERT(0 == uv_loop_init(&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));
|
||||||
|
ASSERT(0 == uv_loop_close(&loop));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
1
uv.gyp
1
uv.gyp
@ -315,6 +315,7 @@
|
|||||||
'test/test-loop-close.c',
|
'test/test-loop-close.c',
|
||||||
'test/test-loop-stop.c',
|
'test/test-loop-stop.c',
|
||||||
'test/test-loop-time.c',
|
'test/test-loop-time.c',
|
||||||
|
'test/test-loop-configure.c',
|
||||||
'test/test-walk-handles.c',
|
'test/test-walk-handles.c',
|
||||||
'test/test-watcher-cross-stop.c',
|
'test/test-watcher-cross-stop.c',
|
||||||
'test/test-multiple-listen.c',
|
'test/test-multiple-listen.c',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user