From 96e35edc16deeb71cae3e4b72063a96e57faf82e Mon Sep 17 00:00:00 2001 From: Luca Bruno Date: Tue, 12 May 2015 22:04:35 +0200 Subject: [PATCH] [PATCH] unix: use libc-provided epoll_pwait wrapper Bug-Debian: https://bugs.debian.org/841354 Signed-off-by: Luca Bruno We now use epoll_pwait() wrapper from libc, which takes care of passing proper sigset_t size to kernel. This is more portable, as some arch have a larger sigmask and kernel explicitely checks size parameter to match sizeof(sigset_t). Spotted as a uv_loop_configure regression on MIPS. This fixes #335. Many thanks to Tobias Leich who amended this patch to fix #841354 Gbp-Pq: Name mips-epoll_pwait.diff --- src/unix/linux-core.c | 17 +++++++++-------- src/unix/linux-syscalls.c | 21 +++++++-------------- src/unix/linux-syscalls.h | 2 +- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/unix/linux-core.c b/src/unix/linux-core.c index b48a111..6fb514f 100644 --- a/src/unix/linux-core.c +++ b/src/unix/linux-core.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -186,8 +187,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { QUEUE* q; uv__io_t* w; sigset_t sigset; - uint64_t sigmask; uint64_t base; + int is_sigmasked; int have_signals; int nevents; int count; @@ -236,11 +237,11 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { w->events = w->pevents; } - sigmask = 0; + is_sigmasked = 0; + sigemptyset(&sigset); if (loop->flags & UV_LOOP_BLOCK_SIGPROF) { - sigemptyset(&sigset); sigaddset(&sigset, SIGPROF); - sigmask |= 1 << (SIGPROF - 1); + is_sigmasked = 1; } assert(timeout >= -1); @@ -255,16 +256,16 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout) timeout = max_safe_timeout; - if (sigmask != 0 && no_epoll_pwait != 0) + if (is_sigmasked != 0 && no_epoll_pwait != 0) if (pthread_sigmask(SIG_BLOCK, &sigset, NULL)) abort(); - if (no_epoll_wait != 0 || (sigmask != 0 && no_epoll_pwait == 0)) { + if (no_epoll_wait != 0 || (is_sigmasked != 0 && no_epoll_pwait == 0)) { nfds = uv__epoll_pwait(loop->backend_fd, events, ARRAY_SIZE(events), timeout, - sigmask); + &sigset); if (nfds == -1 && errno == ENOSYS) no_epoll_pwait = 1; } else { @@ -276,7 +277,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { no_epoll_wait = 1; } - if (sigmask != 0 && no_epoll_pwait != 0) + if (is_sigmasked != 0 && no_epoll_pwait != 0) if (pthread_sigmask(SIG_UNBLOCK, &sigset, NULL)) abort(); diff --git a/src/unix/linux-syscalls.c b/src/unix/linux-syscalls.c index 89998de..d9114a8 100644 --- a/src/unix/linux-syscalls.c +++ b/src/unix/linux-syscalls.c @@ -22,6 +22,7 @@ #include "linux-syscalls.h" #include #include +#include #include #include #include @@ -334,21 +335,13 @@ int uv__epoll_pwait(int epfd, struct uv__epoll_event* events, int nevents, int timeout, - uint64_t sigmask) { + const sigset_t* sigmask) { #if defined(__NR_epoll_pwait) - int result; - result = syscall(__NR_epoll_pwait, - epfd, - events, - nevents, - timeout, - &sigmask, - sizeof(sigmask)); -#if MSAN_ACTIVE - if (result > 0) - __msan_unpoison(events, sizeof(events[0]) * result); -#endif - return result; + return epoll_pwait(epfd, + (struct epoll_event *) events, + nevents, + timeout, + sigmask); #else return errno = ENOSYS, -1; #endif diff --git a/src/unix/linux-syscalls.h b/src/unix/linux-syscalls.h index 4c095e9..0c747c4 100644 --- a/src/unix/linux-syscalls.h +++ b/src/unix/linux-syscalls.h @@ -124,7 +124,7 @@ int uv__epoll_pwait(int epfd, struct uv__epoll_event* events, int nevents, int timeout, - uint64_t sigmask); + const sigset_t* sigmask); int uv__eventfd2(unsigned int count, int flags); int uv__inotify_init(void); int uv__inotify_init1(int flags); -- 2.30.2