From: Rusty Russell Date: Mon, 14 Oct 2013 10:58:35 +0000 (+1030) Subject: ccan/io: pass struct io_plan explicitly. X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=625bae8f5720d3ad3253ea9b26ad68abcd81bde5 ccan/io: pass struct io_plan explicitly. This simplifies some things: in particular, we can construct an io_plan without needing the current io_conn. On the other hand, we need to expose the structure now. Signed-off-by: Rusty Russell --- diff --git a/ccan/io/_info b/ccan/io/_info index affd97b4..e7dfe9da 100644 --- a/ccan/io/_info +++ b/ccan/io/_info @@ -32,18 +32,18 @@ * }; * * // This reads from stdin. - * static struct io_plan *wake_writer(struct io_conn *, struct stdin_buffer *); + * static struct io_plan wake_writer(struct io_conn *, struct stdin_buffer *); * // This writes the stdin buffer to the child. - * static struct io_plan *write_to_child(struct io_conn *c, - * struct stdin_buffer *b); - * static struct io_plan *read_stdin(struct io_conn *c, struct stdin_buffer *b) + * static struct io_plan write_to_child(struct io_conn *c, + * struct stdin_buffer *b); + * static struct io_plan read_stdin(struct io_conn *c, struct stdin_buffer *b) * { * assert(c == b->reader); * b->len = sizeof(b->inbuf); * return io_read_partial(c, b->inbuf, &b->len, wake_writer, b); * } * - * static struct io_plan *wake_writer(struct io_conn *c, struct stdin_buffer *b) + * static struct io_plan wake_writer(struct io_conn *c, struct stdin_buffer *b) * { * assert(c == b->reader); * io_wake(b->writer, write_to_child, b); @@ -57,14 +57,14 @@ * b->reader = NULL; * } * - * static struct io_plan *wake_reader(struct io_conn *c, struct stdin_buffer *b) + * static struct io_plan wake_reader(struct io_conn *c, struct stdin_buffer *b) * { * assert(c == b->writer); * io_wake(b->reader, read_stdin, b); * return io_idle(c); * } * - * static struct io_plan *write_to_child(struct io_conn *conn, + * static struct io_plan write_to_child(struct io_conn *conn, * struct stdin_buffer *b) * { * assert(conn == b->writer); @@ -73,8 +73,8 @@ * return io_write(conn, b->inbuf, b->len, wake_reader, b); * } * - * static struct io_plan *start_writer(struct io_conn *conn, - * struct stdin_buffer *b) + * static struct io_plan start_writer(struct io_conn *conn, + * struct stdin_buffer *b) * { * assert(conn == b->writer); * return io_idle(conn); @@ -87,8 +87,8 @@ * } * * // This reads from the child and saves it into buffer. - * static struct io_plan *read_from_child(struct io_conn *conn, - * struct buffer *b) + * static struct io_plan read_from_child(struct io_conn *conn, + * struct buffer *b) * { * b->off += b->rlen; * diff --git a/ccan/io/backend.h b/ccan/io/backend.h index 765e920e..c03ce2dc 100644 --- a/ccan/io/backend.h +++ b/ccan/io/backend.h @@ -10,60 +10,21 @@ struct fd { size_t backend_info; }; - /* Listeners create connections. */ struct io_listener { struct fd fd; /* These are for connections we create. */ - struct io_plan *(*next)(struct io_conn *, void *arg); + struct io_plan (*next)(struct io_conn *, void *arg); void (*finish)(struct io_conn *, void *arg); void *conn_arg; }; -enum io_result { - RESULT_AGAIN, - RESULT_FINISHED, - RESULT_CLOSE -}; - -enum io_state { - IO_IO, - IO_NEXT, /* eg starting, woken from idle, return from io_break. */ - IO_IDLE, - IO_FINISHED -}; - -static inline enum io_state from_ioplan(struct io_plan *op) -{ - return (enum io_state)(long)op; -} - -struct io_state_read { - char *buf; - size_t len; -}; - -struct io_state_write { - const char *buf; - size_t len; -}; - -struct io_state_readpart { - char *buf; - size_t *lenp; -}; - -struct io_state_writepart { - const char *buf; - size_t *lenp; -}; - struct io_timeout { struct timer timer; struct io_conn *conn; - struct io_plan *(*next)(struct io_conn *, void *arg); + struct io_plan (*next)(struct io_conn *, void *arg); void *next_arg; }; @@ -71,25 +32,13 @@ struct io_timeout { struct io_conn { struct fd fd; - struct io_plan *(*next)(struct io_conn *, void *arg); - void *next_arg; - void (*finish)(struct io_conn *, void *arg); void *finish_arg; struct io_conn *duplex; struct io_timeout *timeout; - enum io_result (*io)(struct io_conn *conn); - - int pollflag; /* 0, POLLIN or POLLOUT */ - enum io_state state; - union { - struct io_state_read read; - struct io_state_write write; - struct io_state_readpart readpart; - struct io_state_writepart writepart; - } u; + struct io_plan plan; }; static inline bool timeout_active(const struct io_conn *conn) @@ -107,5 +56,5 @@ void backend_wakeup(struct io_conn *conn); void backend_add_timeout(struct io_conn *conn, struct timespec ts); void backend_del_timeout(struct io_conn *conn); -struct io_plan *do_ready(struct io_conn *conn); +struct io_plan do_ready(struct io_conn *conn); #endif /* CCAN_IO_BACKEND_H */ diff --git a/ccan/io/benchmarks/run-different-speed.c b/ccan/io/benchmarks/run-different-speed.c index 10fa0b96..537a67bb 100644 --- a/ccan/io/benchmarks/run-different-speed.c +++ b/ccan/io/benchmarks/run-different-speed.c @@ -25,21 +25,21 @@ struct client { char reply_buffer[REPLY_SIZE]; }; -static struct io_plan *write_reply(struct io_conn *conn, struct client *client); -static struct io_plan *read_request(struct io_conn *conn, struct client *client) +static struct io_plan write_reply(struct io_conn *conn, struct client *client); +static struct io_plan read_request(struct io_conn *conn, struct client *client) { return io_read(conn, client->request_buffer, REQUEST_SIZE, write_reply, client); } /* once we're done, loop again. */ -static struct io_plan *write_complete(struct io_conn *conn, struct client *client) +static struct io_plan write_complete(struct io_conn *conn, struct client *client) { completed++; return read_request(conn, client); } -static struct io_plan *write_reply(struct io_conn *conn, struct client *client) +static struct io_plan write_reply(struct io_conn *conn, struct client *client) { return io_write(conn, client->reply_buffer, REPLY_SIZE, write_complete, client); @@ -106,12 +106,12 @@ static void sigalarm(int sig) write(timeout[1], "1", 1); } -static struct io_plan *do_timeout(struct io_conn *conn, char *buf) +static struct io_plan do_timeout(struct io_conn *conn, char *buf) { return io_break(conn, buf, NULL, NULL); } -static struct io_plan *do_timeout_read(struct io_conn *conn, char *buf) +static struct io_plan do_timeout_read(struct io_conn *conn, char *buf) { return io_read(conn, buf, 1, do_timeout, buf); } diff --git a/ccan/io/benchmarks/run-length-prefix.c b/ccan/io/benchmarks/run-length-prefix.c index 74290fd8..2ed9c729 100644 --- a/ccan/io/benchmarks/run-length-prefix.c +++ b/ccan/io/benchmarks/run-length-prefix.c @@ -25,28 +25,28 @@ struct client { char *request_buffer; }; -static struct io_plan *write_reply(struct io_conn *conn, struct client *client); -static struct io_plan *read_body(struct io_conn *conn, struct client *client) +static struct io_plan write_reply(struct io_conn *conn, struct client *client); +static struct io_plan read_body(struct io_conn *conn, struct client *client) { assert(client->len <= REQUEST_MAX); return io_read(conn, client->request_buffer, client->len, write_reply, client); } -static struct io_plan *read_header(struct io_conn *conn, struct client *client) +static struct io_plan read_header(struct io_conn *conn, struct client *client) { return io_read(conn, &client->len, sizeof(client->len), read_body, client); } /* once we're done, loop again. */ -static struct io_plan *write_complete(struct io_conn *conn, struct client *client) +static struct io_plan write_complete(struct io_conn *conn, struct client *client) { completed++; return read_header(conn, client); } -static struct io_plan *write_reply(struct io_conn *conn, struct client *client) +static struct io_plan write_reply(struct io_conn *conn, struct client *client) { return io_write(conn, &client->len, sizeof(client->len), write_complete, client); @@ -112,12 +112,12 @@ static void sigalarm(int sig) write(timeout[1], "1", 1); } -static struct io_plan *do_timeout(struct io_conn *conn, char *buf) +static struct io_plan do_timeout(struct io_conn *conn, char *buf) { return io_break(conn, buf, NULL, NULL); } -static struct io_plan *do_timeout_read(struct io_conn *conn, char *buf) +static struct io_plan do_timeout_read(struct io_conn *conn, char *buf) { return io_read(conn, buf, 1, do_timeout, buf); } diff --git a/ccan/io/benchmarks/run-loop.c b/ccan/io/benchmarks/run-loop.c index 5dc1c3e1..a2898e13 100644 --- a/ccan/io/benchmarks/run-loop.c +++ b/ccan/io/benchmarks/run-loop.c @@ -16,24 +16,24 @@ struct buffer { char buf[32]; }; -static struct io_plan *poke_writer(struct io_conn *conn, struct buffer *buf); -static struct io_plan *poke_reader(struct io_conn *conn, struct buffer *buf); +static struct io_plan poke_writer(struct io_conn *conn, struct buffer *buf); +static struct io_plan poke_reader(struct io_conn *conn, struct buffer *buf); -static struct io_plan *do_read(struct io_conn *conn, struct buffer *buf) +static struct io_plan do_read(struct io_conn *conn, struct buffer *buf) { assert(conn == buf->reader); return io_read(conn, &buf->buf, sizeof(buf->buf), poke_writer, buf); } -static struct io_plan *do_write(struct io_conn *conn, struct buffer *buf) +static struct io_plan do_write(struct io_conn *conn, struct buffer *buf) { assert(conn == buf->writer); return io_write(conn, &buf->buf, sizeof(buf->buf), poke_reader, buf); } -static struct io_plan *poke_writer(struct io_conn *conn, struct buffer *buf) +static struct io_plan poke_writer(struct io_conn *conn, struct buffer *buf) { assert(conn == buf->reader); @@ -47,7 +47,7 @@ static struct io_plan *poke_writer(struct io_conn *conn, struct buffer *buf) return io_idle(conn); } -static struct io_plan *poke_reader(struct io_conn *conn, struct buffer *buf) +static struct io_plan poke_reader(struct io_conn *conn, struct buffer *buf) { assert(conn == buf->writer); /* You read. */ @@ -60,7 +60,7 @@ static struct io_plan *poke_reader(struct io_conn *conn, struct buffer *buf) return io_idle(conn); } -static struct io_plan *reader(struct io_conn *conn, struct buffer *buf) +static struct io_plan reader(struct io_conn *conn, struct buffer *buf) { assert(conn == buf->reader); diff --git a/ccan/io/io.c b/ccan/io/io.c index f7b46faa..fe9fed4f 100644 --- a/ccan/io/io.c +++ b/ccan/io/io.c @@ -13,8 +13,8 @@ void *io_loop_return; struct io_listener *io_new_listener_(int fd, - struct io_plan *(*start)(struct io_conn *, - void *arg), + struct io_plan (*start)(struct io_conn *, + void *arg), void (*finish)(struct io_conn *, void *), void *arg) { @@ -43,7 +43,7 @@ void io_close_listener(struct io_listener *l) } struct io_conn *io_new_conn_(int fd, - struct io_plan *(*start)(struct io_conn *, void *), + struct io_plan (*start)(struct io_conn *, void *), void (*finish)(struct io_conn *, void *), void *arg) { @@ -54,11 +54,11 @@ struct io_conn *io_new_conn_(int fd, conn->fd.listener = false; conn->fd.fd = fd; - conn->next = start; + conn->plan.next = start; conn->finish = finish; - conn->finish_arg = conn->next_arg = arg; - conn->pollflag = 0; - conn->state = IO_NEXT; + conn->finish_arg = conn->plan.next_arg = arg; + conn->plan.pollflag = 0; + conn->plan.state = IO_NEXT; conn->duplex = NULL; conn->timeout = NULL; if (!add_conn(conn)) { @@ -69,7 +69,7 @@ struct io_conn *io_new_conn_(int fd, } struct io_conn *io_duplex_(struct io_conn *old, - struct io_plan *(*start)(struct io_conn *, void *), + struct io_plan (*start)(struct io_conn *, void *), void (*finish)(struct io_conn *, void *), void *arg) { @@ -83,11 +83,11 @@ struct io_conn *io_duplex_(struct io_conn *old, conn->fd.listener = false; conn->fd.fd = old->fd.fd; - conn->next = start; + conn->plan.next = start; conn->finish = finish; - conn->finish_arg = conn->next_arg = arg; - conn->pollflag = 0; - conn->state = IO_NEXT; + conn->finish_arg = conn->plan.next_arg = arg; + conn->plan.pollflag = 0; + conn->plan.state = IO_NEXT; conn->duplex = old; conn->timeout = NULL; if (!add_duplex(conn)) { @@ -98,13 +98,8 @@ struct io_conn *io_duplex_(struct io_conn *old, return conn; } -static inline struct io_plan *to_ioplan(enum io_state state) -{ - return (struct io_plan *)(long)state; -} - bool io_timeout_(struct io_conn *conn, struct timespec ts, - struct io_plan *(*cb)(struct io_conn *, void *), void *arg) + struct io_plan (*cb)(struct io_conn *, void *), void *arg) { if (!conn->timeout) { conn->timeout = malloc(sizeof(*conn->timeout)); @@ -121,145 +116,165 @@ bool io_timeout_(struct io_conn *conn, struct timespec ts, static enum io_result do_write(struct io_conn *conn) { - ssize_t ret = write(conn->fd.fd, conn->u.write.buf, conn->u.write.len); + ssize_t ret = write(conn->fd.fd, conn->plan.u.write.buf, conn->plan.u.write.len); if (ret < 0) return RESULT_CLOSE; - conn->u.write.buf += ret; - conn->u.write.len -= ret; - if (conn->u.write.len == 0) + conn->plan.u.write.buf += ret; + conn->plan.u.write.len -= ret; + if (conn->plan.u.write.len == 0) return RESULT_FINISHED; else return RESULT_AGAIN; } /* Queue some data to be written. */ -struct io_plan *io_write_(struct io_conn *conn, const void *data, size_t len, - struct io_plan *(*cb)(struct io_conn *, void *), - void *arg) +struct io_plan io_write_(struct io_conn *conn, const void *data, size_t len, + struct io_plan (*cb)(struct io_conn *, void *), + void *arg) { - conn->u.write.buf = data; - conn->u.write.len = len; - conn->io = do_write; - conn->next = cb; - conn->next_arg = arg; - conn->pollflag = POLLOUT; - return to_ioplan(IO_IO); + struct io_plan plan; + + plan.u.write.buf = data; + plan.u.write.len = len; + plan.io = do_write; + plan.next = cb; + plan.next_arg = arg; + plan.pollflag = POLLOUT; + plan.state = IO_IO; + return plan; } static enum io_result do_read(struct io_conn *conn) { - ssize_t ret = read(conn->fd.fd, conn->u.read.buf, conn->u.read.len); + ssize_t ret = read(conn->fd.fd, conn->plan.u.read.buf, + conn->plan.u.read.len); if (ret <= 0) return RESULT_CLOSE; - conn->u.read.buf += ret; - conn->u.read.len -= ret; - if (conn->u.read.len == 0) + conn->plan.u.read.buf += ret; + conn->plan.u.read.len -= ret; + if (conn->plan.u.read.len == 0) return RESULT_FINISHED; else return RESULT_AGAIN; } /* Queue a request to read into a buffer. */ -struct io_plan *io_read_(struct io_conn *conn, void *data, size_t len, - struct io_plan *(*cb)(struct io_conn *, void *), - void *arg) +struct io_plan io_read_(struct io_conn *conn, void *data, size_t len, + struct io_plan (*cb)(struct io_conn *, void *), + void *arg) { - conn->u.read.buf = data; - conn->u.read.len = len; - conn->io = do_read; - conn->next = cb; - conn->next_arg = arg; - conn->pollflag = POLLIN; - return to_ioplan(IO_IO); + struct io_plan plan; + + plan.u.read.buf = data; + plan.u.read.len = len; + plan.io = do_read; + plan.next = cb; + plan.next_arg = arg; + plan.pollflag = POLLIN; + plan.state = IO_IO; + return plan; } static enum io_result do_read_partial(struct io_conn *conn) { - ssize_t ret = read(conn->fd.fd, conn->u.readpart.buf, - *conn->u.readpart.lenp); + ssize_t ret = read(conn->fd.fd, conn->plan.u.readpart.buf, + *conn->plan.u.readpart.lenp); if (ret <= 0) return RESULT_CLOSE; - *conn->u.readpart.lenp = ret; + *conn->plan.u.readpart.lenp = ret; return RESULT_FINISHED; } /* Queue a partial request to read into a buffer. */ -struct io_plan *io_read_partial_(struct io_conn *conn, void *data, size_t *len, - struct io_plan *(*cb)(struct io_conn *, void *), - void *arg) +struct io_plan io_read_partial_(struct io_conn *conn, void *data, size_t *len, + struct io_plan (*cb)(struct io_conn *, void *), + void *arg) { - conn->u.readpart.buf = data; - conn->u.readpart.lenp = len; - conn->io = do_read_partial; - conn->next = cb; - conn->next_arg = arg; - conn->pollflag = POLLIN; - return to_ioplan(IO_IO); + struct io_plan plan; + + plan.u.readpart.buf = data; + plan.u.readpart.lenp = len; + plan.io = do_read_partial; + plan.next = cb; + plan.next_arg = arg; + plan.pollflag = POLLIN; + plan.state = IO_IO; + + return plan; } static enum io_result do_write_partial(struct io_conn *conn) { - ssize_t ret = write(conn->fd.fd, conn->u.writepart.buf, - *conn->u.writepart.lenp); + ssize_t ret = write(conn->fd.fd, conn->plan.u.writepart.buf, + *conn->plan.u.writepart.lenp); if (ret < 0) return RESULT_CLOSE; - *conn->u.writepart.lenp = ret; + *conn->plan.u.writepart.lenp = ret; return RESULT_FINISHED; } /* Queue a partial write request. */ -struct io_plan *io_write_partial_(struct io_conn *conn, - const void *data, size_t *len, - struct io_plan *(*cb)(struct io_conn*, void *), - void *arg) +struct io_plan io_write_partial_(struct io_conn *conn, + const void *data, size_t *len, + struct io_plan (*cb)(struct io_conn*, void *), + void *arg) { - conn->u.writepart.buf = data; - conn->u.writepart.lenp = len; - conn->io = do_write_partial; - conn->next = cb; - conn->next_arg = arg; - conn->pollflag = POLLOUT; - return to_ioplan(IO_IO); + struct io_plan plan; + + plan.u.writepart.buf = data; + plan.u.writepart.lenp = len; + plan.io = do_write_partial; + plan.next = cb; + plan.next_arg = arg; + plan.pollflag = POLLOUT; + plan.state = IO_IO; + + return plan; } -struct io_plan *io_idle(struct io_conn *conn) +struct io_plan io_idle(struct io_conn *conn) { - conn->pollflag = 0; - return to_ioplan(IO_IDLE); + struct io_plan plan; + + plan.pollflag = 0; + plan.state = IO_IDLE; + + return plan; } void io_wake_(struct io_conn *conn, - struct io_plan *(*fn)(struct io_conn *, void *), void *arg) + struct io_plan (*fn)(struct io_conn *, void *), void *arg) { /* It might have finished, but we haven't called its finish() yet. */ - if (conn->state == IO_FINISHED) + if (conn->plan.state == IO_FINISHED) return; - assert(conn->state == IO_IDLE); - conn->next = fn; - conn->next_arg = arg; - conn->state = IO_NEXT; + assert(conn->plan.state == IO_IDLE); + conn->plan.next = fn; + conn->plan.next_arg = arg; + conn->plan.pollflag = 0; + conn->plan.state = IO_NEXT; backend_wakeup(conn); } -static struct io_plan *do_next(struct io_conn *conn) +static struct io_plan do_next(struct io_conn *conn) { if (timeout_active(conn)) backend_del_timeout(conn); - return conn->next(conn, conn->next_arg); + return conn->plan.next(conn, conn->plan.next_arg); } -struct io_plan *do_ready(struct io_conn *conn) +struct io_plan do_ready(struct io_conn *conn) { - assert(conn->state == IO_IO); - switch (conn->io(conn)) { + assert(conn->plan.state == IO_IO); + switch (conn->plan.io(conn)) { case RESULT_CLOSE: return io_close(conn, NULL); case RESULT_FINISHED: return do_next(conn); case RESULT_AGAIN: - return to_ioplan(conn->state); + return conn->plan; default: abort(); } @@ -267,19 +282,29 @@ struct io_plan *do_ready(struct io_conn *conn) /* 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(struct io_conn *conn, void *arg) { - return to_ioplan(IO_FINISHED); + struct io_plan plan; + + plan.state = IO_FINISHED; + plan.pollflag = 0; + + return plan; } /* Exit the loop, returning this (non-NULL) arg. */ -struct io_plan *io_break_(struct io_conn *conn, void *ret, - struct io_plan *(*fn)(struct io_conn *, void *), - void *arg) +struct io_plan io_break_(struct io_conn *conn, void *ret, + struct io_plan (*fn)(struct io_conn *, void *), + void *arg) { + struct io_plan plan; + io_loop_return = ret; - conn->next = fn; - conn->next_arg = arg; - return to_ioplan(IO_NEXT); + plan.state = IO_NEXT; + plan.pollflag = 0; + plan.next = fn; + plan.next_arg = arg; + + return plan; } diff --git a/ccan/io/io.h b/ccan/io/io.h index 9b4797a5..a027fe71 100644 --- a/ccan/io/io.h +++ b/ccan/io/io.h @@ -6,12 +6,60 @@ #include #include +struct io_conn; + +struct io_state_read { + char *buf; + size_t len; +}; + +struct io_state_write { + const char *buf; + size_t len; +}; + +struct io_state_readpart { + char *buf; + size_t *lenp; +}; + +struct io_state_writepart { + const char *buf; + size_t *lenp; +}; + +enum io_result { + RESULT_AGAIN, + RESULT_FINISHED, + RESULT_CLOSE +}; + +enum io_state { + IO_IO, + IO_NEXT, /* eg starting, woken from idle, return from io_break. */ + IO_IDLE, + IO_FINISHED +}; + /** - * struct io_plan - pointer to return from a setup function. + * struct io_plan - returned from a setup function. * * A plan of what IO to do, when. */ -struct io_plan; +struct io_plan { + int pollflag; + enum io_state state; + enum io_result (*io)(struct io_conn *conn); + struct io_plan (*next)(struct io_conn *, void *arg); + void *next_arg; + + union { + struct io_state_read read; + struct io_state_write write; + struct io_state_readpart readpart; + struct io_state_writepart writepart; + } u; +}; /** * io_new_conn - create a new connection. @@ -32,13 +80,13 @@ struct io_plan; */ #define io_new_conn(fd, start, finish, arg) \ io_new_conn_((fd), \ - typesafe_cb_preargs(struct io_plan *, void *, \ + typesafe_cb_preargs(struct io_plan, void *, \ (start), (arg), struct io_conn *), \ typesafe_cb_preargs(void, void *, (finish), (arg), \ struct io_conn *), \ (arg)) struct io_conn *io_new_conn_(int fd, - struct io_plan *(*start)(struct io_conn *, void *), + struct io_plan (*start)(struct io_conn *, void *), void (*finish)(struct io_conn *, void *), void *arg); @@ -56,14 +104,14 @@ struct io_conn *io_new_conn_(int fd, */ #define io_new_listener(fd, start, finish, arg) \ io_new_listener_((fd), \ - typesafe_cb_preargs(struct io_plan *, void *, \ + typesafe_cb_preargs(struct io_plan, void *, \ (start), (arg), \ struct io_conn *), \ typesafe_cb_preargs(void, void *, (finish), \ (arg), struct io_conn *), \ (arg)) struct io_listener *io_new_listener_(int fd, - struct io_plan *(*start)(struct io_conn *, + struct io_plan (*start)(struct io_conn *, void *arg), void (*finish)(struct io_conn *, void *arg), @@ -93,12 +141,12 @@ void io_close_listener(struct io_listener *listener); */ #define io_write(conn, data, len, cb, arg) \ io_write_((conn), (data), (len), \ - typesafe_cb_preargs(struct io_plan *, void *, \ + typesafe_cb_preargs(struct io_plan, void *, \ (cb), (arg), struct io_conn *), \ (arg)) -struct io_plan *io_write_(struct io_conn *conn, const void *data, size_t len, - struct io_plan *(*cb)(struct io_conn *, void *), - void *arg); +struct io_plan io_write_(struct io_conn *conn, const void *data, size_t len, + struct io_plan (*cb)(struct io_conn *, void *), + void *arg); /** * io_read - queue buffer to be read. @@ -116,12 +164,12 @@ struct io_plan *io_write_(struct io_conn *conn, const void *data, size_t len, */ #define io_read(conn, data, len, cb, arg) \ io_read_((conn), (data), (len), \ - typesafe_cb_preargs(struct io_plan *, void *, \ + typesafe_cb_preargs(struct io_plan, void *, \ (cb), (arg), struct io_conn *), \ (arg)) -struct io_plan *io_read_(struct io_conn *conn, void *data, size_t len, - struct io_plan *(*cb)(struct io_conn *, void *), - void *arg); +struct io_plan io_read_(struct io_conn *conn, void *data, size_t len, + struct io_plan (*cb)(struct io_conn *, void *), + void *arg); /** @@ -140,12 +188,12 @@ struct io_plan *io_read_(struct io_conn *conn, void *data, size_t len, */ #define io_read_partial(conn, data, len, cb, arg) \ io_read_partial_((conn), (data), (len), \ - typesafe_cb_preargs(struct io_plan *, void *, \ + typesafe_cb_preargs(struct io_plan, void *, \ (cb), (arg), struct io_conn *), \ (arg)) -struct io_plan *io_read_partial_(struct io_conn *conn, void *data, size_t *len, - struct io_plan *(*cb)(struct io_conn *, void *), - void *arg); +struct io_plan io_read_partial_(struct io_conn *conn, void *data, size_t *len, + struct io_plan (*cb)(struct io_conn *, void *), + void *arg); /** * io_write_partial - queue data to be written (partial OK). @@ -163,13 +211,13 @@ struct io_plan *io_read_partial_(struct io_conn *conn, void *data, size_t *len, */ #define io_write_partial(conn, data, len, cb, arg) \ io_write_partial_((conn), (data), (len), \ - typesafe_cb_preargs(struct io_plan *, void *, \ + typesafe_cb_preargs(struct io_plan, void *, \ (cb), (arg), struct io_conn *), \ (arg)) -struct io_plan *io_write_partial_(struct io_conn *conn, - const void *data, size_t *len, - struct io_plan *(*cb)(struct io_conn *, void*), - void *arg); +struct io_plan io_write_partial_(struct io_conn *conn, + const void *data, size_t *len, + struct io_plan (*cb)(struct io_conn *, void*), + void *arg); /** @@ -180,7 +228,7 @@ struct io_plan *io_write_partial_(struct io_conn *conn, * later call io_read/io_write etc. (or io_close) on it, in which case * it will do that. */ -struct io_plan *io_idle(struct io_conn *conn); +struct io_plan io_idle(struct io_conn *conn); /** * io_timeout - set timeout function if the callback doesn't fire. @@ -198,12 +246,12 @@ struct io_plan *io_idle(struct io_conn *conn); */ #define io_timeout(conn, ts, fn, arg) \ io_timeout_((conn), (ts), \ - typesafe_cb_preargs(struct io_plan *, void *, \ + typesafe_cb_preargs(struct io_plan, void *, \ (fn), (arg), \ struct io_conn *), \ (arg)) bool io_timeout_(struct io_conn *conn, struct timespec ts, - struct io_plan *(*fn)(struct io_conn *, void *), void *arg); + struct io_plan (*fn)(struct io_conn *, void *), void *arg); /** * io_duplex - split an fd into two connections. @@ -221,14 +269,14 @@ bool io_timeout_(struct io_conn *conn, struct timespec ts, */ #define io_duplex(conn, start, finish, arg) \ io_duplex_((conn), \ - typesafe_cb_preargs(struct io_plan *, void *, \ + typesafe_cb_preargs(struct io_plan, void *, \ (start), (arg), struct io_conn *), \ typesafe_cb_preargs(void, void *, (finish), (arg), \ struct io_conn *), \ (arg)) struct io_conn *io_duplex_(struct io_conn *conn, - struct io_plan *(*start)(struct io_conn *, void *), + struct io_plan (*start)(struct io_conn *, void *), void (*finish)(struct io_conn *, void *), void *arg); @@ -243,11 +291,11 @@ struct io_conn *io_duplex_(struct io_conn *conn, */ #define io_wake(conn, fn, arg) \ io_wake_((conn), \ - typesafe_cb_preargs(struct io_plan *, void *, \ + typesafe_cb_preargs(struct io_plan, void *, \ (fn), (arg), struct io_conn *), \ (arg)) void io_wake_(struct io_conn *conn, - struct io_plan *(*fn)(struct io_conn *, void *), void *arg); + struct io_plan (*fn)(struct io_conn *, void *), void *arg); /** * io_break - return from io_loop() @@ -264,12 +312,12 @@ void io_wake_(struct io_conn *conn, */ #define io_break(conn, ret, fn, arg) \ io_break_((conn), (ret), \ - typesafe_cb_preargs(struct io_plan *, void *, \ + typesafe_cb_preargs(struct io_plan, void *, \ (fn), (arg), struct io_conn *), \ (arg)) -struct io_plan *io_break_(struct io_conn *conn, void *ret, - struct io_plan *(*fn)(struct io_conn *, void *), - void *arg); +struct io_plan io_break_(struct io_conn *conn, void *ret, + struct io_plan (*fn)(struct io_conn *, void *), + void *arg); /* FIXME: io_recvfrom/io_sendto */ @@ -284,7 +332,7 @@ struct io_plan *io_break_(struct io_conn *conn, void *ret, * It's common to 'return io_close(...)' from a @next function, but * io_close can also be used as an argument to io_next(). */ -struct io_plan *io_close(struct io_conn *, void *unused); +struct io_plan io_close(struct io_conn *, void *unused); /** * io_loop - process fds until all closed on io_break. diff --git a/ccan/io/poll.c b/ccan/io/poll.c index 0cc84ad9..adf7bb0c 100644 --- a/ccan/io/poll.c +++ b/ccan/io/poll.c @@ -101,9 +101,9 @@ static void del_conn(struct io_conn *conn) conn->duplex->duplex = NULL; } else del_fd(&conn->fd); - if (conn->state == IO_FINISHED) + if (conn->plan.state == IO_FINISHED) num_finished--; - else if (conn->state == IO_NEXT) + else if (conn->plan.state == IO_NEXT) num_next--; } @@ -112,17 +112,16 @@ void del_listener(struct io_listener *l) del_fd(&l->fd); } -static void backend_set_state(struct io_conn *conn, struct io_plan *plan) +static void backend_set_state(struct io_conn *conn, struct io_plan plan) { - enum io_state state = from_ioplan(plan); struct pollfd *pfd = &pollfds[conn->fd.backend_info]; if (pfd->events) num_waiting--; - pfd->events = conn->pollflag; + pfd->events = plan.pollflag; if (conn->duplex) { - int mask = conn->duplex->pollflag; + int mask = conn->duplex->plan.pollflag; /* You can't *both* read/write. */ assert(!mask || pfd->events != mask); pfd->events |= mask; @@ -130,12 +129,12 @@ static void backend_set_state(struct io_conn *conn, struct io_plan *plan) if (pfd->events) num_waiting++; - if (state == IO_NEXT) + if (plan.state == IO_NEXT) num_next++; - else if (state == IO_FINISHED) + else if (plan.state == IO_FINISHED) num_finished++; - conn->state = state; + conn->plan = plan; } void backend_wakeup(struct io_conn *conn) @@ -174,12 +173,12 @@ static void finish_and_next(bool finished_only) continue; c = (void *)fds[i]; for (duplex = c->duplex; c; c = duplex, duplex = NULL) { - if (c->state == IO_FINISHED) { + if (c->plan.state == IO_FINISHED) { del_conn(c); free(c); i--; - } else if (!finished_only && c->state == IO_NEXT) { - backend_set_state(c, c->next(c, c->next_arg)); + } else if (!finished_only && c->plan.state == IO_NEXT) { + backend_set_state(c, c->plan.next(c, c->plan.next_arg)); num_next--; } } @@ -271,7 +270,7 @@ void *io_loop(void) } else if (events & (POLLIN|POLLOUT)) { r--; if (c->duplex) { - int mask = c->duplex->pollflag; + int mask = c->duplex->plan.pollflag; if (events & mask) { ready(c->duplex); events &= ~mask; diff --git a/ccan/io/test/run-01-start-finish.c b/ccan/io/test/run-01-start-finish.c index a2393d9f..7c6ae415 100644 --- a/ccan/io/test/run-01-start-finish.c +++ b/ccan/io/test/run-01-start-finish.c @@ -6,7 +6,7 @@ #include #include -static struct io_plan *start_ok(struct io_conn *conn, int *state) +static struct io_plan start_ok(struct io_conn *conn, int *state) { ok1(*state == 0); (*state)++; diff --git a/ccan/io/test/run-02-read.c b/ccan/io/test/run-02-read.c index 4e184909..8b96f029 100644 --- a/ccan/io/test/run-02-read.c +++ b/ccan/io/test/run-02-read.c @@ -11,7 +11,7 @@ struct data { char buf[4]; }; -static struct io_plan *start_ok(struct io_conn *conn, struct data *d) +static struct io_plan start_ok(struct io_conn *conn, struct data *d) { ok1(d->state == 0); d->state++; diff --git a/ccan/io/test/run-03-readpartial.c b/ccan/io/test/run-03-readpartial.c index 9e97f49a..e6e33e3d 100644 --- a/ccan/io/test/run-03-readpartial.c +++ b/ccan/io/test/run-03-readpartial.c @@ -12,7 +12,7 @@ struct data { char buf[4]; }; -static struct io_plan *start_ok(struct io_conn *conn, struct data *d) +static struct io_plan start_ok(struct io_conn *conn, struct data *d) { ok1(d->state == 0); d->state++; diff --git a/ccan/io/test/run-04-writepartial.c b/ccan/io/test/run-04-writepartial.c index 87fa8d9d..d4e33c96 100644 --- a/ccan/io/test/run-04-writepartial.c +++ b/ccan/io/test/run-04-writepartial.c @@ -12,7 +12,7 @@ struct data { char *buf; }; -static struct io_plan *start_ok(struct io_conn *conn, struct data *d) +static struct io_plan start_ok(struct io_conn *conn, struct data *d) { ok1(d->state == 0); d->state++; diff --git a/ccan/io/test/run-05-write.c b/ccan/io/test/run-05-write.c index 1181bec0..ad6760e4 100644 --- a/ccan/io/test/run-05-write.c +++ b/ccan/io/test/run-05-write.c @@ -12,7 +12,7 @@ struct data { char *buf; }; -static struct io_plan *start_ok(struct io_conn *conn, struct data *d) +static struct io_plan start_ok(struct io_conn *conn, struct data *d) { ok1(d->state == 0); d->state++; diff --git a/ccan/io/test/run-06-idle.c b/ccan/io/test/run-06-idle.c index 597060c2..19d0f8b1 100644 --- a/ccan/io/test/run-06-idle.c +++ b/ccan/io/test/run-06-idle.c @@ -16,14 +16,14 @@ struct data { char buf[4]; }; -static struct io_plan *plan_read(struct io_conn *conn, struct data *d) +static struct io_plan plan_read(struct io_conn *conn, struct data *d) { ok1(d->state == 2 || d->state == 3); d->state++; return io_read(conn, d->buf, sizeof(d->buf), io_close, d); } -static struct io_plan *start_waker(struct io_conn *conn, struct data *d) +static struct io_plan start_waker(struct io_conn *conn, struct data *d) { ok1(d->state == 1); d->state++; @@ -38,7 +38,7 @@ static void finish_waker(struct io_conn *conn, struct data *d) d->state++; } -static struct io_plan *start_idle(struct io_conn *conn, struct data *d) +static struct io_plan start_idle(struct io_conn *conn, struct data *d) { int fd; diff --git a/ccan/io/test/run-07-break.c b/ccan/io/test/run-07-break.c index 3dac4ece..5bc0e8c6 100644 --- a/ccan/io/test/run-07-break.c +++ b/ccan/io/test/run-07-break.c @@ -11,14 +11,14 @@ struct data { char buf[4]; }; -static struct io_plan *plan_read(struct io_conn *conn, struct data *d) +static struct io_plan plan_read(struct io_conn *conn, struct data *d) { ok1(d->state == 1); d->state++; return io_read(conn, d->buf, sizeof(d->buf), io_close, d); } -static struct io_plan *start_break(struct io_conn *conn, struct data *d) +static struct io_plan start_break(struct io_conn *conn, struct data *d) { ok1(d->state == 0); d->state++; diff --git a/ccan/io/test/run-10-many.c b/ccan/io/test/run-10-many.c index 31369118..91b335e1 100644 --- a/ccan/io/test/run-10-many.c +++ b/ccan/io/test/run-10-many.c @@ -15,10 +15,10 @@ struct buffer { char buf[32]; }; -static struct io_plan *poke_writer(struct io_conn *conn, struct buffer *buf); -static struct io_plan *poke_reader(struct io_conn *conn, struct buffer *buf); +static struct io_plan poke_writer(struct io_conn *conn, struct buffer *buf); +static struct io_plan poke_reader(struct io_conn *conn, struct buffer *buf); -static struct io_plan *plan_read(struct io_conn *conn, struct buffer *buf) +static struct io_plan plan_read(struct io_conn *conn, struct buffer *buf) { assert(conn == buf->reader); @@ -26,7 +26,7 @@ static struct io_plan *plan_read(struct io_conn *conn, struct buffer *buf) poke_writer, buf); } -static struct io_plan *plan_write(struct io_conn *conn, struct buffer *buf) +static struct io_plan plan_write(struct io_conn *conn, struct buffer *buf) { assert(conn == buf->writer); @@ -34,7 +34,7 @@ static struct io_plan *plan_write(struct io_conn *conn, struct buffer *buf) poke_reader, buf); } -static struct io_plan *poke_writer(struct io_conn *conn, struct buffer *buf) +static struct io_plan poke_writer(struct io_conn *conn, struct buffer *buf) { assert(conn == buf->reader); @@ -48,7 +48,7 @@ static struct io_plan *poke_writer(struct io_conn *conn, struct buffer *buf) return io_idle(conn); } -static struct io_plan *poke_reader(struct io_conn *conn, struct buffer *buf) +static struct io_plan poke_reader(struct io_conn *conn, struct buffer *buf) { assert(conn == buf->writer); /* You read. */ @@ -61,7 +61,7 @@ static struct io_plan *poke_reader(struct io_conn *conn, struct buffer *buf) return io_idle(conn); } -static struct io_plan *reader(struct io_conn *conn, struct buffer *buf) +static struct io_plan reader(struct io_conn *conn, struct buffer *buf) { assert(conn == buf->reader); diff --git a/ccan/io/test/run-12-bidir.c b/ccan/io/test/run-12-bidir.c index eb4f4f05..0cafb4f2 100644 --- a/ccan/io/test/run-12-bidir.c +++ b/ccan/io/test/run-12-bidir.c @@ -18,13 +18,13 @@ static void finish_ok(struct io_conn *conn, struct data *d) d->state++; } -static struct io_plan *write_out(struct io_conn *conn, struct data *d) +static struct io_plan write_out(struct io_conn *conn, struct data *d) { d->state++; return io_write(conn, d->wbuf, sizeof(d->wbuf), io_close, d); } -static struct io_plan *start_ok(struct io_conn *conn, struct data *d) +static struct io_plan start_ok(struct io_conn *conn, struct data *d) { ok1(d->state == 0); d->state++; diff --git a/ccan/io/test/run-13-all-idle.c b/ccan/io/test/run-13-all-idle.c index 48be71dd..178b68a8 100644 --- a/ccan/io/test/run-13-all-idle.c +++ b/ccan/io/test/run-13-all-idle.c @@ -7,7 +7,7 @@ #include #include -static struct io_plan *start(struct io_conn *conn, void *unused) +static struct io_plan start(struct io_conn *conn, void *unused) { return io_idle(conn); } diff --git a/ccan/io/test/run-15-timeout.c b/ccan/io/test/run-15-timeout.c index 510a9720..5e94b8c0 100644 --- a/ccan/io/test/run-15-timeout.c +++ b/ccan/io/test/run-15-timeout.c @@ -15,14 +15,14 @@ struct data { }; -static struct io_plan *no_timeout(struct io_conn *conn, struct data *d) +static struct io_plan no_timeout(struct io_conn *conn, struct data *d) { ok1(d->state == 1); d->state++; return io_close(conn, d); } -static struct io_plan *timeout(struct io_conn *conn, struct data *d) +static struct io_plan timeout(struct io_conn *conn, struct data *d) { ok1(d->state == 1); d->state++; @@ -30,7 +30,7 @@ static struct io_plan *timeout(struct io_conn *conn, struct data *d) return io_close(conn, d); } -static struct io_plan *start_ok(struct io_conn *conn, struct data *d) +static struct io_plan start_ok(struct io_conn *conn, struct data *d) { ok1(d->state == 0); d->state++;