From: Rusty Russell Date: Mon, 4 Aug 2014 08:14:21 +0000 (+0930) Subject: ccan/io: implement debug. X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=318f717e34e4735e5397bee24dbbee69205be82b ccan/io: implement debug. Now a simple flag, with an external toggle (no compile time DEBUG define required). But it's completely synchronous. Signed-off-by: Rusty Russell --- diff --git a/ccan/io/_info b/ccan/io/_info index 2e0018ad..42b71d9e 100644 --- a/ccan/io/_info +++ b/ccan/io/_info @@ -133,6 +133,7 @@ int main(int argc, char *argv[]) return 1; if (strcmp(argv[1], "depends") == 0) { + printf("ccan/container_of\n"); printf("ccan/list\n"); printf("ccan/tal\n"); printf("ccan/time\n"); diff --git a/ccan/io/backend.h b/ccan/io/backend.h index 44e64ab1..9f8c546c 100644 --- a/ccan/io/backend.h +++ b/ccan/io/backend.h @@ -25,6 +25,9 @@ struct io_listener { /* One connection per client. */ struct io_conn { struct fd fd; + bool debug; + /* For duplex to save. */ + bool debug_saved; /* always or closing list. */ struct io_conn *list; @@ -44,7 +47,7 @@ void del_listener(struct io_listener *l); void backend_new_closing(struct io_conn *conn); void backend_new_always(struct io_conn *conn); void backend_new_plan(struct io_conn *conn); - +void remove_from_always(struct io_conn *conn); void backend_plan_done(struct io_conn *conn); void backend_wake(const void *wait); diff --git a/ccan/io/io.c b/ccan/io/io.c index 23e80704..85d4654d 100644 --- a/ccan/io/io.c +++ b/ccan/io/io.c @@ -10,6 +10,7 @@ #include #include #include +#include void *io_loop_return; @@ -80,6 +81,7 @@ struct io_conn *io_new_conn_(const tal_t *ctx, int fd, conn->finish = NULL; conn->finish_arg = NULL; conn->list = NULL; + conn->debug = false; if (!add_conn(conn)) return tal_free(conn); @@ -116,12 +118,9 @@ static struct io_plan *set_always(struct io_conn *conn, void *), void *arg) { - plan->next = next; - plan->next_arg = arg; plan->status = IO_ALWAYS; - backend_new_always(conn); - return plan; + return io_set_plan(conn, plan, NULL, next, arg); } struct io_plan *io_always_(struct io_conn *conn, @@ -138,9 +137,7 @@ struct io_plan *io_always_(struct io_conn *conn, plan = io_get_plan(conn, IO_OUT); assert(next); - set_always(conn, plan, next, arg); - - return plan; + return set_always(conn, plan, next, arg); } static int do_write(int fd, struct io_plan *plan) @@ -161,18 +158,13 @@ struct io_plan *io_write_(struct io_conn *conn, const void *data, size_t len, { struct io_plan *plan = io_get_plan(conn, IO_OUT); - assert(next); - if (len == 0) return set_always(conn, plan, next, arg); plan->u1.const_vp = data; plan->u2.s = len; - plan->io = do_write; - plan->next = next; - plan->next_arg = arg; - return plan; + return io_set_plan(conn, plan, do_write, next, arg); } static int do_read(int fd, struct io_plan *plan) @@ -201,11 +193,8 @@ struct io_plan *io_read_(struct io_conn *conn, plan->u1.cp = data; plan->u2.s = len; - plan->io = do_read; - plan->next = next; - plan->next_arg = arg; - return plan; + return io_set_plan(conn, plan, do_read, next, arg); } static int do_read_partial(int fd, struct io_plan *plan) @@ -227,8 +216,6 @@ struct io_plan *io_read_partial_(struct io_conn *conn, { struct io_plan *plan = io_get_plan(conn, IO_IN); - assert(next); - if (maxlen == 0) return set_always(conn, plan, next, arg); @@ -236,11 +223,8 @@ struct io_plan *io_read_partial_(struct io_conn *conn, /* We store the max len in here temporarily. */ *len = maxlen; plan->u2.vp = len; - plan->io = do_read_partial; - plan->next = next; - plan->next_arg = arg; - return plan; + return io_set_plan(conn, plan, do_read_partial, next, arg); } static int do_write_partial(int fd, struct io_plan *plan) @@ -262,8 +246,6 @@ struct io_plan *io_write_partial_(struct io_conn *conn, { struct io_plan *plan = io_get_plan(conn, IO_OUT); - assert(next); - if (maxlen == 0) return set_always(conn, plan, next, arg); @@ -271,11 +253,8 @@ struct io_plan *io_write_partial_(struct io_conn *conn, /* We store the max len in here temporarily. */ *len = maxlen; plan->u2.vp = len; - plan->io = do_write_partial; - plan->next = next; - plan->next_arg = arg; - return plan; + return io_set_plan(conn, plan, do_write_partial, next, arg); } static int do_connect(int fd, struct io_plan *plan) @@ -319,11 +298,7 @@ struct io_plan *io_connect_(struct io_conn *conn, const struct addrinfo *addr, if (errno != EINPROGRESS) return io_close(conn); - plan->next = next; - plan->next_arg = arg; - plan->io = do_connect; - - return plan; + return io_set_plan(conn, plan, do_connect, next, arg); } struct io_plan *io_wait_(struct io_conn *conn, @@ -340,14 +315,10 @@ struct io_plan *io_wait_(struct io_conn *conn, else plan = io_get_plan(conn, IO_OUT); - assert(next); - - plan->next = next; - plan->next_arg = arg; - plan->u1.const_vp = wait; plan->status = IO_WAITING; + plan->u1.const_vp = wait; - return plan; + return io_set_plan(conn, plan, NULL, next, arg); } void io_wake(const void *wait) @@ -355,11 +326,11 @@ void io_wake(const void *wait) backend_wake(wait); } -static void do_plan(struct io_conn *conn, struct io_plan *plan) +static int do_plan(struct io_conn *conn, struct io_plan *plan) { /* Someone else might have called io_close() on us. */ if (plan->status == IO_CLOSING) - return; + return -1; /* We shouldn't have polled for this event if this wasn't true! */ assert(plan->status == IO_POLLING); @@ -367,12 +338,12 @@ static void do_plan(struct io_conn *conn, struct io_plan *plan) switch (plan->io(conn->fd.fd, plan)) { case -1: io_close(conn); - break; + return -1; case 0: - break; + return 0; case 1: next_plan(conn, plan); - break; + return 1; default: /* IO should only return -1, 0 or 1 */ abort(); @@ -414,7 +385,7 @@ struct io_plan *io_close(struct io_conn *conn) conn->plan[IO_IN].u1.s = errno; backend_new_closing(conn); - return &conn->plan[IO_IN]; + return io_set_plan(conn, &conn->plan[IO_IN], NULL, NULL, NULL); } struct io_plan *io_close_cb(struct io_conn *conn, void *arg) @@ -439,10 +410,85 @@ int io_conn_fd(const struct io_conn *conn) return conn->fd.fd; } -struct io_plan *io_duplex(struct io_plan *in_plan, struct io_plan *out_plan) +void io_duplex_prepare(struct io_conn *conn) +{ + assert(conn->plan[IO_IN].status == IO_UNSET); + assert(conn->plan[IO_OUT].status == IO_UNSET); + + conn->debug_saved = conn->debug; + conn->debug = false; +} + +struct io_plan *io_duplex_(struct io_plan *in_plan, struct io_plan *out_plan) { + struct io_conn *conn; + /* in_plan must be conn->plan[IO_IN], out_plan must be [IO_OUT] */ assert(out_plan == in_plan + 1); + /* Restore debug. */ + conn = container_of(in_plan, struct io_conn, plan[IO_IN]); + conn->debug = conn->debug_saved; + + /* Now set the plans again, to invoke sync debug. */ + io_set_plan(conn, + out_plan, out_plan->io, out_plan->next, out_plan->next_arg); + io_set_plan(conn, + in_plan, in_plan->io, in_plan->next, in_plan->next_arg); + return out_plan + 1; } + +struct io_plan *io_set_plan(struct io_conn *conn, struct io_plan *plan, + int (*io)(int fd, struct io_plan *plan), + struct io_plan *(*next)(struct io_conn *, void *), + void *next_arg) +{ + struct io_plan *other; + + plan->io = io; + plan->next = next; + plan->next_arg = next_arg; + assert(plan->status == IO_CLOSING || next != NULL); + + if (!conn->debug) + return plan; + + if (io_loop_return) { + io_debug_complete(conn); + return plan; + } + + switch (plan->status) { + case IO_POLLING: + while (do_plan(conn, plan) == 0); + break; + /* Shouldn't happen, since you said you did plan! */ + case IO_UNSET: + abort(); + case IO_ALWAYS: + /* If other one is ALWAYS, leave in list! */ + if (plan == &conn->plan[IO_IN]) + other = &conn->plan[IO_OUT]; + else + other = &conn->plan[IO_IN]; + if (other->status != IO_ALWAYS) + remove_from_always(conn); + next_plan(conn, plan); + break; + case IO_WAITING: + case IO_CLOSING: + io_debug_complete(conn); + } + + return plan; +} + +void io_set_debug(struct io_conn *conn, bool debug) +{ + conn->debug = debug; +} + +void io_debug_complete(struct io_conn *conn) +{ +} diff --git a/ccan/io/io.h b/ccan/io/io.h index 165ff6f6..1341b6f2 100644 --- a/ccan/io/io.h +++ b/ccan/io/io.h @@ -432,11 +432,16 @@ struct io_plan *io_connect_(struct io_conn *conn, const struct addrinfo *addr, * * static struct io_plan *read_and_write(struct io_conn *conn, struct buf *b) * { - * return io_duplex(io_read(conn, b->in, sizeof(b->in), io_close_cb, b), - * io_write(conn, b->out, sizeof(b->out), io_close_cb, b)); + * return io_duplex(conn, + * io_read(conn, b->in, sizeof(b->in), io_close_cb, b), + * io_write(conn, b->out, sizeof(b->out), io_close_cb,b)); * } */ -struct io_plan *io_duplex(struct io_plan *in_plan, struct io_plan *out_plan); +#define io_duplex(conn, in_plan, out_plan) \ + (io_duplex_prepare(conn), io_duplex_(in_plan, out_plan)) + +struct io_plan *io_duplex_(struct io_plan *in_plan, struct io_plan *out_plan); +void io_duplex_prepare(struct io_conn *conn); /** * io_wait - leave a plan idle until something wakes us. @@ -575,4 +580,38 @@ void *io_loop(struct timers *timers, struct list_head *expired); * Sometimes useful, eg for getsockname(). */ int io_conn_fd(const struct io_conn *conn); + +/** + * io_set_debug - set synchronous mode on a connection. + * @conn: the connection. + * @debug: whether to enable or disable debug. + * + * Once @debug is true on a connection, all I/O is done synchronously + * as soon as it is set, until it is unset or @conn is closed. This + * makes it easy to debug what's happening with a connection, but note + * that other connections are starved while this is being done. + * + * See also: io_debug_complete() + * + * Example: + * // Dumb init function to set debug and tell conn to close. + * static struct io_plan *conn_init(struct io_conn *conn, const char *msg) + * { + * io_set_debug(conn, true); + * return io_close(conn); + * } + */ +void io_set_debug(struct io_conn *conn, bool debug); + +/** + * io_debug_complete - empty function called when conn is closing/waiting. + * @conn: the connection. + * + * This is for putting a breakpoint onto, when debugging. It is called + * when a conn with io_set_debug() true can no longer be synchronous: + * 1) It is io_close()'d + * 2) It enters io_wait() (sychronous debug will resume after io_wake()) + * 3) io_break() is called (sychronous debug will resume after io_loop()) + */ +void io_debug_complete(struct io_conn *conn); #endif /* CCAN_IO_H */ diff --git a/ccan/io/io_plan.h b/ccan/io/io_plan.h index 21a19217..3bc2770f 100644 --- a/ccan/io/io_plan.h +++ b/ccan/io/io_plan.h @@ -52,7 +52,51 @@ struct io_plan { union io_plan_arg u1, u2; }; -/* Helper to get a conn's io_plan. */ +/** + * io_get_plan - get a conn's io_plan for a given direction. + * @conn: the connection. + * @dir: IO_IN or IO_OUT. + * + * This is how an io helper gets a plan to store into; you must call + * io_done_plan() when you've initialized it. + * + * Example: + * // Simple helper to read a single char. + * static int do_readchar(int fd, struct io_plan *plan) + * { + * return read(fd, plan->u1.cp, 1) <= 0 ? -1 : 1; + * } + * + * struct io_plan *io_read_char_(struct io_conn *conn, char *in, + * struct io_plan *(*next)(struct io_conn*,void*), + * void *arg) + * { + * struct io_plan *plan = io_get_plan(conn, IO_IN); + * + * // Store information we need in the plan unions u1 and u2. + * plan->u1.cp = in; + * + * return io_set_plan(conn, plan, do_readchar, next, arg); + * } + */ struct io_plan *io_get_plan(struct io_conn *conn, enum io_direction dir); +/** + * io_set_plan - set a conn's io_plan. + * @conn: the connection. + * @plan: the plan + * @io: the IO function to call when the fd is ready. + * @next: the next callback when @io returns 1. + * @next_arg: the argument to @next. + * + * If @conn has debug set, the io function will be called immediately, + * so it's important that this be the last thing in your function! + * + * See also: + * io_get_plan() + */ +struct io_plan *io_set_plan(struct io_conn *conn, struct io_plan *plan, + int (*io)(int fd, struct io_plan *plan), + struct io_plan *(*next)(struct io_conn *, void *), + void *next_arg); #endif /* CCAN_IO_PLAN_H */ diff --git a/ccan/io/poll.c b/ccan/io/poll.c index e4058766..1564444b 100644 --- a/ccan/io/poll.c +++ b/ccan/io/poll.c @@ -88,17 +88,21 @@ bool add_listener(struct io_listener *l) return true; } -void backend_new_closing(struct io_conn *conn) +void remove_from_always(struct io_conn *conn) { - /* Already on always list? Remove it. */ - if (conn->list) { - struct io_conn **p = &always; + struct io_conn **p = &always; - while (*p != conn) - p = &(*p)->list; + while (*p != conn) + p = &(*p)->list; - *p = conn->list; - } + *p = conn->list; +} + +void backend_new_closing(struct io_conn *conn) +{ + /* Already on always list? Remove it. */ + if (conn->list) + remove_from_always(conn); conn->list = closing; closing = conn; diff --git a/ccan/io/test/run-01-start-finish-debug.c b/ccan/io/test/run-01-start-finish-debug.c new file mode 100644 index 00000000..bc43299f --- /dev/null +++ b/ccan/io/test/run-01-start-finish-debug.c @@ -0,0 +1,2 @@ +#define DEBUG_CONN +#include "run-01-start-finish.c" diff --git a/ccan/io/test/run-01-start-finish.c b/ccan/io/test/run-01-start-finish.c index eb2c90a6..eb12e948 100644 --- a/ccan/io/test/run-01-start-finish.c +++ b/ccan/io/test/run-01-start-finish.c @@ -6,7 +6,9 @@ #include #include -#ifndef PORT +#ifdef DEBUG_CONN +#define PORT "64001" +#else #define PORT "65001" #endif static int expected_fd; @@ -21,6 +23,9 @@ static void finish_ok(struct io_conn *conn, int *state) static struct io_plan *init_conn(struct io_conn *conn, int *state) { +#ifdef DEBUG_CONN + io_set_debug(conn, true); +#endif ok1(*state == 0); (*state)++; expected_fd = io_conn_fd(conn); diff --git a/ccan/io/test/run-02-read-debug.c b/ccan/io/test/run-02-read-debug.c new file mode 100644 index 00000000..eba1363d --- /dev/null +++ b/ccan/io/test/run-02-read-debug.c @@ -0,0 +1,2 @@ +#define DEBUG_CONN +#include "run-02-read.c" diff --git a/ccan/io/test/run-02-read.c b/ccan/io/test/run-02-read.c index b43bb8bf..e25bbbb4 100644 --- a/ccan/io/test/run-02-read.c +++ b/ccan/io/test/run-02-read.c @@ -6,7 +6,9 @@ #include #include -#ifndef PORT +#ifdef DEBUG_CONN +#define PORT "64002" +#else #define PORT "65002" #endif @@ -24,6 +26,9 @@ static void finish_ok(struct io_conn *conn, struct data *d) static struct io_plan *init_conn(struct io_conn *conn, struct data *d) { +#ifdef DEBUG_CONN + io_set_debug(conn, true); +#endif ok1(d->state == 0); d->state++; diff --git a/ccan/io/test/run-03-readpartial-debug.c b/ccan/io/test/run-03-readpartial-debug.c new file mode 100644 index 00000000..7c9f8c4e --- /dev/null +++ b/ccan/io/test/run-03-readpartial-debug.c @@ -0,0 +1,2 @@ +#define DEBUG_CONN +#include "run-03-readpartial.c" diff --git a/ccan/io/test/run-03-readpartial.c b/ccan/io/test/run-03-readpartial.c index 2d15c2f5..7c24d16e 100644 --- a/ccan/io/test/run-03-readpartial.c +++ b/ccan/io/test/run-03-readpartial.c @@ -6,7 +6,9 @@ #include #include -#ifndef PORT +#ifdef DEBUG_CONN +#define PORT "64003" +#else #define PORT "65003" #endif @@ -25,6 +27,9 @@ static void finish_ok(struct io_conn *conn, struct data *d) static struct io_plan *init_conn(struct io_conn *conn, struct data *d) { +#ifdef DEBUG_CONN + io_set_debug(conn, true); +#endif ok1(d->state == 0); d->state++; diff --git a/ccan/io/test/run-04-writepartial-debug.c b/ccan/io/test/run-04-writepartial-debug.c new file mode 100644 index 00000000..dd40c0c9 --- /dev/null +++ b/ccan/io/test/run-04-writepartial-debug.c @@ -0,0 +1,2 @@ +#define DEBUG_CONN +#include "run-04-writepartial.c" diff --git a/ccan/io/test/run-04-writepartial.c b/ccan/io/test/run-04-writepartial.c index 011bbc89..d3f7043f 100644 --- a/ccan/io/test/run-04-writepartial.c +++ b/ccan/io/test/run-04-writepartial.c @@ -6,7 +6,9 @@ #include #include -#ifndef PORT +#ifdef DEBUG_CONN +#define PORT "64004" +#else #define PORT "65004" #endif @@ -25,6 +27,9 @@ static void finish_ok(struct io_conn *conn, struct data *d) static struct io_plan *init_conn(struct io_conn *conn, struct data *d) { +#ifdef DEBUG_CONN + io_set_debug(conn, true); +#endif ok1(d->state == 0); d->state++; io_set_finish(conn, finish_ok, d); diff --git a/ccan/io/test/run-05-write-debug.c b/ccan/io/test/run-05-write-debug.c new file mode 100644 index 00000000..5c991283 --- /dev/null +++ b/ccan/io/test/run-05-write-debug.c @@ -0,0 +1,2 @@ +#define DEBUG_CONN +#include "run-05-write.c" diff --git a/ccan/io/test/run-05-write.c b/ccan/io/test/run-05-write.c index b17ef83a..41fe2949 100644 --- a/ccan/io/test/run-05-write.c +++ b/ccan/io/test/run-05-write.c @@ -6,7 +6,9 @@ #include #include -#ifndef PORT +#ifdef DEBUG_CONN +#define PORT "64005" +#else #define PORT "65005" #endif @@ -25,6 +27,9 @@ static void finish_ok(struct io_conn *conn, struct data *d) static struct io_plan *init_conn(struct io_conn *conn, struct data *d) { +#ifdef DEBUG_CONN + io_set_debug(conn, true); +#endif ok1(d->state == 0); d->state++; io_set_finish(conn, finish_ok, d); diff --git a/ccan/io/test/run-06-idle.c b/ccan/io/test/run-06-idle.c index 8f3d5410..57d5e20c 100644 --- a/ccan/io/test/run-06-idle.c +++ b/ccan/io/test/run-06-idle.c @@ -9,7 +9,9 @@ #include #include -#ifndef PORT +#ifdef DEBUG_CONN +#define PORT "64006" +#else #define PORT "65006" #endif diff --git a/ccan/io/test/run-07-break-debug.c b/ccan/io/test/run-07-break-debug.c new file mode 100644 index 00000000..94291c68 --- /dev/null +++ b/ccan/io/test/run-07-break-debug.c @@ -0,0 +1,2 @@ +#define DEBUG_CONN +#include "run-07-break.c" diff --git a/ccan/io/test/run-07-break.c b/ccan/io/test/run-07-break.c index dd192c4d..d13b0f18 100644 --- a/ccan/io/test/run-07-break.c +++ b/ccan/io/test/run-07-break.c @@ -6,7 +6,9 @@ #include #include -#ifndef PORT +#ifdef DEBUG_CONN +#define PORT "64007" +#else #define PORT "65007" #endif @@ -30,6 +32,9 @@ static void finish_ok(struct io_conn *conn, struct data *d) static struct io_plan *init_conn(struct io_conn *conn, struct data *d) { +#ifdef DEBUG_CONN + io_set_debug(conn, true); +#endif ok1(d->state == 0); d->state++; diff --git a/ccan/io/test/run-09-connect-debug.c b/ccan/io/test/run-09-connect-debug.c new file mode 100644 index 00000000..e7f9ddeb --- /dev/null +++ b/ccan/io/test/run-09-connect-debug.c @@ -0,0 +1,2 @@ +#define DEBUG_CONN +#include "run-09-connect.c" diff --git a/ccan/io/test/run-09-connect.c b/ccan/io/test/run-09-connect.c index 09b33387..124b6a1f 100644 --- a/ccan/io/test/run-09-connect.c +++ b/ccan/io/test/run-09-connect.c @@ -6,7 +6,9 @@ #include #include -#ifndef PORT +#ifdef DEBUG_CONN +#define PORT "64009" +#else #define PORT "65009" #endif @@ -33,6 +35,9 @@ static struct io_plan *connected(struct io_conn *conn, struct data *d2) static struct io_plan *init_conn(struct io_conn *conn, struct data *d) { +#ifdef DEBUG_CONN + io_set_debug(conn, true); +#endif ok1(d->state == 0); d->state++; io_close_listener(l); diff --git a/ccan/io/test/run-12-bidir-debug.c b/ccan/io/test/run-12-bidir-debug.c new file mode 100644 index 00000000..af5fd89c --- /dev/null +++ b/ccan/io/test/run-12-bidir-debug.c @@ -0,0 +1,2 @@ +#define DEBUG_CONN +#include "run-12-bidir.c" diff --git a/ccan/io/test/run-12-bidir.c b/ccan/io/test/run-12-bidir.c index bddd7fbe..2ecc5470 100644 --- a/ccan/io/test/run-12-bidir.c +++ b/ccan/io/test/run-12-bidir.c @@ -6,7 +6,9 @@ #include #include -#ifndef PORT +#ifdef DEBUG_CONN +#define PORT "64012" +#else #define PORT "65012" #endif @@ -34,6 +36,9 @@ static struct io_plan *rw_done(struct io_conn *conn, struct data *d) static struct io_plan *init_conn(struct io_conn *conn, struct data *d) { +#ifdef DEBUG_CONN + io_set_debug(conn, true); +#endif ok1(d->state == 0); d->state++; @@ -42,7 +47,8 @@ static struct io_plan *init_conn(struct io_conn *conn, struct data *d) memset(d->wbuf, 7, sizeof(d->wbuf)); io_set_finish(conn, finish_ok, d); - return io_duplex(io_read(conn, d->buf, sizeof(d->buf), rw_done, d), + return io_duplex(conn, + io_read(conn, d->buf, sizeof(d->buf), rw_done, d), io_write(conn, d->wbuf, sizeof(d->wbuf), rw_done, d)); } diff --git a/ccan/io/test/run-14-duplex-both-read-debug.c b/ccan/io/test/run-14-duplex-both-read-debug.c new file mode 100644 index 00000000..92bbb670 --- /dev/null +++ b/ccan/io/test/run-14-duplex-both-read-debug.c @@ -0,0 +1,2 @@ +#define DEBUG_CONN +#include "run-14-duplex-both-read.c" diff --git a/ccan/io/test/run-14-duplex-both-read.c b/ccan/io/test/run-14-duplex-both-read.c index 8cf22aa1..ac334e78 100644 --- a/ccan/io/test/run-14-duplex-both-read.c +++ b/ccan/io/test/run-14-duplex-both-read.c @@ -8,7 +8,9 @@ #include #include -#ifndef PORT +#ifdef DEBUG_CONN +#define PORT "64014" +#else #define PORT "65014" #endif @@ -37,12 +39,16 @@ static struct io_plan *make_duplex(struct io_conn *conn, struct data *d) { d->state++; /* Have duplex read the rest of the buffer. */ - return io_duplex(io_read(conn, d->buf+1, sizeof(d->buf)-1, end, d), + return io_duplex(conn, + io_read(conn, d->buf+1, sizeof(d->buf)-1, end, d), io_write(conn, d->wbuf, sizeof(d->wbuf), end, d)); } static struct io_plan *init_conn(struct io_conn *conn, struct data *d) { +#ifdef DEBUG_CONN + io_set_debug(conn, true); +#endif ok1(d->state == 0); d->state++; diff --git a/ccan/io/test/run-15-timeout.c b/ccan/io/test/run-15-timeout.c index e0a3b05e..e4f3be6d 100644 --- a/ccan/io/test/run-15-timeout.c +++ b/ccan/io/test/run-15-timeout.c @@ -8,7 +8,9 @@ #include #include -#ifndef PORT +#ifdef DEBUG_CONN +#define PORT "64015" +#else #define PORT "65015" #endif @@ -36,6 +38,9 @@ static struct io_plan *no_timeout(struct io_conn *conn, struct data *d) static struct io_plan *init_conn(struct io_conn *conn, struct data *d) { +#ifdef DEBUG_CONN + io_set_debug(conn, true); +#endif ok1(d->state == 0); d->state++; diff --git a/ccan/io/test/run-16-duplex-test-debug.c b/ccan/io/test/run-16-duplex-test-debug.c new file mode 100644 index 00000000..70ef3db9 --- /dev/null +++ b/ccan/io/test/run-16-duplex-test-debug.c @@ -0,0 +1,2 @@ +#define DEBUG_CONN +#include "run-16-duplex-test.c" diff --git a/ccan/io/test/run-16-duplex-test.c b/ccan/io/test/run-16-duplex-test.c index ea588661..20814183 100644 --- a/ccan/io/test/run-16-duplex-test.c +++ b/ccan/io/test/run-16-duplex-test.c @@ -8,7 +8,9 @@ #include #include -#ifndef PORT +#ifdef DEBUG_CONN +#define PORT "64016" +#else #define PORT "65016" #endif @@ -34,6 +36,9 @@ static struct io_plan *io_done(struct io_conn *conn, struct data *d) static struct io_plan *init_conn(struct io_conn *conn, struct data *d) { +#ifdef DEBUG_CONN + io_set_debug(conn, true); +#endif ok1(d->state == 0); d->state++; @@ -43,7 +48,8 @@ static struct io_plan *init_conn(struct io_conn *conn, struct data *d) io_close_listener(d->l); - return io_duplex(io_read(conn, d->buf, sizeof(d->buf), io_done, d), + return io_duplex(conn, + io_read(conn, d->buf, sizeof(d->buf), io_done, d), io_write(conn, d->wbuf, sizeof(d->wbuf), io_done, d)); } diff --git a/ccan/io/test/run-17-homemade-io-debug.c b/ccan/io/test/run-17-homemade-io-debug.c new file mode 100644 index 00000000..e26de11c --- /dev/null +++ b/ccan/io/test/run-17-homemade-io-debug.c @@ -0,0 +1,2 @@ +#define DEBUG_CONN +#include "run-17-homemade-io.c" diff --git a/ccan/io/test/run-17-homemade-io.c b/ccan/io/test/run-17-homemade-io.c index 1087e250..325a7468 100644 --- a/ccan/io/test/run-17-homemade-io.c +++ b/ccan/io/test/run-17-homemade-io.c @@ -6,7 +6,9 @@ #include #include -#ifndef PORT +#ifdef DEBUG_CONN +#define PORT "64017" +#else #define PORT "65017" #endif @@ -77,15 +79,15 @@ static struct io_plan *io_read_packet(struct io_conn *conn, pkt->contents = NULL; plan->u1.vp = pkt; plan->u2.s = 0; - plan->io = do_read_packet; - plan->next = cb; - plan->next_arg = arg; - return plan; + return io_set_plan(conn, plan, do_read_packet, cb, arg); } static struct io_plan *init_conn(struct io_conn *conn, struct packet *pkt) { +#ifdef DEBUG_CONN + io_set_debug(conn, true); +#endif ok1(pkt->state == 0); pkt->state++; diff --git a/ccan/io/test/run-18-errno-debug.c b/ccan/io/test/run-18-errno-debug.c new file mode 100644 index 00000000..f7ffc3d4 --- /dev/null +++ b/ccan/io/test/run-18-errno-debug.c @@ -0,0 +1,2 @@ +#define DEBUG_CONN +#include "run-18-errno.c" diff --git a/ccan/io/test/run-18-errno.c b/ccan/io/test/run-18-errno.c index c19ab375..1bee7682 100644 --- a/ccan/io/test/run-18-errno.c +++ b/ccan/io/test/run-18-errno.c @@ -6,7 +6,9 @@ #include #include -#ifndef PORT +#ifdef DEBUG_CONN +#define PORT "64018" +#else #define PORT "65018" #endif @@ -27,6 +29,9 @@ static void finish_EBADF(struct io_conn *conn, int *state) static struct io_plan *init_conn(struct io_conn *conn, int *state) { +#ifdef DEBUG_CONN + io_set_debug(conn, true); +#endif if (*state == 0) { (*state)++; errno = 100; diff --git a/ccan/io/test/run-19-always-debug.c b/ccan/io/test/run-19-always-debug.c new file mode 100644 index 00000000..f36d58ed --- /dev/null +++ b/ccan/io/test/run-19-always-debug.c @@ -0,0 +1,2 @@ +#define DEBUG_CONN +#include "run-19-always.c" diff --git a/ccan/io/test/run-19-always.c b/ccan/io/test/run-19-always.c index 63eb34e6..7a015f28 100644 --- a/ccan/io/test/run-19-always.c +++ b/ccan/io/test/run-19-always.c @@ -6,7 +6,9 @@ #include #include -#ifndef PORT +#ifdef DEBUG_CONN +#define PORT "64019" +#else #define PORT "65019" #endif @@ -30,6 +32,9 @@ static struct io_plan *write_buf(struct io_conn *conn, struct data *d) static struct io_plan *init_conn(struct io_conn *conn, struct data *d) { +#ifdef DEBUG_CONN + io_set_debug(conn, true); +#endif ok1(d->state == 0); d->state++; io_set_finish(conn, finish_ok, d);