Commit 3f642347 authored by Rusty Russell's avatar Rusty Russell

io: make io_close_taken_fd() unset nonblocking on the fd.

This is what users want, and expect: as demonstrated by the test failure
when not under valgrind!
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent f08b8139
...@@ -73,6 +73,7 @@ bool add_listener(struct io_listener *l); ...@@ -73,6 +73,7 @@ bool add_listener(struct io_listener *l);
bool add_conn(struct io_conn *c); bool add_conn(struct io_conn *c);
bool add_duplex(struct io_conn *c); bool add_duplex(struct io_conn *c);
void del_listener(struct io_listener *l); void del_listener(struct io_listener *l);
void cleanup_conn_without_close(struct io_conn *c);
void backend_new_always(struct io_conn *conn); void backend_new_always(struct io_conn *conn);
void backend_new_plan(struct io_conn *conn); void backend_new_plan(struct io_conn *conn);
void remove_from_always(struct io_conn *conn); void remove_from_always(struct io_conn *conn);
......
...@@ -421,6 +421,14 @@ struct io_plan *io_close_cb(struct io_conn *conn, void *next_arg) ...@@ -421,6 +421,14 @@ struct io_plan *io_close_cb(struct io_conn *conn, void *next_arg)
return io_close(conn); return io_close(conn);
} }
struct io_plan *io_close_taken_fd(struct io_conn *conn)
{
set_blocking(conn->fd.fd, true);
cleanup_conn_without_close(conn);
return io_close(conn);
}
/* Exit the loop, returning this (non-NULL) arg. */ /* Exit the loop, returning this (non-NULL) arg. */
void io_break(const void *ret) void io_break(const void *ret)
{ {
......
...@@ -630,12 +630,14 @@ struct io_plan *io_close_cb(struct io_conn *, void *unused); ...@@ -630,12 +630,14 @@ struct io_plan *io_close_cb(struct io_conn *, void *unused);
/** /**
* io_close_taken_fd - close a connection, but remove the filedescriptor first. * io_close_taken_fd - close a connection, but remove the filedescriptor first.
* @conn: the connection to take the file descriptor from and close, * @conn: the connection to take the file descriptor from and close.
* *
* io_close closes the file descriptor underlying the io_conn; this version does * io_close closes the file descriptor underlying the io_conn; this version does
* not. Presumably you have used io_conn_fd() on it beforehand and will take * not. Presumably you have used io_conn_fd() on it beforehand and will take
* care of the fd yourself. * care of the fd yourself.
* *
* Note that this also turns off O_NONBLOCK on the fd.
*
* Example: * Example:
* static struct io_plan *steal_fd(struct io_conn *conn, int *fd) * static struct io_plan *steal_fd(struct io_conn *conn, int *fd)
* { * {
...@@ -664,7 +666,10 @@ void *io_loop(struct timers *timers, struct timer **expired); ...@@ -664,7 +666,10 @@ void *io_loop(struct timers *timers, struct timer **expired);
* io_conn_fd - get the fd from a connection. * io_conn_fd - get the fd from a connection.
* @conn: the connection. * @conn: the connection.
* *
* Sometimes useful, eg for getsockname(). * Sometimes useful, eg for getsockname(). Note that the fd is O_NONBLOCK.
*
* See Also:
* io_close_taken_fd
*/ */
int io_conn_fd(const struct io_conn *conn); int io_conn_fd(const struct io_conn *conn);
......
...@@ -187,11 +187,10 @@ bool add_conn(struct io_conn *c) ...@@ -187,11 +187,10 @@ bool add_conn(struct io_conn *c)
return true; return true;
} }
struct io_plan *io_close_taken_fd(struct io_conn *conn) void cleanup_conn_without_close(struct io_conn *conn)
{ {
tal_del_destructor(conn, destroy_conn_close_fd); tal_del_destructor(conn, destroy_conn_close_fd);
destroy_conn(conn, false); destroy_conn(conn, false);
return io_close(conn);
} }
static void accept_conn(struct io_listener *l) static void accept_conn(struct io_listener *l)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment