|  | @@ -126,6 +126,9 @@ struct grpc_fd {
 | 
	
		
			
				|  |  |    grpc_closure *on_done_closure;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    grpc_iomgr_object iomgr_object;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /* The pollset that last noticed and notified that the fd is readable */
 | 
	
		
			
				|  |  | +  grpc_pollset *read_notifier_pollset;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /* Begin polling on an fd.
 | 
	
	
		
			
				|  | @@ -147,7 +150,8 @@ static uint32_t fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset,
 | 
	
		
			
				|  |  |     if got_read or got_write are 1, also does the become_{readable,writable} as
 | 
	
		
			
				|  |  |     appropriate. */
 | 
	
		
			
				|  |  |  static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *rec,
 | 
	
		
			
				|  |  | -                        int got_read, int got_write);
 | 
	
		
			
				|  |  | +                        int got_read, int got_write,
 | 
	
		
			
				|  |  | +                        grpc_pollset *read_notifier_pollset);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /* Return 1 if this fd is orphaned, 0 otherwise */
 | 
	
		
			
				|  |  |  static bool fd_is_orphaned(grpc_fd *fd);
 | 
	
	
		
			
				|  | @@ -342,6 +346,7 @@ static grpc_fd *alloc_fd(int fd) {
 | 
	
		
			
				|  |  |    r->on_done_closure = NULL;
 | 
	
		
			
				|  |  |    r->closed = 0;
 | 
	
		
			
				|  |  |    r->released = 0;
 | 
	
		
			
				|  |  | +  r->read_notifier_pollset = NULL;
 | 
	
		
			
				|  |  |    gpr_mu_unlock(&r->mu);
 | 
	
		
			
				|  |  |    return r;
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -545,6 +550,11 @@ static int set_ready_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +static void set_read_notifier_pollset_locked(
 | 
	
		
			
				|  |  | +    grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_pollset *read_notifier_pollset) {
 | 
	
		
			
				|  |  | +  fd->read_notifier_pollset = read_notifier_pollset;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  static void fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
 | 
	
		
			
				|  |  |    gpr_mu_lock(&fd->mu);
 | 
	
		
			
				|  |  |    GPR_ASSERT(!fd->shutdown);
 | 
	
	
		
			
				|  | @@ -568,6 +578,18 @@ static void fd_notify_on_write(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
 | 
	
		
			
				|  |  |    gpr_mu_unlock(&fd->mu);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +/* Return the read-notifier pollset */
 | 
	
		
			
				|  |  | +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 uint32_t fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset,
 | 
	
		
			
				|  |  |                                grpc_pollset_worker *worker, uint32_t read_mask,
 | 
	
		
			
				|  |  |                                uint32_t write_mask, grpc_fd_watcher *watcher) {
 | 
	
	
		
			
				|  | @@ -620,7 +642,8 @@ static uint32_t fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset,
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *watcher,
 | 
	
		
			
				|  |  | -                        int got_read, int got_write) {
 | 
	
		
			
				|  |  | +                        int got_read, int got_write,
 | 
	
		
			
				|  |  | +                        grpc_pollset *read_notifier_pollset) {
 | 
	
		
			
				|  |  |    int was_polling = 0;
 | 
	
		
			
				|  |  |    int kick = 0;
 | 
	
		
			
				|  |  |    grpc_fd *fd = watcher->fd;
 | 
	
	
		
			
				|  | @@ -656,6 +679,10 @@ static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *watcher,
 | 
	
		
			
				|  |  |      if (set_ready_locked(exec_ctx, fd, &fd->read_closure)) {
 | 
	
		
			
				|  |  |        kick = 1;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    if (read_notifier_pollset != NULL) {
 | 
	
		
			
				|  |  | +      set_read_notifier_pollset_locked(exec_ctx, fd, read_notifier_pollset);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    if (got_write) {
 | 
	
		
			
				|  |  |      if (set_ready_locked(exec_ctx, fd, &fd->write_closure)) {
 | 
	
	
		
			
				|  | @@ -756,9 +783,14 @@ static void pollset_kick_ext(grpc_pollset *p,
 | 
	
		
			
				|  |  |      specific_worker = pop_front_worker(p);
 | 
	
		
			
				|  |  |      if (specific_worker != NULL) {
 | 
	
		
			
				|  |  |        if (gpr_tls_get(&g_current_thread_worker) == (intptr_t)specific_worker) {
 | 
	
		
			
				|  |  | +        /* Prefer not to kick self. Push the worker to the end of the list and
 | 
	
		
			
				|  |  | +         * pop the one from front */
 | 
	
		
			
				|  |  |          GPR_TIMER_MARK("kick_anonymous_not_self", 0);
 | 
	
		
			
				|  |  |          push_back_worker(p, specific_worker);
 | 
	
		
			
				|  |  |          specific_worker = pop_front_worker(p);
 | 
	
		
			
				|  |  | +        /* If there was only one worker on the pollset, we would get the same
 | 
	
		
			
				|  |  | +         * worker we pushed (the one set on current thread local) back. If so,
 | 
	
		
			
				|  |  | +         * kick it only if GRPC_POLLSET_CAN_KICK_SELF flag is set */
 | 
	
		
			
				|  |  |          if ((flags & GRPC_POLLSET_CAN_KICK_SELF) == 0 &&
 | 
	
		
			
				|  |  |              gpr_tls_get(&g_current_thread_worker) ==
 | 
	
		
			
				|  |  |                  (intptr_t)specific_worker) {
 | 
	
	
		
			
				|  | @@ -1201,11 +1233,11 @@ static void basic_pollset_maybe_work_and_unlock(grpc_exec_ctx *exec_ctx,
 | 
	
		
			
				|  |  |        gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      if (fd) {
 | 
	
		
			
				|  |  | -      fd_end_poll(exec_ctx, &fd_watcher, 0, 0);
 | 
	
		
			
				|  |  | +      fd_end_poll(exec_ctx, &fd_watcher, 0, 0, NULL);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    } else if (r == 0) {
 | 
	
		
			
				|  |  |      if (fd) {
 | 
	
		
			
				|  |  | -      fd_end_poll(exec_ctx, &fd_watcher, 0, 0);
 | 
	
		
			
				|  |  | +      fd_end_poll(exec_ctx, &fd_watcher, 0, 0, NULL);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    } else {
 | 
	
		
			
				|  |  |      if (pfd[0].revents & POLLIN_CHECK) {
 | 
	
	
		
			
				|  | @@ -1216,9 +1248,9 @@ static void basic_pollset_maybe_work_and_unlock(grpc_exec_ctx *exec_ctx,
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      if (nfds > 2) {
 | 
	
		
			
				|  |  |        fd_end_poll(exec_ctx, &fd_watcher, pfd[2].revents & POLLIN_CHECK,
 | 
	
		
			
				|  |  | -                  pfd[2].revents & POLLOUT_CHECK);
 | 
	
		
			
				|  |  | +                  pfd[2].revents & POLLOUT_CHECK, pollset);
 | 
	
		
			
				|  |  |      } else if (fd) {
 | 
	
		
			
				|  |  | -      fd_end_poll(exec_ctx, &fd_watcher, 0, 0);
 | 
	
		
			
				|  |  | +      fd_end_poll(exec_ctx, &fd_watcher, 0, 0, NULL);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1354,11 +1386,11 @@ static void multipoll_with_poll_pollset_maybe_work_and_unlock(
 | 
	
		
			
				|  |  |        gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      for (i = 2; i < pfd_count; i++) {
 | 
	
		
			
				|  |  | -      fd_end_poll(exec_ctx, &watchers[i], 0, 0);
 | 
	
		
			
				|  |  | +      fd_end_poll(exec_ctx, &watchers[i], 0, 0, NULL);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    } else if (r == 0) {
 | 
	
		
			
				|  |  |      for (i = 2; i < pfd_count; i++) {
 | 
	
		
			
				|  |  | -      fd_end_poll(exec_ctx, &watchers[i], 0, 0);
 | 
	
		
			
				|  |  | +      fd_end_poll(exec_ctx, &watchers[i], 0, 0, NULL);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    } else {
 | 
	
		
			
				|  |  |      if (pfds[0].revents & POLLIN_CHECK) {
 | 
	
	
		
			
				|  | @@ -1369,11 +1401,11 @@ static void multipoll_with_poll_pollset_maybe_work_and_unlock(
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      for (i = 2; i < pfd_count; i++) {
 | 
	
		
			
				|  |  |        if (watchers[i].fd == NULL) {
 | 
	
		
			
				|  |  | -        fd_end_poll(exec_ctx, &watchers[i], 0, 0);
 | 
	
		
			
				|  |  | +        fd_end_poll(exec_ctx, &watchers[i], 0, 0, NULL);
 | 
	
		
			
				|  |  |          continue;
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |        fd_end_poll(exec_ctx, &watchers[i], pfds[i].revents & POLLIN_CHECK,
 | 
	
		
			
				|  |  | -                  pfds[i].revents & POLLOUT_CHECK);
 | 
	
		
			
				|  |  | +                  pfds[i].revents & POLLOUT_CHECK, pollset);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1449,20 +1481,31 @@ static void poll_become_multipoller(grpc_exec_ctx *exec_ctx,
 | 
	
		
			
				|  |  |  #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) {
 | 
	
		
			
				|  |  | +static void set_ready(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure **st,
 | 
	
		
			
				|  |  | +                      grpc_pollset *read_notifier_pollset) {
 | 
	
		
			
				|  |  |    /* only one set_ready can be active at once (but there may be a racing
 | 
	
		
			
				|  |  |       notify_on) */
 | 
	
		
			
				|  |  |    gpr_mu_lock(&fd->mu);
 | 
	
		
			
				|  |  |    set_ready_locked(exec_ctx, fd, st);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /* A non-NULL read_notifier_pollset means that the fd is readable. */
 | 
	
		
			
				|  |  | +  if (read_notifier_pollset != NULL) {
 | 
	
		
			
				|  |  | +    /* Note: Since the fd might be a part of multiple pollsets, this might be
 | 
	
		
			
				|  |  | +     * called multiple times (for each time the fd becomes readable) and it is
 | 
	
		
			
				|  |  | +     * okay to set the fd's read-notifier pollset to anyone of these pollsets */
 | 
	
		
			
				|  |  | +    set_read_notifier_pollset_locked(exec_ctx, fd, read_notifier_pollset);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    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_readable(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
 | 
	
		
			
				|  |  | +                               grpc_pollset *notifier_pollset) {
 | 
	
		
			
				|  |  | +  set_ready(exec_ctx, fd, &fd->read_closure, notifier_pollset);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void fd_become_writable(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
 | 
	
		
			
				|  |  | -  set_ready(exec_ctx, fd, &fd->write_closure);
 | 
	
		
			
				|  |  | +  set_ready(exec_ctx, fd, &fd->write_closure, NULL);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  struct epoll_fd_list {
 | 
	
	
		
			
				|  | @@ -1554,7 +1597,7 @@ static void finally_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  fd_end_poll(exec_ctx, &watcher, 0, 0);
 | 
	
		
			
				|  |  | +  fd_end_poll(exec_ctx, &watcher, 0, 0, NULL);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void perform_delayed_add(grpc_exec_ctx *exec_ctx, void *arg,
 | 
	
	
		
			
				|  | @@ -1668,7 +1711,7 @@ static void multipoll_with_epoll_pollset_maybe_work_and_unlock(
 | 
	
		
			
				|  |  |                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);
 | 
	
	
		
			
				|  | @@ -1897,6 +1940,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,
 |