Skip to content

Commit 751ac48

Browse files
committed
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: #83 Reviewed-By: Saúl Ibarra Corretgé <[email protected]>
1 parent a6d3d5a commit 751ac48

7 files changed

Lines changed: 52 additions & 15 deletions

File tree

Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
159159
test/test-loop-close.c \
160160
test/test-loop-stop.c \
161161
test/test-loop-time.c \
162+
test/test-loop-configure.c \
162163
test/test-multiple-listen.c \
163164
test/test-mutexes.c \
164165
test/test-osx-select.c \

src/unix/linux-core.c

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
#include <sys/prctl.h>
3434
#include <sys/sysinfo.h>
3535
#include <unistd.h>
36-
#include <signal.h>
3736
#include <fcntl.h>
3837
#include <time.h>
3938

@@ -142,8 +141,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
142141
struct uv__epoll_event e;
143142
QUEUE* q;
144143
uv__io_t* w;
145-
sigset_t* pset;
146-
sigset_t set;
144+
uint64_t sigmask;
147145
uint64_t base;
148146
uint64_t diff;
149147
int nevents;
@@ -194,24 +192,21 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
194192
w->events = w->pevents;
195193
}
196194

197-
pset = NULL;
198-
if (loop->flags & UV_LOOP_BLOCK_SIGPROF) {
199-
pset = &set;
200-
sigemptyset(pset);
201-
sigaddset(pset, SIGPROF);
202-
}
195+
sigmask = 0;
196+
if (loop->flags & UV_LOOP_BLOCK_SIGPROF)
197+
sigmask |= 1 << (SIGPROF - 1);
203198

204199
assert(timeout >= -1);
205200
base = loop->time;
206201
count = 48; /* Benchmarks suggest this gives the best throughput. */
207202

208203
for (;;) {
209-
if (no_epoll_wait || pset != NULL) {
204+
if (no_epoll_wait || sigmask) {
210205
nfds = uv__epoll_pwait(loop->backend_fd,
211206
events,
212207
ARRAY_SIZE(events),
213208
timeout,
214-
pset);
209+
sigmask);
215210
} else {
216211
nfds = uv__epoll_wait(loop->backend_fd,
217212
events,

src/unix/linux-syscalls.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -321,15 +321,15 @@ int uv__epoll_pwait(int epfd,
321321
struct uv__epoll_event* events,
322322
int nevents,
323323
int timeout,
324-
const sigset_t* sigmask) {
324+
uint64_t sigmask) {
325325
#if defined(__NR_epoll_pwait)
326326
return syscall(__NR_epoll_pwait,
327327
epfd,
328328
events,
329329
nevents,
330330
timeout,
331-
sigmask,
332-
_NSIG / 8);
331+
&sigmask,
332+
sizeof(sigmask));
333333
#else
334334
return errno = ENOSYS, -1;
335335
#endif

src/unix/linux-syscalls.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ int uv__epoll_pwait(int epfd,
131131
struct uv__epoll_event* events,
132132
int nevents,
133133
int timeout,
134-
const sigset_t* sigmask);
134+
uint64_t sigmask);
135135
int uv__eventfd2(unsigned int count, int flags);
136136
int uv__inotify_init(void);
137137
int uv__inotify_init1(int flags);

test/test-list.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ TEST_DECLARE (loop_close)
2929
TEST_DECLARE (loop_stop)
3030
TEST_DECLARE (loop_update_time)
3131
TEST_DECLARE (loop_backend_timeout)
32+
TEST_DECLARE (loop_configure)
3233
TEST_DECLARE (default_loop_close)
3334
TEST_DECLARE (barrier_1)
3435
TEST_DECLARE (barrier_2)
@@ -313,6 +314,7 @@ TASK_LIST_START
313314
TEST_ENTRY (loop_stop)
314315
TEST_ENTRY (loop_update_time)
315316
TEST_ENTRY (loop_backend_timeout)
317+
TEST_ENTRY (loop_configure)
316318
TEST_ENTRY (default_loop_close)
317319
TEST_ENTRY (barrier_1)
318320
TEST_ENTRY (barrier_2)

test/test-loop-configure.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* Copyright (c) 2014, Ben Noordhuis <[email protected]>
2+
*
3+
* Permission to use, copy, modify, and/or distribute this software for any
4+
* purpose with or without fee is hereby granted, provided that the above
5+
* copyright notice and this permission notice appear in all copies.
6+
*
7+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10+
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12+
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13+
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14+
*/
15+
16+
#include "uv.h"
17+
#include "task.h"
18+
19+
static void timer_cb(uv_timer_t* handle) {
20+
uv_close((uv_handle_t*) handle, NULL);
21+
}
22+
23+
24+
TEST_IMPL(loop_configure) {
25+
uv_timer_t timer_handle;
26+
uv_loop_t loop;
27+
ASSERT(0 == uv_loop_init(&loop));
28+
#ifdef _WIN32
29+
ASSERT(UV_ENOSYS == uv_loop_configure(&loop, UV_LOOP_BLOCK_SIGNAL, 0));
30+
#else
31+
ASSERT(0 == uv_loop_configure(&loop, UV_LOOP_BLOCK_SIGNAL, SIGPROF));
32+
#endif
33+
ASSERT(0 == uv_timer_init(&loop, &timer_handle));
34+
ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 10, 0));
35+
ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT));
36+
ASSERT(0 == uv_loop_close(&loop));
37+
return 0;
38+
}

uv.gyp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@
315315
'test/test-loop-close.c',
316316
'test/test-loop-stop.c',
317317
'test/test-loop-time.c',
318+
'test/test-loop-configure.c',
318319
'test/test-walk-handles.c',
319320
'test/test-watcher-cross-stop.c',
320321
'test/test-multiple-listen.c',

0 commit comments

Comments
 (0)