|
|
|
@ -33,7 +33,7 @@ |
|
|
|
|
|
|
|
|
|
#include <grpc/support/port_platform.h> |
|
|
|
|
|
|
|
|
|
#ifdef GPR_POSIX_SOCKET |
|
|
|
|
#ifdef GPR_LINUX_EPOLL |
|
|
|
|
|
|
|
|
|
#include "src/core/lib/iomgr/ev_epoll_linux.h" |
|
|
|
|
|
|
|
|
@ -60,6 +60,8 @@ |
|
|
|
|
|
|
|
|
|
struct polling_island; |
|
|
|
|
|
|
|
|
|
static int grpc_poller_kick_signum; |
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
|
* Fd Declarations |
|
|
|
|
*/ |
|
|
|
@ -92,6 +94,9 @@ struct grpc_fd { |
|
|
|
|
struct grpc_fd *freelist_next; |
|
|
|
|
grpc_closure *on_done_closure; |
|
|
|
|
|
|
|
|
|
/* The pollset that last noticed that the fd is readable */ |
|
|
|
|
grpc_pollset *read_notifier_pollset; |
|
|
|
|
|
|
|
|
|
grpc_iomgr_object iomgr_object; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
@ -650,14 +655,15 @@ static grpc_fd *fd_create(int fd, const char *name) { |
|
|
|
|
gpr_mu_lock(&new_fd->mu); |
|
|
|
|
|
|
|
|
|
gpr_atm_rel_store(&new_fd->refst, 1); |
|
|
|
|
new_fd->fd = fd; |
|
|
|
|
new_fd->shutdown = false; |
|
|
|
|
new_fd->orphaned = false; |
|
|
|
|
new_fd->read_closure = CLOSURE_NOT_READY; |
|
|
|
|
new_fd->write_closure = CLOSURE_NOT_READY; |
|
|
|
|
new_fd->fd = fd; |
|
|
|
|
new_fd->polling_island = NULL; |
|
|
|
|
new_fd->freelist_next = NULL; |
|
|
|
|
new_fd->on_done_closure = NULL; |
|
|
|
|
new_fd->orphaned = false; |
|
|
|
|
new_fd->read_notifier_pollset = NULL; |
|
|
|
|
|
|
|
|
|
gpr_mu_unlock(&new_fd->mu); |
|
|
|
|
|
|
|
|
@ -765,6 +771,17 @@ static int set_ready_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static grpc_pollset *fd_get_read_notifier_pollset(grpc_exec_ctx *exec_ctx, |
|
|
|
|
grpc_fd *fd) { |
|
|
|
|
grpc_pollset *notifier = NULL; |
|
|
|
|
|
|
|
|
|
gpr_mu_lock(&fd->mu); |
|
|
|
|
notifier = fd->read_notifier_pollset; |
|
|
|
|
gpr_mu_unlock(&fd->mu); |
|
|
|
|
|
|
|
|
|
return notifier; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd) { |
|
|
|
|
gpr_mu_lock(&fd->mu); |
|
|
|
|
GPR_ASSERT(!fd->shutdown); |
|
|
|
@ -801,16 +818,25 @@ static void sig_handler(int sig_num) { |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void poller_kick_init() { |
|
|
|
|
grpc_poller_kick_signum = SIGRTMIN + 2; |
|
|
|
|
signal(grpc_poller_kick_signum, sig_handler); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Global state management */ |
|
|
|
|
static void pollset_global_init(void) { |
|
|
|
|
grpc_wakeup_fd_init(&grpc_global_wakeup_fd); |
|
|
|
|
signal(SIGUSR1, sig_handler); /* TODO: sreek - Do not hardcode SIGUSR1 */ |
|
|
|
|
poller_kick_init(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void pollset_global_shutdown(void) { |
|
|
|
|
grpc_wakeup_fd_destroy(&grpc_global_wakeup_fd); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void pollset_worker_kick(grpc_pollset_worker *worker) { |
|
|
|
|
pthread_kill(worker->pt_id, grpc_poller_kick_signum); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Return 1 if the pollset has active threads in pollset_work (pollset must
|
|
|
|
|
* be locked) */ |
|
|
|
|
static int pollset_has_workers(grpc_pollset *p) { |
|
|
|
@ -856,7 +882,7 @@ static void pollset_kick(grpc_pollset *p, |
|
|
|
|
GPR_TIMER_BEGIN("pollset_kick.broadcast", 0); |
|
|
|
|
for (worker = p->root_worker.next; worker != &p->root_worker; |
|
|
|
|
worker = worker->next) { |
|
|
|
|
pthread_kill(worker->pt_id, SIGUSR1); |
|
|
|
|
pollset_worker_kick(worker); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
p->kicked_without_pollers = true; |
|
|
|
@ -864,7 +890,7 @@ static void pollset_kick(grpc_pollset *p, |
|
|
|
|
GPR_TIMER_END("pollset_kick.broadcast", 0); |
|
|
|
|
} else { |
|
|
|
|
GPR_TIMER_MARK("kicked_specifically", 0); |
|
|
|
|
pthread_kill(worker->pt_id, SIGUSR1); |
|
|
|
|
pollset_worker_kick(worker); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
GPR_TIMER_MARK("kick_anonymous", 0); |
|
|
|
@ -872,7 +898,7 @@ static void pollset_kick(grpc_pollset *p, |
|
|
|
|
if (worker != NULL) { |
|
|
|
|
GPR_TIMER_MARK("finally_kick", 0); |
|
|
|
|
push_back_worker(p, worker); |
|
|
|
|
pthread_kill(worker->pt_id, SIGUSR1); |
|
|
|
|
pollset_worker_kick(worker); |
|
|
|
|
} else { |
|
|
|
|
GPR_TIMER_MARK("kicked_no_pollers", 0); |
|
|
|
|
p->kicked_without_pollers = true; |
|
|
|
@ -924,20 +950,20 @@ static int poll_deadline_to_millis_timeout(gpr_timespec deadline, |
|
|
|
|
timeout, gpr_time_from_nanos(GPR_NS_PER_MS - 1, GPR_TIMESPAN))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void set_ready(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure **st) { |
|
|
|
|
/* only one set_ready can be active at once (but there may be a racing
|
|
|
|
|
notify_on) */ |
|
|
|
|
static void fd_become_readable(grpc_exec_ctx *exec_ctx, grpc_fd *fd, |
|
|
|
|
grpc_pollset *notifier) { |
|
|
|
|
/* Need the fd->mu since we might be racing with fd_notify_on_read */ |
|
|
|
|
gpr_mu_lock(&fd->mu); |
|
|
|
|
set_ready_locked(exec_ctx, fd, st); |
|
|
|
|
set_ready_locked(exec_ctx, fd, &fd->read_closure); |
|
|
|
|
fd->read_notifier_pollset = notifier; |
|
|
|
|
gpr_mu_unlock(&fd->mu); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void fd_become_readable(grpc_exec_ctx *exec_ctx, grpc_fd *fd) { |
|
|
|
|
set_ready(exec_ctx, fd, &fd->read_closure); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void fd_become_writable(grpc_exec_ctx *exec_ctx, grpc_fd *fd) { |
|
|
|
|
set_ready(exec_ctx, fd, &fd->write_closure); |
|
|
|
|
/* Need the fd->mu since we might be racing with fd_notify_on_write */ |
|
|
|
|
gpr_mu_lock(&fd->mu); |
|
|
|
|
set_ready_locked(exec_ctx, fd, &fd->write_closure); |
|
|
|
|
gpr_mu_unlock(&fd->mu); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define GRPC_EPOLL_MAX_EVENTS 1000 |
|
|
|
@ -1007,7 +1033,7 @@ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx, |
|
|
|
|
grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd); |
|
|
|
|
} else { |
|
|
|
|
if (read_ev || cancel) { |
|
|
|
|
fd_become_readable(exec_ctx, fd); |
|
|
|
|
fd_become_readable(exec_ctx, fd, pollset); |
|
|
|
|
} |
|
|
|
|
if (write_ev || cancel) { |
|
|
|
|
fd_become_writable(exec_ctx, fd); |
|
|
|
@ -1109,9 +1135,9 @@ static void pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, |
|
|
|
|
pollset->kicked_without_pollers = 0; |
|
|
|
|
} else if (!pollset->shutting_down) { |
|
|
|
|
sigemptyset(&new_mask); |
|
|
|
|
sigaddset(&new_mask, SIGUSR1); |
|
|
|
|
sigaddset(&new_mask, grpc_poller_kick_signum); |
|
|
|
|
pthread_sigmask(SIG_BLOCK, &new_mask, &orig_mask); |
|
|
|
|
sigdelset(&orig_mask, SIGUSR1); |
|
|
|
|
sigdelset(&orig_mask, grpc_poller_kick_signum); |
|
|
|
|
|
|
|
|
|
push_front_worker(pollset, &worker); |
|
|
|
|
|
|
|
|
@ -1350,6 +1376,7 @@ static const grpc_event_engine_vtable vtable = { |
|
|
|
|
.fd_shutdown = fd_shutdown, |
|
|
|
|
.fd_notify_on_read = fd_notify_on_read, |
|
|
|
|
.fd_notify_on_write = fd_notify_on_write, |
|
|
|
|
.fd_get_read_notifier_pollset = fd_get_read_notifier_pollset, |
|
|
|
|
|
|
|
|
|
.pollset_init = pollset_init, |
|
|
|
|
.pollset_shutdown = pollset_shutdown, |
|
|
|
@ -1380,4 +1407,9 @@ const grpc_event_engine_vtable *grpc_init_epoll_linux(void) { |
|
|
|
|
return &vtable; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
|
#else /* defined(GPR_LINUX_EPOLL) */ |
|
|
|
|
/* 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_LINUX_EPOLL) */ |
|
|
|
|