* static void reader_exit(struct io_conn *c, struct stdin_buffer *b)
* {
* assert(c == b->reader);
- * io_wake(b->writer, io_close(b->writer, NULL));
+ * io_wake(b->writer, io_close());
* b->reader = NULL;
* }
*
* {
* assert(c == b->writer);
* if (!b->reader)
- * return io_close(c, NULL);
+ * return io_close();
* b->len = sizeof(b->inbuf);
* io_wake(b->reader, io_read_partial(b->inbuf, &b->len, wake_writer, b));
* return io_idle();
assert(conn == buf->reader);
if (buf->iters == NUM_ITERS)
- return io_close(conn, NULL);
+ return io_close();
/* You write. */
io_wake(buf->writer,
io_read(&buf->buf, sizeof(buf->buf), poke_writer, buf));
if (++buf->iters == NUM_ITERS)
- return io_close(conn, NULL);
+ return io_close();
/* I'll wait until you tell me to write. */
return io_idle();
plan.pollflag = 0;
plan.io = NULL;
- /* Never called (overridded by io_wake), but NULL means closing */
- plan.next = io_close;
+ /* Never called (overridden by io_wake), but NULL means closing */
+ plan.next = (void *)io_idle;
io_plan_debug(&plan);
return plan;
switch (conn->plan.io(conn->fd.fd, &conn->plan)) {
case -1: /* Failure means a new plan: close up. */
set_current(conn);
- conn->plan = io_close(NULL, NULL);
+ conn->plan = io_close();
backend_plan_changed(conn);
set_current(NULL);
break;
}
}
-/* Useful next functions. */
/* Close the connection, we're done. */
-struct io_plan io_close(struct io_conn *conn, void *arg)
+struct io_plan io_close(void)
{
struct io_plan plan;
return plan;
}
+struct io_plan io_close_cb(struct io_conn *conn, void *arg)
+{
+ return io_close();
+}
+
/* Exit the loop, returning this (non-NULL) arg. */
struct io_plan io_break_(void *ret, struct io_plan plan)
{
/* FIXME: io_recvfrom/io_sendto */
/**
- * io_close - terminate a connection.
- * @conn: any connection.
+ * io_close - plan to close a connection.
*
- * The schedules a connection to be closed. It can be done on any
- * connection, whether it has I/O queued or not (though that I/O may
- * be performed first).
+ * On return to io_loop, the connection will be closed.
+ */
+struct io_plan io_close(void);
+
+/**
+ * io_close_cb - helper callback to close a connection.
+ * @conn: the connection.
*
- * It's common to 'return io_close(...)' from a @next function, but
- * io_close can also be used as an argument to io_next().
+ * This schedules a connection to be closed; designed to be used as
+ * a callback function.
*/
-struct io_plan io_close(struct io_conn *, void *unused);
+struct io_plan io_close_cb(struct io_conn *, void *unused);
/**
* io_loop - process fds until all closed on io_break.
} else if (events & POLLHUP) {
r--;
set_current(c);
- set_plan(c, io_close(c, NULL));
+ set_plan(c, io_close());
if (c->duplex) {
set_current(c->duplex);
- set_plan(c->duplex,
- io_close(c->duplex, NULL));
+ set_plan(c->duplex, io_close());
}
}
}
{
ok1(*state == 0);
(*state)++;
- io_set_finish(io_new_conn(fd, io_close(NULL, NULL)), finish_ok, state);
-
+ io_set_finish(io_new_conn(fd, io_close()), finish_ok, state);
}
static int make_listen_fd(const char *port, struct addrinfo **info)
d->state++;
io_set_finish(io_new_conn(fd,
- io_read(d->buf, sizeof(d->buf), io_close, d)),
+ io_read(d->buf, sizeof(d->buf), io_close_cb, d)),
finish_ok, d);
}
d->bytes = sizeof(d->buf);
io_set_finish(io_new_conn(fd,
- io_read_partial(d->buf, &d->bytes, io_close, d)),
+ io_read_partial(d->buf, &d->bytes, io_close_cb, d)),
finish_ok, d);
}
ok1(d->state == 0);
d->state++;
io_set_finish(io_new_conn(fd,
- io_write_partial(d->buf, &d->bytes, io_close, d)),
+ io_write_partial(d->buf, &d->bytes, io_close_cb, d)),
finish_ok, d);
}
{
ok1(d->state == 0);
d->state++;
- io_set_finish(io_new_conn(fd, io_write(d->buf, d->bytes, io_close, d)),
+ io_set_finish(io_new_conn(fd, io_write(d->buf, d->bytes,
+ io_close_cb, d)),
finish_ok, d);
}
{
ok1(d->state == 2 || d->state == 3);
d->state++;
- return io_close(conn, NULL);
+ return io_close();
}
static void finish_waker(struct io_conn *conn, struct data *d)
{
ok1(d->state == 1);
d->state++;
- return io_close(conn, NULL);
+ return io_close();
}
static void finish_ok(struct io_conn *conn, struct data *d)
{
/* This kills the dummy connection. */
close(fds2[1]);
- return io_read(buf, 16, io_close, NULL);
+ return io_read(buf, 16, io_close_cb, NULL);
}
int main(void)
ok1(pipe(fds) == 0);
/* Write then close. */
- io_new_conn(fds[1], io_write("hello there world", 16, io_close, NULL));
+ io_new_conn(fds[1], io_write("hello there world", 16,
+ io_close_cb, NULL));
conn = io_new_conn(fds[0], io_idle());
/* To avoid assert(num_waiting) */
ok1(pipe(fds2) == 0);
- io_new_conn(fds2[0], io_read(buf, 16, io_close, NULL));
+ io_new_conn(fds2[0], io_read(buf, 16, io_close_cb, NULL));
/* After half a second, it will read. */
io_timeout(conn, time_from_msec(500), timeout_wakeup, buf);
static struct io_plan wake_it(struct io_conn *conn, struct io_conn *reader)
{
- io_wake(reader, io_read(inbuf, 8, io_close, NULL));
- return io_close(conn, NULL);
+ io_wake(reader, io_read(inbuf, 8, io_close_cb, NULL));
+ return io_close();
}
int main(void)
assert(conn == buf->reader);
if (buf->iters == NUM_ITERS)
- return io_close(conn, NULL);
+ return io_close();
/* You write. */
io_wake(buf->writer,
io_read(&buf->buf, sizeof(buf->buf), poke_writer, buf));
if (++buf->iters == NUM_ITERS)
- return io_close(conn, NULL);
+ return io_close();
/* I'll wait until you tell me to write. */
return io_idle();
static struct io_plan write_done(struct io_conn *conn, struct data *d)
{
d->state++;
- return io_close(conn, NULL);
+ return io_close();
}
static void init_conn(int fd, struct data *d)
memset(d->wbuf, 7, sizeof(d->wbuf));
- conn = io_new_conn(fd, io_read(d->buf, sizeof(d->buf), io_close, d));
+ conn = io_new_conn(fd, io_read(d->buf, sizeof(d->buf), io_close_cb, d));
io_set_finish(conn, finish_ok, d);
conn = io_duplex(conn, io_write(d->wbuf, sizeof(d->wbuf), write_done, d));
ok1(conn);
{
ok1(d->state == 1);
d->state++;
- return io_close(conn, d);
+ return io_close();
}
static struct io_plan timeout(struct io_conn *conn, struct data *d)
ok1(d->state == 1);
d->state++;
d->timed_out = true;
- return io_close(conn, d);
+ return io_close();
}
static void finish_ok(struct io_conn *conn, struct data *d)
ok1(pkt->state == 0);
pkt->state++;
- io_set_finish(io_new_conn(fd, io_read_packet(pkt, io_close, pkt)),
+ io_set_finish(io_new_conn(fd, io_read_packet(pkt, io_close_cb, pkt)),
finish_ok, pkt);
}