|
|
|
@ -236,6 +236,17 @@ static grpc_wakeup_fd polling_island_wakeup_fd; |
|
|
|
|
static gpr_mu g_pi_freelist_mu; |
|
|
|
|
static polling_island *g_pi_freelist = NULL; |
|
|
|
|
|
|
|
|
|
#ifdef _GRPC_TSAN |
|
|
|
|
/* Currently TSAN may incorrectly flag data races between epoll_ctl and
|
|
|
|
|
epoll_wait for any grpc_fd structs that are added to the epoll set via |
|
|
|
|
epoll_ctl and are returned (within a very short window) via epoll_wait(). |
|
|
|
|
|
|
|
|
|
To work-around this race, we establish a happens-before relation between |
|
|
|
|
the code just-before epoll_ctl() and the code after epoll_wait() by using |
|
|
|
|
this atomic */ |
|
|
|
|
gpr_atm g_epoll_sync; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/* The caller is expected to hold pi->mu lock before calling this function */ |
|
|
|
|
static void polling_island_add_fds_locked(polling_island *pi, grpc_fd **fds, |
|
|
|
|
size_t fd_count, bool add_fd_refs) { |
|
|
|
@ -243,6 +254,11 @@ static void polling_island_add_fds_locked(polling_island *pi, grpc_fd **fds, |
|
|
|
|
size_t i; |
|
|
|
|
struct epoll_event ev; |
|
|
|
|
|
|
|
|
|
#ifdef _GRPC_TSAN |
|
|
|
|
/* See the definition of g_epoll_sync for more context */ |
|
|
|
|
gpr_atm_rel_store(&g_epoll_sync, 0); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
for (i = 0; i < fd_count; i++) { |
|
|
|
|
ev.events = (uint32_t)(EPOLLIN | EPOLLOUT | EPOLLET); |
|
|
|
|
ev.data.ptr = fds[i]; |
|
|
|
@ -361,6 +377,7 @@ static polling_island *polling_island_create(grpc_fd *initial_fd, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pi->epoll_fd = epoll_create1(EPOLL_CLOEXEC); |
|
|
|
|
|
|
|
|
|
if (pi->epoll_fd < 0) { |
|
|
|
|
gpr_log(GPR_ERROR, "epoll_create1() failed with error: %s", |
|
|
|
|
strerror(errno)); |
|
|
|
@ -1144,6 +1161,11 @@ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef _GRPC_TSAN |
|
|
|
|
/* See the definition of g_poll_sync for more details */ |
|
|
|
|
gpr_atm_acq_load(&g_epoll_sync); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < ep_rv; ++i) { |
|
|
|
|
void *data_ptr = ep_ev[i].data.ptr; |
|
|
|
|
if (data_ptr == &grpc_global_wakeup_fd) { |
|
|
|
@ -1514,10 +1536,13 @@ const grpc_event_engine_vtable *grpc_init_epoll_linux(void) { |
|
|
|
|
return &vtable; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#else /* defined(GPR_LINUX_EPOLL) */ |
|
|
|
|
#else /* defined(GPR_LINUX_EPOLL) */ |
|
|
|
|
#if defined(GPR_POSIX_SOCKET) |
|
|
|
|
#include "src/core/lib/iomgr/ev_posix.h" |
|
|
|
|
/* If GPR_LINUX_EPOLL is not defined, it means epoll is not available. Return
|
|
|
|
|
* NULL */ |
|
|
|
|
const grpc_event_engine_vtable *grpc_init_epoll_linux(void) { return NULL; } |
|
|
|
|
#endif /* defined(GPR_POSIX_SOCKET) */ |
|
|
|
|
|
|
|
|
|
void grpc_use_signal(int signum) {} |
|
|
|
|
#endif /* !defined(GPR_LINUX_EPOLL) */ |
|
|
|
|