[PATCH] unix: use libc-provided epoll_pwait wrapper
authorLuca Bruno <lucab@debian.org>
Tue, 12 May 2015 20:04:35 +0000 (22:04 +0200)
committerMattia Rizzolo <mattia@debian.org>
Sun, 23 Oct 2016 13:36:45 +0000 (14:36 +0100)
Bug-Debian: https://bugs.debian.org/841354

Signed-off-by: Luca Bruno <lucab@debian.org>
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
src/unix/linux-syscalls.c
src/unix/linux-syscalls.h

index b48a1111701753581d22582177821d59deb7df9a..6fb514f5ea3e5301931c41bca6f64e618ff9c2e3 100644 (file)
@@ -38,6 +38,7 @@
 #include <sys/prctl.h>
 #include <sys/sysinfo.h>
 #include <unistd.h>
+#include <signal.h>
 #include <fcntl.h>
 #include <time.h>
 
@@ -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();
 
index 89998ded26b17c67991eba2a86dfe3ad47dd8aec..d9114a893db2447f023bd88386584e12945dd07d 100644 (file)
@@ -22,6 +22,7 @@
 #include "linux-syscalls.h"
 #include <unistd.h>
 #include <signal.h>
+#include <sys/epoll.h>
 #include <sys/syscall.h>
 #include <sys/types.h>
 #include <errno.h>
@@ -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
index 4c095e9b5379968cba56f0efc66afbdf70b28d4e..0c747c4f37f7e108092f87a60ab337e863c4c557 100644 (file)
@@ -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);