while (free_later) {
struct io_conn *c = free_later;
free_later = c->finish_arg;
- free(c);
+ io_alloc.free(c);
}
}
}
conn->finish_arg = free_later;
free_later = conn;
} else
- free(conn);
+ io_alloc.free(conn);
}
#else
static void io_loop_enter(void)
}
static void free_conn(struct io_conn *conn)
{
- free(conn);
+ io_alloc.free(conn);
}
#endif
struct fd **newfds;
size_t num = max_fds ? max_fds * 2 : 8;
- newpollfds = realloc(pollfds, sizeof(*newpollfds) * num);
+ newpollfds = io_alloc.realloc(pollfds, sizeof(*newpollfds)*num);
if (!newpollfds)
return false;
pollfds = newpollfds;
- newfds = realloc(fds, sizeof(*newfds) * num);
+ newfds = io_alloc.realloc(fds, sizeof(*newfds) * num);
if (!newfds)
return false;
fds = newfds;
fds[n] = fds[num_fds-1];
assert(fds[n]->backend_info == num_fds-1);
fds[n]->backend_info = n;
+ /* If that happens to be a duplex, move that too. */
+ if (!fds[n]->listener) {
+ struct io_conn *c = (void *)fds[n];
+ if (c->duplex) {
+ assert(c->duplex->fd.backend_info == num_fds-1);
+ c->duplex->fd.backend_info = n;
+ }
+ }
} else if (num_fds == 1) {
/* Free everything when no more fds. */
- free(pollfds);
- free(fds);
+ io_alloc.free(pollfds);
+ io_alloc.free(fds);
pollfds = NULL;
fds = NULL;
max_fds = 0;
void backend_del_conn(struct io_conn *conn)
{
if (conn->finish) {
- errno = conn->plan.u.close.saved_errno;
+ /* Saved by io_close */
+ errno = conn->plan.u1.s;
conn->finish(conn, conn->finish_arg);
}
if (timeout_active(conn))
backend_del_timeout(conn);
- free(conn->timeout);
+ io_alloc.free(conn->timeout);
if (conn->duplex) {
/* In case fds[] pointed to the other one. */
+ assert(conn->duplex->fd.backend_info == conn->fd.backend_info);
fds[conn->fd.backend_info] = &conn->duplex->fd;
conn->duplex->duplex = NULL;
conn->fd.backend_info = -1;
* anything can change. */
if (doing_debug())
break;
- if (!(events&(POLLIN|POLLOUT)))
+
+ /* If no events, or it closed
+ * the duplex, continue. */
+ if (!(events&(POLLIN|POLLOUT))
+ || !c->plan.next)
continue;
}
}