From 737705f0c2ec60ea5b51ca55299488d86db37b5d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 14 Oct 2013 21:28:36 +1030 Subject: [PATCH] ccan/io: generic init function for listening connections. Instead of assuming they want a connection made from the new fd, hand the fd to a callback. Signed-off-by: Rusty Russell --- ccan/io/backend.h | 5 ++--- ccan/io/io.c | 9 +++------ ccan/io/io.h | 23 ++++++++--------------- ccan/io/poll.c | 7 +------ ccan/io/test/run-01-start-finish.c | 8 +++++++- ccan/io/test/run-02-read.c | 8 +++++++- ccan/io/test/run-03-readpartial.c | 8 +++++++- ccan/io/test/run-04-writepartial.c | 8 +++++++- ccan/io/test/run-05-write.c | 8 +++++++- ccan/io/test/run-06-idle.c | 8 +++++++- ccan/io/test/run-07-break.c | 8 +++++++- ccan/io/test/run-12-bidir.c | 8 +++++++- ccan/io/test/run-15-timeout.c | 8 +++++++- 13 files changed, 77 insertions(+), 39 deletions(-) diff --git a/ccan/io/backend.h b/ccan/io/backend.h index c03ce2dc..e65c9906 100644 --- a/ccan/io/backend.h +++ b/ccan/io/backend.h @@ -15,9 +15,8 @@ struct io_listener { struct fd fd; /* These are for connections we create. */ - struct io_plan (*next)(struct io_conn *, void *arg); - void (*finish)(struct io_conn *, void *arg); - void *conn_arg; + void (*init)(int fd, void *arg); + void *arg; }; struct io_timeout { diff --git a/ccan/io/io.c b/ccan/io/io.c index bad06939..5ea90ea7 100644 --- a/ccan/io/io.c +++ b/ccan/io/io.c @@ -13,9 +13,7 @@ void *io_loop_return; struct io_listener *io_new_listener_(int fd, - struct io_plan (*start)(struct io_conn *, - void *arg), - void (*finish)(struct io_conn *, void *), + void (*init)(int fd, void *arg), void *arg) { struct io_listener *l = malloc(sizeof(*l)); @@ -25,9 +23,8 @@ struct io_listener *io_new_listener_(int fd, l->fd.listener = true; l->fd.fd = fd; - l->next = start; - l->finish = finish; - l->conn_arg = arg; + l->init = init; + l->arg = arg; if (!add_listener(l)) { free(l); return NULL; diff --git a/ccan/io/io.h b/ccan/io/io.h index e48f15b5..9ba46b67 100644 --- a/ccan/io/io.h +++ b/ccan/io/io.h @@ -93,28 +93,21 @@ struct io_conn *io_new_conn_(int fd, /** * io_new_listener - create a new accepting listener. * @fd: the file descriptor. - * @start: the first function to call on new connections. - * @finish: the function to call when the connection is closed or fails. - * @arg: the argument to both @start and @finish. + * @init: the function to call for a new connection + * @arg: the argument to @init. * - * When @fd becomes readable, we accept() and turn that fd into a new - * connection. + * When @fd becomes readable, we accept() and pass that fd to init(). * * Returns NULL on error (and sets errno). */ -#define io_new_listener(fd, start, finish, arg) \ +#define io_new_listener(fd, init, arg) \ io_new_listener_((fd), \ - typesafe_cb_preargs(struct io_plan, void *, \ - (start), (arg), \ - struct io_conn *), \ - typesafe_cb_preargs(void, void *, (finish), \ - (arg), struct io_conn *), \ + typesafe_cb_preargs(void, void *, \ + (init), (arg), \ + int fd), \ (arg)) struct io_listener *io_new_listener_(int fd, - struct io_plan (*start)(struct io_conn *, - void *arg), - void (*finish)(struct io_conn *, - void *arg), + void (*init)(int fd, void *arg), void *arg); /** diff --git a/ccan/io/poll.c b/ccan/io/poll.c index adf7bb0c..c30bea17 100644 --- a/ccan/io/poll.c +++ b/ccan/io/poll.c @@ -144,17 +144,12 @@ void backend_wakeup(struct io_conn *conn) static void accept_conn(struct io_listener *l) { - struct io_conn *c; int fd = accept(l->fd.fd, NULL, NULL); /* FIXME: What to do here? */ if (fd < 0) return; - c = io_new_conn(fd, l->next, l->finish, l->conn_arg); - if (!c) { - close(fd); - return; - } + l->init(fd, l->arg); } /* It's OK to miss some, as long as we make progress. */ diff --git a/ccan/io/test/run-01-start-finish.c b/ccan/io/test/run-01-start-finish.c index b879a2c8..53c07f24 100644 --- a/ccan/io/test/run-01-start-finish.c +++ b/ccan/io/test/run-01-start-finish.c @@ -20,6 +20,12 @@ static void finish_ok(struct io_conn *conn, int *state) io_break(state + 1, NULL, NULL); } +static void init_conn(int fd, int *state) +{ + if (!io_new_conn(fd, start_ok, finish_ok, state)) + abort(); +} + static int make_listen_fd(const char *port, struct addrinfo **info) { int fd, on = 1; @@ -63,7 +69,7 @@ int main(void) plan_tests(9); fd = make_listen_fd("65001", &addrinfo); ok1(fd >= 0); - l = io_new_listener(fd, start_ok, finish_ok, &state); + l = io_new_listener(fd, init_conn, &state); ok1(l); fflush(stdout); if (!fork()) { diff --git a/ccan/io/test/run-02-read.c b/ccan/io/test/run-02-read.c index e5a6142c..abc66463 100644 --- a/ccan/io/test/run-02-read.c +++ b/ccan/io/test/run-02-read.c @@ -25,6 +25,12 @@ static void finish_ok(struct io_conn *conn, struct data *d) io_break(d, NULL, NULL); } +static void init_conn(int fd, struct data *d) +{ + if (!io_new_conn(fd, start_ok, finish_ok, d)) + abort(); +} + static int make_listen_fd(const char *port, struct addrinfo **info) { int fd, on = 1; @@ -69,7 +75,7 @@ int main(void) d->state = 0; fd = make_listen_fd("65002", &addrinfo); ok1(fd >= 0); - l = io_new_listener(fd, start_ok, finish_ok, d); + l = io_new_listener(fd, init_conn, d); ok1(l); fflush(stdout); if (!fork()) { diff --git a/ccan/io/test/run-03-readpartial.c b/ccan/io/test/run-03-readpartial.c index 0d5f636e..a7d0ae31 100644 --- a/ccan/io/test/run-03-readpartial.c +++ b/ccan/io/test/run-03-readpartial.c @@ -27,6 +27,12 @@ static void finish_ok(struct io_conn *conn, struct data *d) io_break(d, NULL, NULL); } +static void init_conn(int fd, struct data *d) +{ + if (!io_new_conn(fd, start_ok, finish_ok, d)) + abort(); +} + static int make_listen_fd(const char *port, struct addrinfo **info) { int fd, on = 1; @@ -89,7 +95,7 @@ int main(void) d->state = 0; fd = make_listen_fd("65003", &addrinfo); ok1(fd >= 0); - l = io_new_listener(fd, start_ok, finish_ok, d); + l = io_new_listener(fd, init_conn, d); ok1(l); fflush(stdout); if (!fork()) { diff --git a/ccan/io/test/run-04-writepartial.c b/ccan/io/test/run-04-writepartial.c index 5a5b2506..11ac22a7 100644 --- a/ccan/io/test/run-04-writepartial.c +++ b/ccan/io/test/run-04-writepartial.c @@ -26,6 +26,12 @@ static void finish_ok(struct io_conn *conn, struct data *d) io_break(d, NULL, NULL); } +static void init_conn(int fd, struct data *d) +{ + if (!io_new_conn(fd, start_ok, finish_ok, d)) + abort(); +} + static int make_listen_fd(const char *port, struct addrinfo **info) { int fd, on = 1; @@ -91,7 +97,7 @@ int main(void) memset(d->buf, 'a', d->bytes); fd = make_listen_fd("65004", &addrinfo); ok1(fd >= 0); - l = io_new_listener(fd, start_ok, finish_ok, d); + l = io_new_listener(fd, init_conn, d); ok1(l); fflush(stdout); if (!fork()) { diff --git a/ccan/io/test/run-05-write.c b/ccan/io/test/run-05-write.c index 07cc3e0d..3f0a8f98 100644 --- a/ccan/io/test/run-05-write.c +++ b/ccan/io/test/run-05-write.c @@ -26,6 +26,12 @@ static void finish_ok(struct io_conn *conn, struct data *d) io_break(d, NULL, NULL); } +static void init_conn(int fd, struct data *d) +{ + if (!io_new_conn(fd, start_ok, finish_ok, d)) + abort(); +} + static int make_listen_fd(const char *port, struct addrinfo **info) { int fd, on = 1; @@ -94,7 +100,7 @@ int main(void) memset(d->buf, 'a', d->bytes); fd = make_listen_fd("65005", &addrinfo); ok1(fd >= 0); - l = io_new_listener(fd, start_ok, finish_ok, d); + l = io_new_listener(fd, init_conn, d); ok1(l); fflush(stdout); if (!fork()) { diff --git a/ccan/io/test/run-06-idle.c b/ccan/io/test/run-06-idle.c index c5fab50b..314293a5 100644 --- a/ccan/io/test/run-06-idle.c +++ b/ccan/io/test/run-06-idle.c @@ -61,6 +61,12 @@ static void finish_idle(struct io_conn *conn, struct data *d) io_break(d, NULL, NULL); } +static void init_conn(int fd, struct data *d) +{ + if (!io_new_conn(fd, start_idle, finish_idle, d)) + abort(); +} + static int make_listen_fd(const char *port, struct addrinfo **info) { int fd, on = 1; @@ -105,7 +111,7 @@ int main(void) d->state = 0; fd = make_listen_fd("65006", &addrinfo); ok1(fd >= 0); - l = io_new_listener(fd, start_idle, finish_idle, d); + l = io_new_listener(fd, init_conn, d); ok1(l); fflush(stdout); if (!fork()) { diff --git a/ccan/io/test/run-07-break.c b/ccan/io/test/run-07-break.c index d7896591..e8db3889 100644 --- a/ccan/io/test/run-07-break.c +++ b/ccan/io/test/run-07-break.c @@ -31,6 +31,12 @@ static void finish_ok(struct io_conn *conn, struct data *d) d->state++; } +static void init_conn(int fd, struct data *d) +{ + if (!io_new_conn(fd, start_break, finish_ok, d)) + abort(); +} + static int make_listen_fd(const char *port, struct addrinfo **info) { int fd, on = 1; @@ -75,7 +81,7 @@ int main(void) d->state = 0; fd = make_listen_fd("65007", &addrinfo); ok1(fd >= 0); - l = io_new_listener(fd, start_break, finish_ok, d); + l = io_new_listener(fd, init_conn, d); ok1(l); fflush(stdout); if (!fork()) { diff --git a/ccan/io/test/run-12-bidir.c b/ccan/io/test/run-12-bidir.c index 5b39f38d..3534bc31 100644 --- a/ccan/io/test/run-12-bidir.c +++ b/ccan/io/test/run-12-bidir.c @@ -36,6 +36,12 @@ static struct io_plan start_ok(struct io_conn *conn, struct data *d) return io_read(d->buf, sizeof(d->buf), io_close, d); } +static void init_conn(int fd, struct data *d) +{ + if (!io_new_conn(fd, start_ok, finish_ok, d)) + abort(); +} + static int make_listen_fd(const char *port, struct addrinfo **info) { int fd, on = 1; @@ -79,7 +85,7 @@ int main(void) d->state = 0; fd = make_listen_fd("65012", &addrinfo); ok1(fd >= 0); - d->l = io_new_listener(fd, start_ok, finish_ok, d); + d->l = io_new_listener(fd, init_conn, d); ok1(d->l); fflush(stdout); if (!fork()) { diff --git a/ccan/io/test/run-15-timeout.c b/ccan/io/test/run-15-timeout.c index 2f5c60ac..0ff3fc8a 100644 --- a/ccan/io/test/run-15-timeout.c +++ b/ccan/io/test/run-15-timeout.c @@ -45,6 +45,12 @@ static void finish_ok(struct io_conn *conn, struct data *d) io_break(d, NULL, NULL); } +static void init_conn(int fd, struct data *d) +{ + if (!io_new_conn(fd, start_ok, finish_ok, d)) + abort(); +} + static int make_listen_fd(const char *port, struct addrinfo **info) { int fd, on = 1; @@ -91,7 +97,7 @@ int main(void) d->timeout_usec = 100000; fd = make_listen_fd("65002", &addrinfo); ok1(fd >= 0); - l = io_new_listener(fd, start_ok, finish_ok, d); + l = io_new_listener(fd, init_conn, d); ok1(l); fflush(stdout); -- 2.39.2