ccan/io: generic init function for listening connections.
authorRusty Russell <rusty@rustcorp.com.au>
Mon, 14 Oct 2013 10:58:36 +0000 (21:28 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Mon, 14 Oct 2013 10:58:36 +0000 (21:28 +1030)
Instead of assuming they want a connection made from the new fd, hand
the fd to a callback.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
13 files changed:
ccan/io/backend.h
ccan/io/io.c
ccan/io/io.h
ccan/io/poll.c
ccan/io/test/run-01-start-finish.c
ccan/io/test/run-02-read.c
ccan/io/test/run-03-readpartial.c
ccan/io/test/run-04-writepartial.c
ccan/io/test/run-05-write.c
ccan/io/test/run-06-idle.c
ccan/io/test/run-07-break.c
ccan/io/test/run-12-bidir.c
ccan/io/test/run-15-timeout.c

index c03ce2dc5f07e2709fa59744f2d0774d2f608551..e65c990683669d8cae1ee67a4fa3c540201a1764 100644 (file)
@@ -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 {
index bad069398e44eb6388d0bf0c2bd969c11764f7d9..5ea90ea7b03437cd7a7a5e69210a6fc85a8a1363 100644 (file)
@@ -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;
index e48f15b52efe25643b64b533871a64778cdcba60..9ba46b67b497a93af6c429954a4e3013ba2e4742 100644 (file)
@@ -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);
 
 /**
index adf7bb0c048ebfd94ce49edbbf73bd72e9855ebb..c30bea1743444b7a024e1c7b20811207c2959f2e 100644 (file)
@@ -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. */
index b879a2c832fee1bcc0253bac85e6bb8a2eb3b692..53c07f24b4a07b0267953966b2a37af6242ea158 100644 (file)
@@ -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()) {
index e5a6142c9677b411e96cc149180b250477bc95a8..abc66463c74eaee691e536d4c2052002f13c3bd3 100644 (file)
@@ -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()) {
index 0d5f636ebc6103e0b2504b3ab929644d6ecbf6fe..a7d0ae3161aa674cc7b22a23ec16c1148cb1cca8 100644 (file)
@@ -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()) {
index 5a5b2506e31525f2fd05b4d8ee05c26db6dbad6c..11ac22a7c2fb79c125171fca873f2375f55eb257 100644 (file)
@@ -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()) {
index 07cc3e0d0546cc42f7b8b399e8092f63c7caba4c..3f0a8f98cb78b27dd75d8bcb1df8a5ef54d81f0c 100644 (file)
@@ -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()) {
index c5fab50b023b9f1cee6965e9b0541303d8a905fa..314293a5f0f2b5d6a145c8b38359056bf4a6bc0a 100644 (file)
@@ -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()) {
index d789659175625da1078450db18912624930115e3..e8db388904638da90f913f9823bae60220337caa 100644 (file)
@@ -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()) {
index 5b39f38dbc1be78fc7ff26a35fe946203b67f712..3534bc3138f92df5aa6bb57e51849aac26ac6f3b 100644 (file)
@@ -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()) {
index 2f5c60ac7893d79af3787302287c032513e00419..0ff3fc8a54a85c207c3552a1fc73528b60069cc6 100644 (file)
@@ -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);