Enable epoll on Python manylinux1

The Python packages built for Linux and uploaded to PyPI are required to
target a standardized platform specification dubbed `manylinux1`, which
tries to cover a vast array of Linux distributions, thereby emulating a
legacy lowest-common-denominator distribution, with an old `glibc` that
does not support `epoll_create1`, but provides the `epoll_create`
interface.  While there are race condition risks associated with
utilizing the latter interface and setting the `O_CLOEXEC` flag
immediately on the file descriptor returned by `epoll_create`, the
payoff is well worth the risks for our Python users, who currently end
up falling back on `poll` polling engine when downloading our Linux
binary packages.
pull/14041/head
Mehrdad Afshari 7 years ago
parent 4b0e885824
commit 1957fd0a84
  1. 26
      src/core/lib/iomgr/ev_epoll1_linux.cc
  2. 5
      src/core/lib/iomgr/port.h

@ -26,6 +26,7 @@
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <limits.h> #include <limits.h>
#include <poll.h> #include <poll.h>
#include <pthread.h> #include <pthread.h>
@ -84,11 +85,32 @@ typedef struct epoll_set {
/* The global singleton epoll set */ /* The global singleton epoll set */
static epoll_set g_epoll_set; static epoll_set g_epoll_set;
static int epoll_create_and_set_flag() {
#ifdef GRPC_LINUX_EPOLL_CREATE1
int fd = epoll_create1(EPOLL_CLOEXEC);
if (fd >= 0) {
return fd;
}
gpr_log(GPR_ERROR, "epoll_create1 unavailable");
return -1;
#else
int fd = epoll_create(MAX_EPOLL_EVENTS);
if (fd < 0) {
gpr_log(GPR_ERROR, "epoll_create unavailable");
return -1;
}
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == 0) {
return fd;
}
gpr_log(GPR_ERROR, "fcntl following epoll_create failed");
return -1;
#endif
}
/* Must be called *only* once */ /* Must be called *only* once */
static bool epoll_set_init() { static bool epoll_set_init() {
g_epoll_set.epfd = epoll_create1(EPOLL_CLOEXEC); g_epoll_set.epfd = epoll_create_and_set_flag();
if (g_epoll_set.epfd < 0) { if (g_epoll_set.epfd < 0) {
gpr_log(GPR_ERROR, "epoll unavailable");
return false; return false;
} }

@ -67,8 +67,11 @@
#define GRPC_POSIX_WAKEUP_FD 1 #define GRPC_POSIX_WAKEUP_FD 1
#define GRPC_TIMER_USE_GENERIC 1 #define GRPC_TIMER_USE_GENERIC 1
#ifdef __GLIBC_PREREQ #ifdef __GLIBC_PREREQ
#if __GLIBC_PREREQ(2, 9) #if __GLIBC_PREREQ(2, 4)
#define GRPC_LINUX_EPOLL 1 #define GRPC_LINUX_EPOLL 1
#endif
#if __GLIBC_PREREQ(2, 9)
#define GRPC_LINUX_EPOLL_CREATE1 1
#define GRPC_LINUX_EVENTFD 1 #define GRPC_LINUX_EVENTFD 1
#endif #endif
#if __GLIBC_PREREQ(2, 10) #if __GLIBC_PREREQ(2, 10)

Loading…
Cancel
Save