33 #include <sys/types.h> 
   34 #ifdef HAVE_SYS_TIME_H 
   37 #include <sys/_time.h> 
   39 #include <sys/queue.h> 
   47 #ifdef CHECK_INVARIANTS 
   52 #include "event-internal.h" 
   60         struct pollfd *event_set;
 
   61         struct event **event_r_back;
 
   62         struct event **event_w_back;
 
   69 static int poll_add             (
void *, 
struct event *);
 
   70 static int poll_del             (
void *, 
struct event *);
 
   72 static void poll_dealloc        (
struct event_base *, 
void *);
 
   74 const struct eventop pollops = {
 
   90         if (getenv(
"EVENT_NOPOLL"))
 
   93         if (!(pollop = calloc(1, 
sizeof(
struct pollop))))
 
  101 #ifdef CHECK_INVARIANTS 
  103 poll_check_ok(
struct pollop *pop)
 
  108         for (i = 0; i < pop->fd_count; ++
i) {
 
  109                 idx = pop->idxplus1_by_fd[
i]-1;
 
  112                 assert(pop->event_set[idx].fd == i);
 
  113                 if (pop->event_set[idx].events & POLLIN) {
 
  114                         ev = pop->event_r_back[idx];
 
  116                         assert(ev->ev_events & EV_READ);
 
  117                         assert(ev->ev_fd == i);
 
  119                 if (pop->event_set[idx].events & POLLOUT) {
 
  120                         ev = pop->event_w_back[idx];
 
  122                         assert(ev->ev_events & EV_WRITE);
 
  123                         assert(ev->ev_fd == i);
 
  126         for (i = 0; i < pop->nfds; ++
i) {
 
  127                 struct pollfd *pfd = &pop->event_set[
i];
 
  128                 assert(pop->idxplus1_by_fd[pfd->fd] == i+1);
 
  132 #define poll_check_ok(pop) 
  138         int res, 
i, j, msec = -1, nfds;
 
  139         struct pollop *pop = arg;
 
  144                 msec = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
 
  147         res = poll(pop->event_set, nfds, msec);
 
  150                 if (errno != EINTR) {
 
  155                 evsignal_process(base);
 
  157         } 
else if (base->sig.evsignal_caught) {
 
  158                 evsignal_process(base);
 
  161         event_debug((
"%s: poll reports %d", __func__, res));
 
  163         if (res == 0 || nfds == 0)
 
  167         for (j = 0; j < nfds; j++) {
 
  168                 struct event *r_ev = NULL, *w_ev = NULL;
 
  172                 what = pop->event_set[
i].revents;
 
  180                 if (what & (POLLHUP|POLLERR))
 
  181                         what |= POLLIN|POLLOUT;
 
  184                         r_ev = pop->event_r_back[
i];
 
  186                 if (what & POLLOUT) {
 
  188                         w_ev = pop->event_w_back[
i];
 
  193                 if (r_ev && (res & r_ev->ev_events)) {
 
  194                         event_active(r_ev, res & r_ev->ev_events, 1);
 
  196                 if (w_ev && w_ev != r_ev && (res & w_ev->ev_events)) {
 
  197                         event_active(w_ev, res & w_ev->ev_events, 1);
 
  205 poll_add(
void *arg, 
struct event *ev)
 
  207         struct pollop *pop = arg;
 
  208         struct pollfd *pfd = NULL;
 
  211         if (ev->ev_events & EV_SIGNAL)
 
  212                 return (evsignal_add(ev));
 
  213         if (!(ev->ev_events & (EV_READ|EV_WRITE)))
 
  217         if (pop->nfds + 1 >= pop->event_count) {
 
  218                 struct pollfd *tmp_event_set;
 
  219                 struct event **tmp_event_r_back;
 
  220                 struct event **tmp_event_w_back;
 
  223                 if (pop->event_count < 32)
 
  224                         tmp_event_count = 32;
 
  226                         tmp_event_count = pop->event_count * 2;
 
  229                 tmp_event_set = realloc(pop->event_set,
 
  230                                  tmp_event_count * 
sizeof(
struct pollfd));
 
  231                 if (tmp_event_set == NULL) {
 
  232                         event_warn(
"realloc");
 
  235                 pop->event_set = tmp_event_set;
 
  237                 tmp_event_r_back = realloc(pop->event_r_back,
 
  238                             tmp_event_count * 
sizeof(
struct event *));
 
  239                 if (tmp_event_r_back == NULL) {
 
  241                         event_warn(
"realloc");
 
  244                 pop->event_r_back = tmp_event_r_back;
 
  246                 tmp_event_w_back = realloc(pop->event_w_back,
 
  247                             tmp_event_count * 
sizeof(
struct event *));
 
  248                 if (tmp_event_w_back == NULL) {
 
  251                         event_warn(
"realloc");
 
  254                 pop->event_w_back = tmp_event_w_back;
 
  256                 pop->event_count = tmp_event_count;
 
  258         if (ev->ev_fd >= pop->fd_count) {
 
  259                 int *tmp_idxplus1_by_fd;
 
  261                 if (pop->fd_count < 32)
 
  264                         new_count = pop->fd_count * 2;
 
  265                 while (new_count <= ev->ev_fd)
 
  268                         realloc(pop->idxplus1_by_fd, new_count * 
sizeof(
int));
 
  269                 if (tmp_idxplus1_by_fd == NULL) {
 
  270                         event_warn(
"realloc");
 
  273                 pop->idxplus1_by_fd = tmp_idxplus1_by_fd;
 
  274                 memset(pop->idxplus1_by_fd + pop->fd_count,
 
  275                        0, 
sizeof(
int)*(new_count - pop->fd_count));
 
  276                 pop->fd_count = new_count;
 
  279         i = pop->idxplus1_by_fd[ev->ev_fd] - 1;
 
  281                 pfd = &pop->event_set[
i];
 
  284                 pfd = &pop->event_set[
i];
 
  287                 pop->event_w_back[
i] = pop->event_r_back[
i] = NULL;
 
  288                 pop->idxplus1_by_fd[ev->ev_fd] = i + 1;
 
  292         if (ev->ev_events & EV_WRITE) {
 
  293                 pfd->events |= POLLOUT;
 
  294                 pop->event_w_back[
i] = ev;
 
  296         if (ev->ev_events & EV_READ) {
 
  297                 pfd->events |= POLLIN;
 
  298                 pop->event_r_back[
i] = ev;
 
  310 poll_del(
void *arg, 
struct event *ev)
 
  312         struct pollop *pop = arg;
 
  313         struct pollfd *pfd = NULL;
 
  316         if (ev->ev_events & EV_SIGNAL)
 
  317                 return (evsignal_del(ev));
 
  319         if (!(ev->ev_events & (EV_READ|EV_WRITE)))
 
  323         i = pop->idxplus1_by_fd[ev->ev_fd] - 1;
 
  328         pfd = &pop->event_set[
i];
 
  329         if (ev->ev_events & EV_READ) {
 
  330                 pfd->events &= ~POLLIN;
 
  331                 pop->event_r_back[
i] = NULL;
 
  333         if (ev->ev_events & EV_WRITE) {
 
  334                 pfd->events &= ~POLLOUT;
 
  335                 pop->event_w_back[
i] = NULL;
 
  343         pop->idxplus1_by_fd[ev->ev_fd] = 0;
 
  346         if (i != pop->nfds) {
 
  351                 memcpy(&pop->event_set[i], &pop->event_set[pop->nfds],
 
  352                        sizeof(
struct pollfd));
 
  353                 pop->event_r_back[
i] = pop->event_r_back[pop->nfds];
 
  354                 pop->event_w_back[
i] = pop->event_w_back[pop->nfds];
 
  355                 pop->idxplus1_by_fd[pop->event_set[
i].fd] = i + 1;
 
  363 poll_dealloc(
struct event_base *base, 
void *arg)
 
  365         struct pollop *pop = arg;
 
  367         evsignal_dealloc(base);
 
  369                 free(pop->event_set);
 
  370         if (pop->event_r_back)
 
  371                 free(pop->event_r_back);
 
  372         if (pop->event_w_back)
 
  373                 free(pop->event_w_back);
 
  374         if (pop->idxplus1_by_fd)
 
  375                 free(pop->idxplus1_by_fd);
 
  377         memset(pop, 0, 
sizeof(
struct pollop));