* };
*
* // 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);
* 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);
* 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);
* }
*
* // 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;
*
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;
};
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)
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 */
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);
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);
}
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);
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);
}
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);
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. */
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);
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)
{
}
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)
{
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)) {
}
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)
{
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)) {
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));
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();
}
/* 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;
}
#include <stdbool.h>
#include <unistd.h>
+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.
*/
#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);
*/
#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),
*/
#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.
*/
#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);
/**
*/
#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).
*/
#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);
/**
* 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.
*/
#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.
*/
#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);
*/
#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()
*/
#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 */
* 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.
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--;
}
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;
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)
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--;
}
}
} 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;
#include <sys/wait.h>
#include <stdio.h>
-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)++;
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++;
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++;
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++;
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++;
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++;
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;
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++;
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);
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);
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);
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. */
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);
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++;
#include <stdio.h>
#include <signal.h>
-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);
}
};
-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++;
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++;