From 490b63852f281f0d72eb6f6dfa5e0dce36bcbe0d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 12 Nov 2013 20:41:06 +1030 Subject: [PATCH] io: closing one side of a duplex connection closes both. Otherwise, it's a PITA to close a duplexed connection. If necessary we can introduce a half-close to de-deplex later. Signed-off-by: Rusty Russell --- ccan/io/io.c | 14 ++++++++++++++ ccan/io/io.h | 2 +- ccan/io/test/run-12-bidir.c | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/ccan/io/io.c b/ccan/io/io.c index f45589c0..b7452044 100644 --- a/ccan/io/io.c +++ b/ccan/io/io.c @@ -46,6 +46,12 @@ struct io_plan io_debug(struct io_plan plan) current->plan = plan; backend_plan_changed(current); + /* If it closed, close duplex. */ + if (!current->plan.next && current->duplex) { + current->duplex->plan = io_close_(); + backend_plan_changed(current->duplex); + } + /* Call back into the loop immediately. */ io_loop_return = do_io_loop(&ready); @@ -441,6 +447,14 @@ void io_ready(struct io_conn *conn) backend_plan_changed(conn); } set_current(NULL); + + /* If it closed, close duplex. */ + if (!conn->plan.next && conn->duplex) { + set_current(conn->duplex); + conn->duplex->plan = io_close(); + backend_plan_changed(conn->duplex); + set_current(NULL); + } } /* Close the connection, we're done. */ diff --git a/ccan/io/io.h b/ccan/io/io.h index 6248fec0..0318aef3 100644 --- a/ccan/io/io.h +++ b/ccan/io/io.h @@ -394,7 +394,7 @@ bool io_timeout_(struct io_conn *conn, struct timespec ts, * to have two connections for the same fd, and use one for read * operations and one for write. * - * You must io_close() both of them to close the fd. + * Returning io_close() on one will close both fds! * * Example: * static void setup_read_write(int fd, diff --git a/ccan/io/test/run-12-bidir.c b/ccan/io/test/run-12-bidir.c index 1ab0a218..f7a0ecab 100644 --- a/ccan/io/test/run-12-bidir.c +++ b/ccan/io/test/run-12-bidir.c @@ -25,7 +25,7 @@ static void finish_ok(struct io_conn *conn, struct data *d) static struct io_plan write_done(struct io_conn *conn, struct data *d) { d->state++; - return io_close(); + return io_idle(); } static void init_conn(int fd, struct data *d) -- 2.39.2