From 556e5ae525c4fbcffaebc7f0f60b3f0192e3003a Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Mon, 16 May 2016 11:00:33 -0700
Subject: [PATCH] Fix accelerated wakeups

We can end up in situations where a pollset needs to kick itself.

This is supposed to be an accelerated codepath, however a bug crept in
whereby we missed the opportunity to do so, resulting in needing to
round trip these wakeups redundantly through the OS and wake other
threads unnecessarily.
---
 src/core/lib/iomgr/ev_poll_posix.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/core/lib/iomgr/ev_poll_posix.c b/src/core/lib/iomgr/ev_poll_posix.c
index d1752327a2..e91ae40212 100644
--- a/src/core/lib/iomgr/ev_poll_posix.c
+++ b/src/core/lib/iomgr/ev_poll_posix.c
@@ -824,6 +824,7 @@ static void pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
      re-evaluate our pollers (this allows poll() based pollers to
      ensure they don't miss wakeups) */
   keep_polling = 1;
+  gpr_tls_set(&g_current_thread_poller, (intptr_t)pollset);
   while (keep_polling) {
     keep_polling = 0;
     if (!pollset->kicked_without_pollers) {
@@ -832,7 +833,6 @@ static void pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
         added_worker = 1;
         gpr_tls_set(&g_current_thread_worker, (intptr_t)&worker);
       }
-      gpr_tls_set(&g_current_thread_poller, (intptr_t)pollset);
       GPR_TIMER_BEGIN("maybe_work_and_unlock", 0);
 #define POLLOUT_CHECK (POLLOUT | POLLHUP | POLLERR)
 #define POLLIN_CHECK (POLLIN | POLLHUP | POLLERR)
@@ -926,7 +926,6 @@ static void pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
       gpr_free(watchers);
       GPR_TIMER_END("maybe_work_and_unlock", 0);
       locked = 0;
-      gpr_tls_set(&g_current_thread_poller, 0);
     } else {
       GPR_TIMER_MARK("pollset_work.kicked_without_pollers", 0);
       pollset->kicked_without_pollers = 0;
@@ -958,6 +957,7 @@ static void pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
       now = gpr_now(now.clock_type);
     }
   }
+  gpr_tls_set(&g_current_thread_poller, 0);
   if (added_worker) {
     remove_worker(pollset, &worker);
     gpr_tls_set(&g_current_thread_worker, 0);
-- 
GitLab