static LIST_HEAD(closing);
static LIST_HEAD(always);
static struct timemono (*nowfn)(void) = time_mono;
+static int (*pollfn)(struct pollfd *fds, nfds_t nfds, int timeout) = poll;
struct timemono (*io_time_override(struct timemono (*now)(void)))(void)
{
return old;
}
+int (*io_poll_override(int (*poll)(struct pollfd *fds, nfds_t nfds, int timeout)))(struct pollfd *, nfds_t, int)
+{
+ int (*old)(struct pollfd *fds, nfds_t nfds, int timeout) = pollfn;
+ pollfn = poll;
+ return old;
+}
+
static bool add_fd(struct fd *fd, short events)
{
if (!max_fds) {
num_waiting--;
pfd->events = 0;
- if (conn->plan[IO_IN].status == IO_POLLING)
+ if (conn->plan[IO_IN].status == IO_POLLING_NOTSTARTED
+ || conn->plan[IO_IN].status == IO_POLLING_STARTED)
pfd->events |= POLLIN;
- if (conn->plan[IO_OUT].status == IO_POLLING)
+ if (conn->plan[IO_OUT].status == IO_POLLING_NOTSTARTED
+ || conn->plan[IO_OUT].status == IO_POLLING_STARTED)
pfd->events |= POLLOUT;
if (pfd->events) {
return true;
}
-struct io_plan *io_close_taken_fd(struct io_conn *conn)
+void cleanup_conn_without_close(struct io_conn *conn)
{
tal_del_destructor(conn, destroy_conn_close_fd);
destroy_conn(conn, false);
- return io_close(conn);
}
static void accept_conn(struct io_listener *l)
}
}
- r = poll(pollfds, num_fds, ms_timeout);
- if (r < 0)
+ r = pollfn(pollfds, num_fds, ms_timeout);
+ if (r < 0) {
+ /* Signals shouldn't break us, unless they set
+ * io_loop_return. */
+ if (errno == EINTR)
+ continue;
break;
+ }
for (i = 0; i < num_fds && !io_loop_return; i++) {
struct io_conn *c = (void *)fds[i];
break;
if (fds[i]->listener) {
+ struct io_listener *l = (void *)fds[i];
if (events & POLLIN) {
- accept_conn((void *)c);
+ accept_conn(l);
+ r--;
+ } else if (events & (POLLHUP|POLLNVAL|POLLERR)) {
r--;
+ errno = EBADF;
+ io_close_listener(l);
}
} else if (events & (POLLIN|POLLOUT)) {
r--;