|
|
|
@ -42,6 +42,7 @@ |
|
|
|
|
#include <poll.h> |
|
|
|
|
#include <signal.h> |
|
|
|
|
#include <string.h> |
|
|
|
|
#include <sys/epoll.h> |
|
|
|
|
#include <sys/socket.h> |
|
|
|
|
#include <unistd.h> |
|
|
|
|
|
|
|
|
@ -51,11 +52,13 @@ |
|
|
|
|
#include <grpc/support/tls.h> |
|
|
|
|
#include <grpc/support/useful.h> |
|
|
|
|
|
|
|
|
|
#include "src/core/lib/iomgr/ev_posix.h" |
|
|
|
|
#include "src/core/lib/iomgr/iomgr_internal.h" |
|
|
|
|
#include "src/core/lib/iomgr/wakeup_fd_posix.h" |
|
|
|
|
#include "src/core/lib/profiling/timers.h" |
|
|
|
|
#include "src/core/lib/support/block_annotate.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
|
* FD declarations |
|
|
|
|
*/ |
|
|
|
@ -133,10 +136,9 @@ struct grpc_pollset { |
|
|
|
|
int called_shutdown; |
|
|
|
|
int kicked_without_pollers; |
|
|
|
|
grpc_closure *shutdown_done; |
|
|
|
|
union { |
|
|
|
|
int fd; |
|
|
|
|
void *ptr; |
|
|
|
|
} data; |
|
|
|
|
|
|
|
|
|
int epoll_fd; |
|
|
|
|
|
|
|
|
|
/* Local cache of eventfds for workers */ |
|
|
|
|
grpc_cached_wakeup_fd *local_wakeup_cache; |
|
|
|
|
}; |
|
|
|
@ -589,7 +591,6 @@ static void pollset_init(grpc_pollset *pollset, gpr_mu **mu) { |
|
|
|
|
pollset->local_wakeup_cache = NULL; |
|
|
|
|
pollset->kicked_without_pollers = 0; |
|
|
|
|
|
|
|
|
|
pollset->data.ptr = NULL; |
|
|
|
|
multipoll_with_epoll_pollset_create_efd(pollset); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -619,22 +620,6 @@ static void pollset_reset(grpc_pollset *pollset) { |
|
|
|
|
pollset->kicked_without_pollers = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* TODO (sreek): Remove multipoll_with_epoll_add_fd declaration*/ |
|
|
|
|
static void multipoll_with_epoll_pollset_add_fd(grpc_exec_ctx *exec_ctx, |
|
|
|
|
grpc_pollset *pollset, |
|
|
|
|
grpc_fd *fd); |
|
|
|
|
|
|
|
|
|
static void pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, |
|
|
|
|
grpc_fd *fd) { |
|
|
|
|
/* TODO (sreek) - Does reading pollset->data.ptr need pollset->mu lock ?
|
|
|
|
|
* because finally_add_fd() also reads it but without the lock! */ |
|
|
|
|
gpr_mu_lock(&pollset->mu); |
|
|
|
|
GPR_ASSERT(pollset->data.ptr != NULL); |
|
|
|
|
gpr_mu_unlock(&pollset->mu); |
|
|
|
|
|
|
|
|
|
multipoll_with_epoll_pollset_add_fd(exec_ctx, pollset, fd); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* TODO (sreek): Remove multipoll_with_epoll_finish_shutdown() declaration */ |
|
|
|
|
static void multipoll_with_epoll_pollset_finish_shutdown(grpc_pollset *pollset); |
|
|
|
|
|
|
|
|
@ -790,20 +775,6 @@ static int poll_deadline_to_millis_timeout(gpr_timespec deadline, |
|
|
|
|
* pollset_multipoller_with_epoll_posix.c |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#include <errno.h> |
|
|
|
|
#include <poll.h> |
|
|
|
|
#include <string.h> |
|
|
|
|
#include <sys/epoll.h> |
|
|
|
|
#include <unistd.h> |
|
|
|
|
|
|
|
|
|
#include <grpc/support/alloc.h> |
|
|
|
|
#include <grpc/support/log.h> |
|
|
|
|
#include <grpc/support/useful.h> |
|
|
|
|
|
|
|
|
|
#include "src/core/lib/iomgr/ev_posix.h" |
|
|
|
|
#include "src/core/lib/profiling/timers.h" |
|
|
|
|
#include "src/core/lib/support/block_annotate.h" |
|
|
|
|
|
|
|
|
|
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) */ |
|
|
|
@ -879,13 +850,13 @@ static void remove_fd_from_all_epoll_sets(int fd) { |
|
|
|
|
gpr_mu_unlock(&epoll_fd_list_mu); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
typedef struct { int epoll_fd; } epoll_hdr; |
|
|
|
|
|
|
|
|
|
static void finally_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, |
|
|
|
|
/* TODO: sreek - This function multipoll_with_epoll_pollset_add_fd() and
|
|
|
|
|
* finally_add_fd() in ev_poll_and_epoll_posix.c */ |
|
|
|
|
static void pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, |
|
|
|
|
grpc_fd *fd) { |
|
|
|
|
/*TODO: (sree) Shouldn't this read (pollset->data.ptr) be done under a
|
|
|
|
|
pollset lock - i.e pollset->mu ? */ |
|
|
|
|
epoll_hdr *h = pollset->data.ptr; |
|
|
|
|
|
|
|
|
|
/* TODO sreek - Check if we need to get a pollset->mu lock here */ |
|
|
|
|
|
|
|
|
|
struct epoll_event ev; |
|
|
|
|
int err; |
|
|
|
|
|
|
|
|
@ -908,7 +879,7 @@ static void finally_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, |
|
|
|
|
|
|
|
|
|
ev.events = (uint32_t)(EPOLLIN | EPOLLOUT | EPOLLET); |
|
|
|
|
ev.data.ptr = fd; |
|
|
|
|
err = epoll_ctl(h->epoll_fd, EPOLL_CTL_ADD, fd->fd, &ev); |
|
|
|
|
err = epoll_ctl(pollset->epoll_fd, EPOLL_CTL_ADD, fd->fd, &ev); |
|
|
|
|
if (err < 0) { |
|
|
|
|
/* FDs may be added to a pollset multiple times, so EEXIST is normal. */ |
|
|
|
|
if (errno != EEXIST) { |
|
|
|
@ -933,26 +904,20 @@ static void finally_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, |
|
|
|
|
/* TODO: This has to be called ONLY from pollset_init function. and hence it
|
|
|
|
|
* does not acquire any lock */ |
|
|
|
|
static void multipoll_with_epoll_pollset_create_efd(grpc_pollset *pollset) { |
|
|
|
|
epoll_hdr *h = gpr_malloc(sizeof(epoll_hdr)); |
|
|
|
|
struct epoll_event ev; |
|
|
|
|
int err; |
|
|
|
|
|
|
|
|
|
/* TODO (sreek). remove this assert. Currently added this just to ensure that
|
|
|
|
|
* we do not overwrite h->epoll_fd without freeing the older one*/ |
|
|
|
|
GPR_ASSERT(pollset->data.ptr == NULL); |
|
|
|
|
|
|
|
|
|
pollset->data.ptr = h; |
|
|
|
|
h->epoll_fd = epoll_create1(EPOLL_CLOEXEC); |
|
|
|
|
if (h->epoll_fd < 0) { |
|
|
|
|
pollset->epoll_fd = epoll_create1(EPOLL_CLOEXEC); |
|
|
|
|
if (pollset->epoll_fd < 0) { |
|
|
|
|
gpr_log(GPR_ERROR, "epoll_create1 failed: %s", strerror(errno)); |
|
|
|
|
abort(); |
|
|
|
|
} |
|
|
|
|
add_epoll_fd_to_global_list(h->epoll_fd); |
|
|
|
|
add_epoll_fd_to_global_list(pollset->epoll_fd); |
|
|
|
|
|
|
|
|
|
ev.events = (uint32_t)(EPOLLIN | EPOLLET); |
|
|
|
|
ev.data.ptr = NULL; |
|
|
|
|
|
|
|
|
|
err = epoll_ctl(h->epoll_fd, EPOLL_CTL_ADD, |
|
|
|
|
err = epoll_ctl(pollset->epoll_fd, EPOLL_CTL_ADD, |
|
|
|
|
GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd), &ev); |
|
|
|
|
if (err < 0) { |
|
|
|
|
gpr_log(GPR_ERROR, "epoll_ctl add for %d failed: %s", |
|
|
|
@ -961,12 +926,6 @@ static void multipoll_with_epoll_pollset_create_efd(grpc_pollset *pollset) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void multipoll_with_epoll_pollset_add_fd(grpc_exec_ctx *exec_ctx, |
|
|
|
|
grpc_pollset *pollset, |
|
|
|
|
grpc_fd *fd) { |
|
|
|
|
finally_add_fd(exec_ctx, pollset, fd); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* TODO(klempner): We probably want to turn this down a bit */ |
|
|
|
|
#define GRPC_EPOLL_MAX_EVENTS 1000 |
|
|
|
|
|
|
|
|
@ -974,9 +933,9 @@ static void multipoll_with_epoll_pollset_maybe_work_and_unlock( |
|
|
|
|
grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, grpc_pollset_worker *worker, |
|
|
|
|
gpr_timespec deadline, gpr_timespec now) { |
|
|
|
|
struct epoll_event ep_ev[GRPC_EPOLL_MAX_EVENTS]; |
|
|
|
|
int epoll_fd = pollset->epoll_fd; |
|
|
|
|
int ep_rv; |
|
|
|
|
int poll_rv; |
|
|
|
|
epoll_hdr *h = pollset->data.ptr; |
|
|
|
|
int timeout_ms; |
|
|
|
|
struct pollfd pfds[2]; |
|
|
|
|
|
|
|
|
@ -993,7 +952,7 @@ static void multipoll_with_epoll_pollset_maybe_work_and_unlock( |
|
|
|
|
pfds[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&worker->wakeup_fd->fd); |
|
|
|
|
pfds[0].events = POLLIN; |
|
|
|
|
pfds[0].revents = 0; |
|
|
|
|
pfds[1].fd = h->epoll_fd; |
|
|
|
|
pfds[1].fd = epoll_fd; |
|
|
|
|
pfds[1].events = POLLIN; |
|
|
|
|
pfds[1].revents = 0; |
|
|
|
|
|
|
|
|
@ -1018,7 +977,7 @@ static void multipoll_with_epoll_pollset_maybe_work_and_unlock( |
|
|
|
|
if (pfds[1].revents) { |
|
|
|
|
do { |
|
|
|
|
/* The following epoll_wait never blocks; it has a timeout of 0 */ |
|
|
|
|
ep_rv = epoll_wait(h->epoll_fd, ep_ev, GRPC_EPOLL_MAX_EVENTS, 0); |
|
|
|
|
ep_rv = epoll_wait(epoll_fd, ep_ev, GRPC_EPOLL_MAX_EVENTS, 0); |
|
|
|
|
if (ep_rv < 0) { |
|
|
|
|
if (errno != EINTR) { |
|
|
|
|
gpr_log(GPR_ERROR, "epoll_wait() failed: %s", strerror(errno)); |
|
|
|
@ -1053,10 +1012,8 @@ static void multipoll_with_epoll_pollset_finish_shutdown( |
|
|
|
|
grpc_pollset *pollset) {} |
|
|
|
|
|
|
|
|
|
static void multipoll_with_epoll_pollset_destroy(grpc_pollset *pollset) { |
|
|
|
|
epoll_hdr *h = pollset->data.ptr; |
|
|
|
|
close(h->epoll_fd); |
|
|
|
|
remove_epoll_fd_from_global_list(h->epoll_fd); |
|
|
|
|
gpr_free(h); |
|
|
|
|
close(pollset->epoll_fd); |
|
|
|
|
remove_epoll_fd_from_global_list(pollset->epoll_fd); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
|