From 1273379185b86aefe5d426d3208289b70044acac Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 14 Nov 2013 12:59:21 +1030 Subject: [PATCH 1/1] io: add io_is_idle(). Turns out to be useful for complex cases. Signed-off-by: Rusty Russell --- ccan/io/io.c | 5 +++++ ccan/io/io.h | 15 +++++++++++++++ ccan/io/test/run-06-idle.c | 3 ++- ccan/io/test/run-14-duplex-both-read.c | 6 ++---- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/ccan/io/io.c b/ccan/io/io.c index 83104f86..54ba7da5 100644 --- a/ccan/io/io.c +++ b/ccan/io/io.c @@ -418,6 +418,11 @@ struct io_plan io_idle_(void) return plan; } +bool io_is_idle(const struct io_conn *conn) +{ + return conn->plan.io == NULL; +} + void io_wake_(struct io_conn *conn, struct io_plan plan) { diff --git a/ccan/io/io.h b/ccan/io/io.h index 0318aef3..df0764bd 100644 --- a/ccan/io/io.h +++ b/ccan/io/io.h @@ -431,6 +431,21 @@ struct io_conn *io_duplex_(struct io_conn *conn, struct io_plan plan); #define io_wake(conn, plan) (io_plan_no_debug(), io_wake_((conn), (plan))) void io_wake_(struct io_conn *conn, struct io_plan plan); +/** + * io_is_idle - is a connection idle? + * + * This can be useful for complex protocols, eg. where you want a connection + * to send something, so you queue it and wake it if it's idle. + * + * Example: + * struct io_conn *sleeper; + * sleeper = io_new_conn(open("/dev/null", O_RDONLY), io_idle()); + * + * assert(io_is_idle(sleeper)); + * io_wake(sleeper, io_write("junk", 4, io_close_cb, NULL)); + */ +bool io_is_idle(const struct io_conn *conn); + /** * io_break - return from io_loop() * @ret: non-NULL value to return from io_loop(). diff --git a/ccan/io/test/run-06-idle.c b/ccan/io/test/run-06-idle.c index 51cca961..455b8608 100644 --- a/ccan/io/test/run-06-idle.c +++ b/ccan/io/test/run-06-idle.c @@ -29,6 +29,7 @@ static struct io_plan read_done(struct io_conn *conn, struct data *d) static void finish_waker(struct io_conn *conn, struct data *d) { + ok1(io_is_idle(idler)); io_wake(idler, io_read(d->buf, sizeof(d->buf), read_done, d)); ok1(d->state == 1); d->state++; @@ -102,7 +103,7 @@ int main(void) int fd, status; /* This is how many tests you plan to run */ - plan_tests(13); + plan_tests(14); d->state = 0; fd = make_listen_fd(PORT, &addrinfo); ok1(fd >= 0); diff --git a/ccan/io/test/run-14-duplex-both-read.c b/ccan/io/test/run-14-duplex-both-read.c index 366f1d44..70bdec0a 100644 --- a/ccan/io/test/run-14-duplex-both-read.c +++ b/ccan/io/test/run-14-duplex-both-read.c @@ -12,8 +12,6 @@ #define PORT "65014" #endif -#define is_idle(conn) ((conn)->plan.io == NULL) - struct data { struct io_listener *l; int state; @@ -32,11 +30,11 @@ static struct io_plan end(struct io_conn *conn, struct data *d) d->state++; /* last one out closes. */ - if (conn == d->c1 && is_idle(d->c2)) + if (conn == d->c1 && io_is_idle(d->c2)) return io_close(); /* last one out closes. */ - if (conn == d->c2 && is_idle(d->c1)) + if (conn == d->c2 && io_is_idle(d->c1)) return io_close(); return io_idle(); -- 2.39.2