aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/iomgr/pollset_posix.c
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2015-05-28 13:39:15 -0700
committerGravatar Craig Tiller <ctiller@google.com>2015-05-28 13:39:15 -0700
commitaca6ea65c36efb1e89f9f5e0e1e245b33b03d0ca (patch)
treed3d6ccd9c9fde3286adaab1621e74db8947176a4 /src/core/iomgr/pollset_posix.c
parent390561874f33627d80640421f7e38fa1b9c89d1b (diff)
Empty pollset must be kickable.
We *may* want to merge the unary and empty cases here.
Diffstat (limited to 'src/core/iomgr/pollset_posix.c')
-rw-r--r--src/core/iomgr/pollset_posix.c49
1 files changed, 47 insertions, 2 deletions
diff --git a/src/core/iomgr/pollset_posix.c b/src/core/iomgr/pollset_posix.c
index e39b49bd3f..48111cc07b 100644
--- a/src/core/iomgr/pollset_posix.c
+++ b/src/core/iomgr/pollset_posix.c
@@ -192,8 +192,53 @@ static void empty_pollset_del_fd(grpc_pollset *pollset, grpc_fd *fd) {}
static int empty_pollset_maybe_work(grpc_pollset *pollset,
gpr_timespec deadline, gpr_timespec now,
int allow_synchronous_callback) {
- abort();
- return 0;
+ struct pollfd pfd;
+ int timeout;
+ int r;
+
+ if (pollset->in_flight_cbs) {
+ /* Give do_promote priority so we don't starve it out */
+ return 1;
+ }
+ if (gpr_time_cmp(deadline, gpr_inf_future) == 0) {
+ timeout = -1;
+ } else {
+ timeout = gpr_time_to_millis(gpr_time_sub(deadline, now));
+ if (timeout <= 0) {
+ return 1;
+ }
+ }
+ pfd.fd = grpc_pollset_kick_pre_poll(&pollset->kick_state);
+ if (pfd.fd < 0) {
+ /* Already kicked */
+ return 1;
+ }
+ pfd.events = POLLIN;
+ pfd.revents = 0;
+ pollset->counter++;
+ gpr_mu_unlock(&pollset->mu);
+
+ /* poll fd count (argument 2) is shortened by one if we have no events
+ to poll on - such that it only includes the kicker */
+ r = poll(&pfd, 1, timeout);
+
+ if (r < 0) {
+ if (errno != EINTR) {
+ gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno));
+ }
+ } else if (r == 0) {
+ /* do nothing */
+ } else {
+ if (pfd.revents & POLLIN) {
+ grpc_pollset_kick_consume(&pollset->kick_state);
+ }
+ }
+
+ grpc_pollset_kick_post_poll(&pollset->kick_state);
+
+ gpr_mu_lock(&pollset->mu);
+ pollset->counter--;
+ return 1;
}
static void empty_pollset_destroy(grpc_pollset *pollset) {}