ccan/io: io_set_finish()
authorRusty Russell <rusty@rustcorp.com.au>
Mon, 14 Oct 2013 11:01:16 +0000 (21:31 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Mon, 14 Oct 2013 11:01:16 +0000 (21:31 +1030)
Rather than insisting on supplying them on every call to io_new_conn().
Also, this way it can be changed on a connection.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
20 files changed:
ccan/io/_info
ccan/io/benchmarks/run-different-speed.c
ccan/io/benchmarks/run-length-prefix.c
ccan/io/benchmarks/run-loop.c
ccan/io/io.c
ccan/io/io.h
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-08-hangup-on-idle.c
ccan/io/test/run-08-read-after-hangup.c
ccan/io/test/run-10-many.c
ccan/io/test/run-12-bidir.c
ccan/io/test/run-13-all-idle.c
ccan/io/test/run-15-timeout.c
ccan/io/test/run-17-homemade-io.c

index 0dfb43c60ef52d837d0a00dd7eb95c37a77af7c2..a96ee669eb4ae16fbb229f0c247ebd9beb67bb2f 100644 (file)
  *     sbuf.len = sizeof(sbuf.inbuf);
  *     sbuf.reader = io_new_conn(STDIN_FILENO,
  *                               io_read_partial(sbuf.inbuf, &sbuf.len,
- *                                               wake_writer, &sbuf),
- *                               reader_exit, &sbuf);
- *     sbuf.writer = io_new_conn(tochild[1], io_idle(), fail_child_write,
- *                               &sbuf);
+ *                                               wake_writer, &sbuf));
+ *     sbuf.writer = io_new_conn(tochild[1], io_idle());
  *
  *     out.max = 128;
  *     out.off = 0;
  *     out.buf = malloc(out.max);
  *     from_child = io_new_conn(fromchild[0],
  *                              io_read_partial(out.buf, &out.rlen,
- *                                              read_from_child, &out),
- *                              NULL, NULL);
+ *                                              read_from_child, &out));
  *     if (!sbuf.reader || !sbuf.writer || !from_child)
  *             err(1, "Allocating connections");
  *
+ *     io_set_finish(sbuf.reader, reader_exit, &sbuf);
+ *     io_set_finish(sbuf.writer, fail_child_write, &sbuf);
+ *
  *     io_loop();
  *     wait(&status);
  *
index 7a95fd8426bbbf8020f93db8177c98654da41c07..5ee15ea6d0235ce929b0e171db24e4c8eb977a1e 100644 (file)
@@ -152,12 +152,11 @@ int main(int argc, char *argv[])
                        /* For efficiency, we share client structure */
                        io_new_conn(ret,
                                    io_read(client.request_buffer, REQUEST_SIZE,
-                                           write_reply, &client),
-                                   NULL, NULL);
+                                           write_reply, &client));
                }
        }
 
-       io_new_conn(timeout[0], io_read(&buf, 1, do_timeout, &buf), NULL, NULL);
+       io_new_conn(timeout[0], io_read(&buf, 1, do_timeout, &buf));
 
        close(wake[0]);
        for (i = 0; i < NUM_CHILDREN; i++)
index 5eb33acf87401ae1eeefa18d6b78d5194a01f931..d88e3afaa7e7a69d7bb30cd0853c6ff8aafd6a29 100644 (file)
@@ -157,11 +157,11 @@ int main(int argc, char *argv[])
                                err(1, "Accepting fd");
                        /* For efficiency, we share buffer */
                        client->request_buffer = buffer;
-                       io_new_conn(ret, io_read_header(client), NULL, NULL);
+                       io_new_conn(ret, io_read_header(client));
                }
        }
 
-       io_new_conn(timeout[0], io_read(&buf, 1, do_timeout, &buf), NULL, NULL);
+       io_new_conn(timeout[0], io_read(&buf, 1, do_timeout, &buf));
 
        close(wake[0]);
        for (i = 0; i < NUM_CHILDREN; i++)
index b0e6b02c804fec579ed2d6019b3d266f993aeb7e..b0d383e89b7c2310f0c5a6acf42babfc808d9f3e 100644 (file)
@@ -66,14 +66,13 @@ int main(void)
                memset(buf[i].buf, i, sizeof(buf[i].buf));
                sprintf(buf[i].buf, "%i-%i", i, i);
 
-               buf[i].reader = io_new_conn(last_read, io_idle(), NULL, NULL);
+               buf[i].reader = io_new_conn(last_read, io_idle());
                if (!buf[i].reader)
                        err(1, "Creating reader %i", i);
                buf[i].writer = io_new_conn(fds[1],
                                            io_write(&buf[i].buf,
                                                     sizeof(buf[i].buf),
-                                                    poke_reader, &buf[i]),
-                                           NULL, NULL);
+                                                    poke_reader, &buf[i]));
                if (!buf[i].writer)
                        err(1, "Creating writer %i", i);
                last_read = fds[0];
@@ -83,13 +82,12 @@ int main(void)
        i = 0;
        buf[i].iters = 0;
        sprintf(buf[i].buf, "%i-%i", i, i);
-       buf[i].reader = io_new_conn(last_read, io_idle(), NULL, NULL);
+       buf[i].reader = io_new_conn(last_read, io_idle());
        if (!buf[i].reader)
                err(1, "Creating reader %i", i);
        buf[i].writer = io_new_conn(last_write, io_write(&buf[i].buf,
                                                         sizeof(buf[i].buf),
-                                                        poke_reader, &buf[i]),
-                                   NULL, NULL);
+                                                        poke_reader, &buf[i]));
        if (!buf[i].writer)
                err(1, "Creating writer %i", i);
 
index b3c4c760eb445f4ed6c188de08dd7bbad4cd2b22..70e4f1b5037cff62493baee8b1adc7c6faaaae22 100644 (file)
@@ -78,10 +78,7 @@ void io_close_listener(struct io_listener *l)
        free(l);
 }
 
-struct io_conn *io_new_conn_(int fd,
-                            struct io_plan plan,
-                            void (*finish)(struct io_conn *, void *),
-                            void *arg)
+struct io_conn *io_new_conn_(int fd, struct io_plan plan)
 {
        struct io_conn *conn = malloc(sizeof(*conn));
 
@@ -91,8 +88,8 @@ struct io_conn *io_new_conn_(int fd,
        conn->fd.listener = false;
        conn->fd.fd = fd;
        conn->plan = plan;
-       conn->finish = finish;
-       conn->finish_arg = arg;
+       conn->finish = NULL;
+       conn->finish_arg = NULL;
        conn->duplex = NULL;
        conn->timeout = NULL;
        if (!add_conn(conn)) {
@@ -102,10 +99,15 @@ struct io_conn *io_new_conn_(int fd,
        return conn;
 }
 
-struct io_conn *io_duplex_(struct io_conn *old,
-                          struct io_plan plan,
-                          void (*finish)(struct io_conn *, void *),
-                          void *arg)
+void io_set_finish_(struct io_conn *conn,
+                   void (*finish)(struct io_conn *, void *),
+                   void *arg)
+{
+       conn->finish = finish;
+       conn->finish_arg = arg;
+}
+
+struct io_conn *io_duplex_(struct io_conn *old, struct io_plan plan)
 {
        struct io_conn *conn;
 
@@ -119,8 +121,8 @@ struct io_conn *io_duplex_(struct io_conn *old,
        conn->fd.fd = old->fd.fd;
        conn->plan = plan;
        conn->duplex = old;
-       conn->finish = finish;
-       conn->finish_arg = arg;
+       conn->finish = NULL;
+       conn->finish_arg = NULL;
        conn->timeout = NULL;
        if (!add_duplex(conn)) {
                free(conn);
index 72f805244c91ad89c4404703f4b276608339142f..5820f87750059ebf3fd9a1bfaaac14a0bbc51df8 100644 (file)
@@ -67,25 +67,34 @@ static inline void io_plan_debug(struct io_plan *plan) { }
  * io_new_conn - create a new connection.
  * @fd: the file descriptor.
  * @plan: the first I/O function.
- * @finish: the function to call when it's closed or fails.
- * @arg: the argument to @finish.
  *
  * This creates a connection which owns @fd.  @plan will be called on the
- * next io_loop(), and @finish will be called when an I/O operation
- * fails, or you call io_close() on the connection.
+ * next io_loop().
  *
  * Returns NULL on error (and sets errno).
  */
-#define io_new_conn(fd, plan, finish, arg)                             \
-       (io_plan_other(), io_new_conn_((fd), (plan),                    \
-                                      typesafe_cb_preargs(void, void *, \
-                                                          (finish), (arg), \
-                                                          struct io_conn *), \
-                                      (arg)))
-struct io_conn *io_new_conn_(int fd,
-                            struct io_plan plan,
-                            void (*finish)(struct io_conn *, void *),
-                            void *arg);
+#define io_new_conn(fd, plan)                          \
+       (io_plan_other(), io_new_conn_((fd), (plan)))
+struct io_conn *io_new_conn_(int fd, struct io_plan plan);
+
+/**
+ * io_set_finish - set finish function on a connection.
+ * @conn: the connection.
+ * @finish: the function to call when it's closed or fails.
+ * @arg: the argument to @finish.
+ *
+ * @finish will be called when an I/O operation fails, or you call
+ * io_close() on the connection.
+ */
+#define io_set_finish(conn, finish, arg)                               \
+       io_set_finish_((conn),                                          \
+                      typesafe_cb_preargs(void, void *,                \
+                                          (finish), (arg),             \
+                                          struct io_conn *),           \
+                      (arg))
+void io_set_finish_(struct io_conn *conn,
+                   void (*finish)(struct io_conn *, void *),
+                   void *arg);
 
 /**
  * io_new_listener - create a new accepting listener.
@@ -241,8 +250,6 @@ bool io_timeout_(struct io_conn *conn, struct timespec ts,
  * io_duplex - split an fd into two connections.
  * @conn: a connection.
  * @plan: the first I/O function to call.
- * @finish: the function to call when it's closed or fails.
- * @arg: the argument to @finish.
  *
  * Sometimes you want to be able to simultaneously read and write on a
  * single fd, but io forces a linear call sequence.  The solition is
@@ -251,17 +258,10 @@ bool io_timeout_(struct io_conn *conn, struct timespec ts,
  *
  * You must io_close() both of them to close the fd.
  */
-#define io_duplex(conn, plan, finish, arg)                             \
-       (io_plan_other(), io_duplex_((conn), (plan),                    \
-                                    typesafe_cb_preargs(void, void *,  \
-                                                        (finish), (arg), \
-                                                        struct io_conn *), \
-                                    (arg)))
+#define io_duplex(conn, plan)                          \
+       (io_plan_other(), io_duplex_((conn), (plan)))
 
-struct io_conn *io_duplex_(struct io_conn *conn,
-                          struct io_plan plan,
-                          void (*finish)(struct io_conn *, void *),
-                          void *arg);
+struct io_conn *io_duplex_(struct io_conn *conn, struct io_plan plan);
 
 /**
  * io_wake - wake up an idle connection.
index 074769693f3266843deb2d3d26d98f4e33dca95d..297dbc6f9bd9a6ccb15d7af96fb3c49369099e90 100644 (file)
@@ -21,8 +21,8 @@ static void init_conn(int fd, int *state)
 {
        ok1(*state == 0);
        (*state)++;
-       if (!io_new_conn(fd, io_close(NULL, NULL), finish_ok, state))
-               abort();
+       io_set_finish(io_new_conn(fd, io_close(NULL, NULL)), finish_ok, state);
+
 }
 
 static int make_listen_fd(const char *port, struct addrinfo **info)
index b8c93c36209dd1a81a40a5049d4b13725cb39e7e..65dbe4dca220874a57a73e0ebd7e0901fd472918 100644 (file)
@@ -27,9 +27,9 @@ static void init_conn(int fd, struct data *d)
        ok1(d->state == 0);
        d->state++;
 
-       if (!io_new_conn(fd, io_read(d->buf, sizeof(d->buf), io_close, d),
-                        finish_ok, d))
-               abort();
+       io_set_finish(io_new_conn(fd,
+                                 io_read(d->buf, sizeof(d->buf), io_close, d)),
+                     finish_ok, d);
 }
 
 static int make_listen_fd(const char *port, struct addrinfo **info)
index 5e08b1a2709347af6131af10c54692f5edeaf2d9..d5411848b85673ea0808a4b5aad7e5f8d8924c6e 100644 (file)
@@ -29,9 +29,9 @@ static void init_conn(int fd, struct data *d)
        d->state++;
        d->bytes = sizeof(d->buf);
 
-       if (!io_new_conn(fd, io_read_partial(d->buf, &d->bytes, io_close, d),
-                        finish_ok, d))
-               abort();
+       io_set_finish(io_new_conn(fd,
+                                 io_read_partial(d->buf, &d->bytes, io_close, d)),
+                     finish_ok, d);
 }
 
 static int make_listen_fd(const char *port, struct addrinfo **info)
index 681d9d4de9cb1676b55588a6ea0954b3f42dd932..c80238fe5004145244d87c978cd079e39cf524cb 100644 (file)
@@ -27,9 +27,9 @@ static void init_conn(int fd, struct data *d)
 {
        ok1(d->state == 0);
        d->state++;
-       if (!io_new_conn(fd, io_write_partial(d->buf, &d->bytes, io_close, d),
-                        finish_ok, d))
-               abort();
+       io_set_finish(io_new_conn(fd,
+                                 io_write_partial(d->buf, &d->bytes, io_close, d)),
+                                 finish_ok, d);
 }
 
 static int make_listen_fd(const char *port, struct addrinfo **info)
index f8f30ee59194716fb7466a705b02fa40a865c877..bcbc9cad119e3b82ccc0eb3e12f1838fc734792a 100644 (file)
@@ -27,9 +27,8 @@ static void init_conn(int fd, struct data *d)
 {
        ok1(d->state == 0);
        d->state++;
-       if (!io_new_conn(fd, io_write(d->buf, d->bytes, io_close, d),
-                        finish_ok, d))
-               abort();
+       io_set_finish(io_new_conn(fd, io_write(d->buf, d->bytes, io_close, d)),
+                     finish_ok, d);
 }
 
 static int make_listen_fd(const char *port, struct addrinfo **info)
index 388805a882b4bb31bccfc44790d694a8f1f5a641..b32cbfe225c1e2bd5949509cd9d33558f1ce1712 100644 (file)
@@ -52,12 +52,14 @@ static void init_conn(int fd, struct data *d)
 
        ok1(d->state == 0);
        d->state++;
-       idler = io_new_conn(fd, io_idle(), finish_idle, d);
+       idler = io_new_conn(fd, io_idle());
+       io_set_finish(idler, finish_idle, d);
 
        /* This will wake us up, as read will fail. */
        fd2 = open("/dev/null", O_RDONLY);
        ok1(fd2 >= 0);
-       ok1(io_new_conn(fd2, io_read(idler, 1, never, NULL), finish_waker, d));
+       io_set_finish(io_new_conn(fd2, io_read(idler, 1, never, NULL)),
+                     finish_waker, d);
 }
 
 static int make_listen_fd(const char *port, struct addrinfo **info)
@@ -100,7 +102,7 @@ int main(void)
        int fd, status;
 
        /* This is how many tests you plan to run */
-       plan_tests(14);
+       plan_tests(13);
        d->state = 0;
        fd = make_listen_fd(PORT, &addrinfo);
        ok1(fd >= 0);
index 3ea20bf528cf26da7157a5e9eb91ca786804b41e..6fcaea341b58f1123ab72a322d3260dd71f53ba2 100644 (file)
@@ -33,11 +33,10 @@ static void init_conn(int fd, struct data *d)
        ok1(d->state == 0);
        d->state++;
 
-       if (!io_new_conn(fd,
-                        io_break(d,
-                                 io_read(d->buf, sizeof(d->buf), read_done, d)),
-                        finish_ok, d))
-               abort();
+       io_set_finish(io_new_conn(fd,
+                                 io_break(d,
+                                          io_read(d->buf, sizeof(d->buf), read_done, d))),
+                     finish_ok, d);
 }
 
 static int make_listen_fd(const char *port, struct addrinfo **info)
index 364d7943ac1ae368df886dabbb7369559037b4f9..7463dd98c83e592525fc09b0a30ea250681fef20 100644 (file)
@@ -26,13 +26,12 @@ int main(void)
        ok1(pipe(fds) == 0);
 
        /* Write then close. */
-       io_new_conn(fds[1], io_write("hello there world", 16, io_close, NULL),
-                   NULL, NULL);
-       conn = io_new_conn(fds[0], io_idle(), NULL, NULL);
+       io_new_conn(fds[1], io_write("hello there world", 16, io_close, 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), NULL, NULL);
+       io_new_conn(fds2[0], io_read(buf, 16, io_close, NULL));
 
        /* After half a second, it will read. */
        io_timeout(conn, time_from_msec(500), timeout_wakeup, buf);
index 95eb651cd7e7f78ee894b8ce35ff664a0320301a..56d9a164accddbbd40ba290016a2486a008fd45d 100644 (file)
@@ -23,9 +23,8 @@ int main(void)
        plan_tests(3);
 
        ok1(pipe(fds) == 0);
-       conn = io_new_conn(fds[0], io_idle(), NULL, NULL);
-       io_new_conn(fds[1], io_write("EASYTEST", 8, wake_it, conn),
-                   NULL, NULL);
+       conn = io_new_conn(fds[0], io_idle());
+       io_new_conn(fds[1], io_write("EASYTEST", 8, wake_it, conn));
 
        ok1(io_loop() == NULL);
        ok1(memcmp(inbuf, "EASYTEST", sizeof(inbuf)) == 0);
index 1c39635b62ff674e6b961402d49af94881696f2b..b13e1b4345a34997450b5d3ec62b064286fa0240 100644 (file)
@@ -66,14 +66,13 @@ int main(void)
                sprintf(buf[i].buf, "%i-%i", i, i);
 
                /* Wait for writer to tell us to read. */
-               buf[i].reader = io_new_conn(last_read, io_idle(), NULL, &buf[i]);
+               buf[i].reader = io_new_conn(last_read, io_idle());
                if (!buf[i].reader)
                        break;
                buf[i].writer = io_new_conn(fds[1],
                                            io_write(&buf[i].buf,
                                                     sizeof(buf[i].buf),
-                                                    poke_reader, &buf[i]),
-                                           NULL, &buf[i]);
+                                                    poke_reader, &buf[i]));
                if (!buf[i].writer)
                        break;
                last_read = fds[0];
@@ -84,12 +83,11 @@ int main(void)
        /* Last one completes the cirle. */
        i = 0;
        sprintf(buf[i].buf, "%i-%i", i, i);
-       buf[i].reader = io_new_conn(last_read, io_idle(), NULL, NULL);
+       buf[i].reader = io_new_conn(last_read, io_idle());
        ok1(buf[i].reader);
        buf[i].writer = io_new_conn(last_write,
                                    io_write(&buf[i].buf, sizeof(buf[i].buf),
-                                            poke_reader, &buf[i]),
-                                   NULL, NULL);
+                                            poke_reader, &buf[i]));
        ok1(buf[i].writer);
 
        /* They should eventually exit */
index 812c863c85059be1c0fd8dfce286b063034b63f1..32319232d707fe5b873d994825ed1d8e19d8ce11 100644 (file)
@@ -39,10 +39,11 @@ 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),
-                          finish_ok, d);
-       ok1(io_duplex(conn, io_write(d->wbuf, sizeof(d->wbuf), write_done, d),
-                     finish_ok, d));
+       conn = io_new_conn(fd, io_read(d->buf, sizeof(d->buf), io_close, d));
+       io_set_finish(conn, finish_ok, d);
+       conn = io_duplex(conn, io_write(d->wbuf, sizeof(d->wbuf), write_done, d));
+       ok1(conn);
+       io_set_finish(conn, finish_ok, d);
 }
 
 static int make_listen_fd(const char *port, struct addrinfo **info)
index 7ad6bfe4d0ae14d230f2cefbc970641f8423dfc8..0e7e1565d579fa56b76397dcf05107c12611f63e 100644 (file)
@@ -17,7 +17,7 @@ int main(void)
                int fds[2];
 
                ok1(pipe(fds) == 0);
-               io_new_conn(fds[0], io_idle(), NULL, NULL);
+               io_new_conn(fds[0], io_idle());
                io_loop();
                exit(1);
        }
index f8ea6f4c22891c602c339a60401b89830730b5b7..a3e9526b165692ab8ae60b4e92e4a9adfcb14de2 100644 (file)
@@ -48,8 +48,8 @@ static void init_conn(int fd, struct data *d)
        ok1(d->state == 0);
        d->state++;
 
-       conn = io_new_conn(fd, io_read(d->buf, sizeof(d->buf), no_timeout, d),
-                          finish_ok, d);
+       conn = io_new_conn(fd, io_read(d->buf, sizeof(d->buf), no_timeout, d));
+       io_set_finish(conn, finish_ok, d);
        io_timeout(conn, time_from_usec(d->timeout_usec), timeout, d);
 }
 
index 08c081ec4238a1870637c39eb964b241d822c8c8..8b6f17ad89a6ef21ad292cbf2b6c49317f51028d 100644 (file)
@@ -92,8 +92,8 @@ static void init_conn(int fd, struct packet *pkt)
        ok1(pkt->state == 0);
        pkt->state++;
 
-       if (!io_new_conn(fd, io_read_packet(pkt, io_close, pkt), finish_ok, pkt))
-               abort();
+       io_set_finish(io_new_conn(fd, io_read_packet(pkt, io_close, pkt)),
+                     finish_ok, pkt);
 }
 
 static int make_listen_fd(const char *port, struct addrinfo **info)