void test_log_events(int num_seqs) { int start = 0; int *state; state = calloc(num_seqs, sizeof(state[0])); while (start < num_seqs) { int i; int row; if (state[start] == 3) { /* Already done with this posn */ start++; continue; } row = rand() % 10; /* how many in a row */ for (i = start; (i < start + row) && (i < num_seqs); i++) { int j; int advance = 1 + rand() % 3; /* how many to advance by */ for (j = 0; j < advance; j++) { switch (state[i]) { case 0: GRPC_TIMER_MARK(STATE_0, i); state[i]++; break; case 1: GRPC_TIMER_MARK(STATE_1, i); state[i]++; break; case 2: GRPC_TIMER_MARK(STATE_2, i); state[i]++; break; case 3: break; } } } } free(state); }
static void basic_pollset_maybe_work_and_unlock(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, grpc_pollset_worker *worker, gpr_timespec deadline, gpr_timespec now) { struct pollfd pfd[3]; grpc_fd *fd; grpc_fd_watcher fd_watcher; int timeout; int r; nfds_t nfds; fd = pollset->data.ptr; if (fd && grpc_fd_is_orphaned(fd)) { GRPC_FD_UNREF(fd, "basicpoll"); fd = pollset->data.ptr = NULL; } timeout = grpc_poll_deadline_to_millis_timeout(deadline, now); pfd[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd); pfd[0].events = POLLIN; pfd[0].revents = 0; pfd[1].fd = GRPC_WAKEUP_FD_GET_READ_FD(&worker->wakeup_fd); pfd[1].events = POLLIN; pfd[1].revents = 0; nfds = 2; if (fd) { pfd[2].fd = fd->fd; pfd[2].revents = 0; gpr_mu_unlock(&pollset->mu); pfd[2].events = (short)grpc_fd_begin_poll(fd, pollset, POLLIN, POLLOUT, &fd_watcher); if (pfd[2].events != 0) { nfds++; } } else { gpr_mu_unlock(&pollset->mu); } /* TODO(vpai): Consider first doing a 0 timeout poll here to avoid even going into the blocking annotation if possible */ /* poll fd count (argument 2) is shortened by one if we have no events to poll on - such that it only includes the kicker */ GRPC_SCHEDULING_START_BLOCKING_REGION; r = grpc_poll_function(pfd, nfds, timeout); GRPC_SCHEDULING_END_BLOCKING_REGION; GRPC_TIMER_MARK(GRPC_PTAG_POLL_FINISHED, r); if (fd) { grpc_fd_end_poll(exec_ctx, &fd_watcher, pfd[2].revents & POLLIN, pfd[2].revents & POLLOUT); } if (r < 0) { if (errno != EINTR) { gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno)); } } else if (r == 0) { /* do nothing */ } else { if (pfd[0].revents & POLLIN) { grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd); } if (pfd[1].revents & POLLIN) { grpc_wakeup_fd_consume_wakeup(&worker->wakeup_fd); } if (nfds > 2) { if (pfd[2].revents & (POLLIN | POLLHUP | POLLERR)) { grpc_fd_become_readable(exec_ctx, fd); } if (pfd[2].revents & (POLLOUT | POLLHUP | POLLERR)) { grpc_fd_become_writable(exec_ctx, fd); } } } }
static void basic_pollset_maybe_work(grpc_pollset *pollset, grpc_pollset_worker *worker, gpr_timespec deadline, gpr_timespec now, int allow_synchronous_callback) { struct pollfd pfd[2]; grpc_fd *fd; grpc_fd_watcher fd_watcher; int timeout; int r; nfds_t nfds; fd = pollset->data.ptr; if (fd && grpc_fd_is_orphaned(fd)) { GRPC_FD_UNREF(fd, "basicpoll"); fd = pollset->data.ptr = NULL; } timeout = grpc_poll_deadline_to_millis_timeout(deadline, now); pfd[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&worker->wakeup_fd); pfd[0].events = POLLIN; pfd[0].revents = 0; nfds = 1; if (fd) { pfd[1].fd = fd->fd; pfd[1].revents = 0; gpr_mu_unlock(&pollset->mu); pfd[1].events = (short)grpc_fd_begin_poll(fd, pollset, POLLIN, POLLOUT, &fd_watcher); if (pfd[1].events != 0) { nfds++; } } else { 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 = grpc_poll_function(pfd, nfds, timeout); GRPC_TIMER_MARK(GRPC_PTAG_POLL_FINISHED, r); if (fd) { grpc_fd_end_poll(&fd_watcher, pfd[1].revents & POLLIN, pfd[1].revents & POLLOUT); } if (r < 0) { if (errno != EINTR) { gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno)); } } else if (r == 0) { /* do nothing */ } else { if (pfd[0].revents & POLLIN) { grpc_wakeup_fd_consume_wakeup(&worker->wakeup_fd); } if (nfds > 1) { if (pfd[1].revents & (POLLIN | POLLHUP | POLLERR)) { grpc_fd_become_readable(fd, allow_synchronous_callback); } if (pfd[1].revents & (POLLOUT | POLLHUP | POLLERR)) { grpc_fd_become_writable(fd, allow_synchronous_callback); } } } gpr_mu_lock(&pollset->mu); }