+ struct epoll_event *ev;
+ yaz_sock_chan_t chan = 0;
+
+ if (man->timeout_list)
+ { /* possibly timeout events not returned */
+ for (chan = man->timeout_list; chan; chan = chan->next)
+ if (chan->max_idle == man->timeout)
+ break;
+ if (chan)
+ {
+ man->timeout_list = chan->next;
+ chan->output_mask = yaz_poll_timeout;
+ return chan;
+ }
+ man->timeout_list = 0; /* no more timeout events */
+ }
+ assert(man->timeout_list = 0);
+ assert(man->event_no <= man->event_ret);
+ if (man->event_no == man->event_ret)
+ { /* must wait again */
+ rescan_timeout(man);
+ man->event_no = 0;
+ man->event_ret = epoll_wait(man->epoll_handle, man->events,
+ man->maxevents, man->timeout);
+ if (man->event_ret == 0)
+ {
+ /* timeout */
+ for (chan = man->chan_list; chan; chan = chan->next)
+ if (chan->max_idle == man->timeout)
+ break;
+ assert(chan); /* there must be one chan in a timeout state */
+ man->timeout_list = chan->next;
+ chan->output_mask = yaz_poll_timeout;
+ return chan;
+ }
+ else if (man->event_ret < 0)
+ {
+ /* error */
+ return 0;
+ }
+ }
+ ev = man->events + man->event_no;
+ chan = ev->data.ptr;
+ chan->output_mask = 0;
+ if (ev->events & EPOLLIN)
+ chan->output_mask |= yaz_poll_read;
+ if (ev->events & EPOLLOUT)
+ chan->output_mask |= yaz_poll_write;
+ if (ev->events & EPOLLERR)
+ chan->output_mask |= yaz_poll_except;
+ man->event_no++;
+ return chan;