Merge pull request #13952 from vjpai/functional

Need to include functional to use std::bind
diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc
index 043ca9b..9a6f5e9 100644
--- a/src/core/ext/transport/chttp2/transport/writing.cc
+++ b/src/core/ext/transport/chttp2/transport/writing.cc
@@ -138,10 +138,11 @@
                          const char* staller) {
   gpr_log(
       GPR_DEBUG,
-      "%s:%p stream %d stalled by %s [fc:pending=%" PRIdPTR ":flowed=%" PRId64
+      "%s:%p stream %d stalled by %s [fc:pending=%" PRIdPTR
+      ":pending-compressed=%" PRIdPTR ":flowed=%" PRId64
       ":peer_initwin=%d:t_win=%" PRId64 ":s_win=%d:s_delta=%" PRId64 "]",
       t->peer_string, t, s->id, staller, s->flow_controlled_buffer.length,
-      s->flow_controlled_bytes_flowed,
+      s->compressed_data_buffer.length, s->flow_controlled_bytes_flowed,
       t->settings[GRPC_ACKED_SETTINGS]
                  [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE],
       t->flow_control->remote_window(),
diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc
index 5fa0201..08edff5 100644
--- a/src/core/lib/iomgr/ev_poll_posix.cc
+++ b/src/core/lib/iomgr/ev_poll_posix.cc
@@ -71,6 +71,7 @@
   int shutdown;
   int closed;
   int released;
+  gpr_atm pollhup;
   grpc_error* shutdown_error;
 
   /* The watcher list.
@@ -335,6 +336,7 @@
   r->on_done_closure = nullptr;
   r->closed = 0;
   r->released = 0;
+  gpr_atm_no_barrier_store(&r->pollhup, 0);
   r->read_notifier_pollset = nullptr;
 
   char* name2;
@@ -462,7 +464,7 @@
 
 static void notify_on_locked(grpc_fd* fd, grpc_closure** st,
                              grpc_closure* closure) {
-  if (fd->shutdown) {
+  if (fd->shutdown || gpr_atm_no_barrier_load(&fd->pollhup)) {
     GRPC_CLOSURE_SCHED(closure,
                        GRPC_ERROR_CREATE_FROM_STATIC_STRING("FD shutdown"));
   } else if (*st == CLOSURE_NOT_READY) {
@@ -950,7 +952,8 @@
       pfds[0].events = POLLIN;
       pfds[0].revents = 0;
       for (i = 0; i < pollset->fd_count; i++) {
-        if (fd_is_orphaned(pollset->fds[i])) {
+        if (fd_is_orphaned(pollset->fds[i]) ||
+            gpr_atm_no_barrier_load(&pollset->fds[i]->pollhup) == 1) {
           GRPC_FD_UNREF(pollset->fds[i], "multipoller");
         } else {
           pollset->fds[fd_count++] = pollset->fds[i];
@@ -1017,6 +1020,12 @@
                       pfds[i].fd, (pfds[i].revents & POLLIN_CHECK) != 0,
                       (pfds[i].revents & POLLOUT_CHECK) != 0, pfds[i].revents);
             }
+            /* This is a mitigation to prevent poll() from spinning on a
+             ** POLLHUP https://github.com/grpc/grpc/pull/13665
+             */
+            if (pfds[i].revents & POLLHUP) {
+              gpr_atm_no_barrier_store(&watchers[i].fd->pollhup, 1);
+            }
             fd_end_poll(&watchers[i], pfds[i].revents & POLLIN_CHECK,
                         pfds[i].revents & POLLOUT_CHECK, pollset);
           }