Exemple #1
0
void grpc_pollset_kick(grpc_pollset *p, grpc_pollset_worker *specific_worker) {
  if (specific_worker != NULL) {
    if (specific_worker == GRPC_POLLSET_KICK_BROADCAST) {
      for (specific_worker = p->root_worker.next;
           specific_worker != &p->root_worker;
           specific_worker = specific_worker->next) {
        gpr_cv_signal(&specific_worker->cv);
      }
      p->kicked_without_pollers = 1;
    } else {
      gpr_cv_signal(&specific_worker->cv);
    }
  } else {
    specific_worker = pop_front_worker(p);
    if (specific_worker != NULL) {
      push_back_worker(p, specific_worker);
      gpr_cv_signal(&specific_worker->cv);
    } else {
      p->kicked_without_pollers = 1;
    }
  }
}
Exemple #2
0
void grpc_pollset_kick(grpc_pollset *p, grpc_pollset_worker *specific_worker) {
  if (specific_worker != NULL) {
    if (specific_worker == GRPC_POLLSET_KICK_BROADCAST) {
      for (specific_worker =
               p->root_worker.links[GRPC_POLLSET_WORKER_LINK_POLLSET].next;
           specific_worker != &p->root_worker;
           specific_worker =
               specific_worker->links[GRPC_POLLSET_WORKER_LINK_POLLSET].next) {
        specific_worker->kicked = 1;
        gpr_cv_signal(&specific_worker->cv);
      }
      p->kicked_without_pollers = 1;
      if (p->is_iocp_worker) {
        grpc_iocp_kick();
      }
    } else {
      if (p->is_iocp_worker) {
        if (g_active_poller == specific_worker) {
          grpc_iocp_kick();
        }
      } else {
        specific_worker->kicked = 1;
        gpr_cv_signal(&specific_worker->cv);
      }
    }
  } else {
    specific_worker =
        pop_front_worker(&p->root_worker, GRPC_POLLSET_WORKER_LINK_POLLSET);
    if (specific_worker != NULL) {
      grpc_pollset_kick(p, specific_worker);
    } else if (p->is_iocp_worker) {
      grpc_iocp_kick();
    } else {
      p->kicked_without_pollers = 1;
    }
  }
}
Exemple #3
0
void grpc_pollset_kick(grpc_pollset *p, grpc_pollset_worker *specific_worker) {
  /* pollset->mu already held */
  if (specific_worker != NULL) {
    if (specific_worker == GRPC_POLLSET_KICK_BROADCAST) {
      for (specific_worker = p->root_worker.next;
           specific_worker != &p->root_worker;
           specific_worker = specific_worker->next) {
        grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd);
      }
      p->kicked_without_pollers = 1;
    } else if (gpr_tls_get(&g_current_thread_worker) !=
               (gpr_intptr)specific_worker) {
      grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd);
    }
  } else if (gpr_tls_get(&g_current_thread_poller) != (gpr_intptr)p) {
    specific_worker = pop_front_worker(p);
    if (specific_worker != NULL) {
      push_back_worker(p, specific_worker);
      grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd);
    } else {
      p->kicked_without_pollers = 1;
    }
  }
}
Exemple #4
0
void grpc_pollset_kick_ext(grpc_pollset *p,
                           grpc_pollset_worker *specific_worker,
                           uint32_t flags) {
    GPR_TIMER_BEGIN("grpc_pollset_kick_ext", 0);

    /* pollset->mu already held */
    if (specific_worker != NULL) {
        if (specific_worker == GRPC_POLLSET_KICK_BROADCAST) {
            GPR_TIMER_BEGIN("grpc_pollset_kick_ext.broadcast", 0);
            GPR_ASSERT((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) == 0);
            for (specific_worker = p->root_worker.next;
                    specific_worker != &p->root_worker;
                    specific_worker = specific_worker->next) {
                grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd);
            }
            p->kicked_without_pollers = 1;
            GPR_TIMER_END("grpc_pollset_kick_ext.broadcast", 0);
        } else if (gpr_tls_get(&g_current_thread_worker) !=
                   (intptr_t)specific_worker) {
            GPR_TIMER_MARK("different_thread_worker", 0);
            if ((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) != 0) {
                specific_worker->reevaluate_polling_on_wakeup = 1;
            }
            specific_worker->kicked_specifically = 1;
            grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd);
        } else if ((flags & GRPC_POLLSET_CAN_KICK_SELF) != 0) {
            GPR_TIMER_MARK("kick_yoself", 0);
            if ((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) != 0) {
                specific_worker->reevaluate_polling_on_wakeup = 1;
            }
            specific_worker->kicked_specifically = 1;
            grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd);
        }
    } else if (gpr_tls_get(&g_current_thread_poller) != (intptr_t)p) {
        GPR_ASSERT((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) == 0);
        GPR_TIMER_MARK("kick_anonymous", 0);
        specific_worker = pop_front_worker(p);
        if (specific_worker != NULL) {
            if (gpr_tls_get(&g_current_thread_worker) == (intptr_t)specific_worker) {
                GPR_TIMER_MARK("kick_anonymous_not_self", 0);
                push_back_worker(p, specific_worker);
                specific_worker = pop_front_worker(p);
                if ((flags & GRPC_POLLSET_CAN_KICK_SELF) == 0 &&
                        gpr_tls_get(&g_current_thread_worker) ==
                        (intptr_t)specific_worker) {
                    push_back_worker(p, specific_worker);
                    specific_worker = NULL;
                }
            }
            if (specific_worker != NULL) {
                GPR_TIMER_MARK("finally_kick", 0);
                push_back_worker(p, specific_worker);
                grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd);
            }
        } else {
            GPR_TIMER_MARK("kicked_no_pollers", 0);
            p->kicked_without_pollers = 1;
        }
    }

    GPR_TIMER_END("grpc_pollset_kick_ext", 0);
}
Exemple #5
0
void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
                       grpc_pollset_worker *worker, gpr_timespec now,
                       gpr_timespec deadline) {
  int added_worker = 0;
  worker->links[GRPC_POLLSET_WORKER_LINK_POLLSET].next =
      worker->links[GRPC_POLLSET_WORKER_LINK_POLLSET].prev =
          worker->links[GRPC_POLLSET_WORKER_LINK_GLOBAL].next =
              worker->links[GRPC_POLLSET_WORKER_LINK_GLOBAL].prev = NULL;
  worker->kicked = 0;
  worker->pollset = pollset;
  gpr_cv_init(&worker->cv);
  if (grpc_timer_check(exec_ctx, now, &deadline)) {
    goto done;
  }
  if (!pollset->kicked_without_pollers && !pollset->shutting_down) {
    if (g_active_poller == NULL) {
      grpc_pollset_worker *next_worker;
      /* become poller */
      pollset->is_iocp_worker = 1;
      g_active_poller = worker;
      gpr_mu_unlock(&grpc_polling_mu);
      grpc_iocp_work(exec_ctx, deadline);
      grpc_exec_ctx_flush(exec_ctx);
      gpr_mu_lock(&grpc_polling_mu);
      pollset->is_iocp_worker = 0;
      g_active_poller = NULL;
      /* try to get a worker from this pollsets worker list */
      next_worker = pop_front_worker(&pollset->root_worker,
                                     GRPC_POLLSET_WORKER_LINK_POLLSET);
      if (next_worker == NULL) {
        /* try to get a worker from the global list */
        next_worker = pop_front_worker(&g_global_root_worker,
                                       GRPC_POLLSET_WORKER_LINK_GLOBAL);
      }
      if (next_worker != NULL) {
        next_worker->kicked = 1;
        gpr_cv_signal(&next_worker->cv);
      }

      if (pollset->shutting_down && pollset->on_shutdown != NULL) {
        grpc_exec_ctx_enqueue(exec_ctx, pollset->on_shutdown, 1);
        pollset->on_shutdown = NULL;
      }
      goto done;
    }
    push_front_worker(&g_global_root_worker, GRPC_POLLSET_WORKER_LINK_GLOBAL,
                      worker);
    push_front_worker(&pollset->root_worker, GRPC_POLLSET_WORKER_LINK_POLLSET,
                      worker);
    added_worker = 1;
    while (!worker->kicked) {
      if (gpr_cv_wait(&worker->cv, &grpc_polling_mu, deadline)) {
        break;
      }
    }
  } else {
    pollset->kicked_without_pollers = 0;
  }
done:
  if (!grpc_closure_list_empty(exec_ctx->closure_list)) {
    gpr_mu_unlock(&grpc_polling_mu);
    grpc_exec_ctx_flush(exec_ctx);
    gpr_mu_lock(&grpc_polling_mu);
  }
  if (added_worker) {
    remove_worker(worker, GRPC_POLLSET_WORKER_LINK_GLOBAL);
    remove_worker(worker, GRPC_POLLSET_WORKER_LINK_POLLSET);
  }
  gpr_cv_destroy(&worker->cv);
}