- if (!p->destroyed && (FD_ISSET(p->fd, &in) ||
- force_event == EVENT_INPUT))
- {
- p->last_event = now;
- (*p->fun)(p, EVENT_INPUT);
- }
- if (!p->destroyed && (FD_ISSET(p->fd, &out) ||
- force_event == EVENT_OUTPUT))
- {
- p->last_event = now;
- (*p->fun)(p, EVENT_OUTPUT);
- }
- if (!p->destroyed && (FD_ISSET(p->fd, &except) ||
- force_event == EVENT_EXCEPT))
- {
- p->last_event = now;
- (*p->fun)(p, EVENT_EXCEPT);
- }
- }
- for (p = *iochans; p; p = nextp)
- {
- nextp = p->next;
-
- if (p->destroyed)
- {
- IOCHAN tmp = p, pr;
-
- /* Now reset the pointers */
- if (p == *iochans)
- *iochans = p->next;
- else
- {
- for (pr = *iochans; pr; pr = pr->next)
- if (pr->next == p)
- break;
- assert(pr); /* grave error if it weren't there */
- pr->next = p->next;
- }
- if (nextp == p)
- nextp = p->next;
- xfree(tmp);
- }
- }
- }
- while (*iochans);
+ fds[i].fd = p->fd;
+ fds[i].input_mask = 0;
+ if (p->flags & EVENT_INPUT)
+ fds[i].input_mask |= yaz_poll_read;
+ if (p->flags & EVENT_OUTPUT)
+ fds[i].input_mask |= yaz_poll_write;
+ if (p->flags & EVENT_EXCEPT)
+ fds[i].input_mask |= yaz_poll_except;
+ i++;
+ }
+ yaz_log(man->log_level, "yaz_poll begin nofds=%d", no_fds);
+ res = yaz_poll(fds, no_fds, to.tv_sec, 0);
+ yaz_log(man->log_level, "yaz_poll returned res=%d", res);
+ if (res < 0)
+ {
+ if (errno == EINTR)
+ continue;
+ else {
+ yaz_log(YLOG_ERRNO | YLOG_WARN, "poll");
+ return 0;
+ }
+ }
+ i = 0;
+ if (man->sel_fd != -1)
+ {
+ assert(fds[i].fd == man->sel_fd);
+ if (fds[i].output_mask)
+ {
+ IOCHAN chan;
+
+ yaz_log(man->log_level, "eventl: sel input on sel_fd=%d",
+ man->sel_fd);
+ while ((chan = sel_thread_result(man->sel_thread))) {
+ yaz_log(man->log_level,
+ "eventl: got thread result chan=%p name=%s", chan,
+ chan->name ? chan->name : "");
+ chan->thread_users--;
+ }
+ }
+ i++;
+ }
+ if (man->log_level)
+ {
+ int no = 0;
+ for (p = start; p; p = p->next)
+ no++;
+ yaz_log(man->log_level, "%d channels", no);
+ }
+ for (p = start; p; p = p->next)
+ {
+ time_t now = time(0);
+
+ if (p->destroyed)
+ {
+ yaz_log(man->log_level,
+ "eventl: skip destroyed chan=%p name=%s", p,
+ p->name ? p->name : "");
+ if (p->fd >= 0)
+ i++;
+ continue;
+ }
+ if (p->thread_users > 0)
+ {
+ yaz_log(man->log_level,
+ "eventl: skip chan=%p name=%s users=%d", p,
+ p->name ? p->name : "", p->thread_users);
+ if (p->fd >= 0)
+ i++;
+ continue;
+ }
+ p->this_event = 0;
+
+ if (p->max_idle && now - p->last_event > p->max_idle)
+ {
+ p->last_event = now;
+ p->this_event |= EVENT_TIMEOUT;
+ }
+ if (p->fd >= 0)
+ {
+ assert(fds[i].fd == p->fd);
+ if (fds[i].output_mask & yaz_poll_read)
+ {
+ p->last_event = now;
+ p->this_event |= EVENT_INPUT;
+ }
+ if (fds[i].output_mask & yaz_poll_write)
+ {
+ p->last_event = now;
+ p->this_event |= EVENT_OUTPUT;
+ }
+ if (fds[i].output_mask & yaz_poll_except)
+ {
+ p->last_event = now;
+ p->this_event |= EVENT_EXCEPT;
+ }
+ i++;
+ }
+ /* only fire one Z39.50/SRU socket event.. except for timeout */
+ if (p->this_event) {
+ if (!(p->this_event & EVENT_TIMEOUT) &&
+ !strcmp(p->name, "connection_socket"))
+ {
+ /* not a timeout and we have a Z39.50/SRU socket */
+ if (connection_fired == 0)
+ run_fun(man, p);
+ connection_fired++;
+ }
+ else
+ run_fun(man, p);
+ }
+ }
+
+ assert(inv_start == start);
+ yaz_mutex_enter(man->iochan_mutex);
+ for (nextp = iochans; *nextp;) {
+ IOCHAN p = *nextp;
+ if (p->destroyed && p->thread_users == 0) {
+ *nextp = iochan_destroy_real(p);
+ } else
+ nextp = &p->next;
+ }
+ yaz_mutex_leave(man->iochan_mutex);
+ xfree(fds);
+ } while (*iochans);