Browse Source

io: call finish function after fd is actually closed.

This turns out to be the right sequence for pettycoin, which
wants to reap the child in the finish routine.  From that sample
size of 1, this is clearly the Right Thing!

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Rusty Russell 12 years ago
parent
commit
710d42d071
2 changed files with 7 additions and 6 deletions
  1. 2 1
      ccan/io/io.h
  2. 5 5
      ccan/io/poll.c

+ 2 - 1
ccan/io/io.h

@@ -39,7 +39,8 @@ struct io_conn *io_new_conn_(int fd, struct io_plan plan);
  *
  *
  * @finish will be called when an I/O operation fails, or you call
  * @finish will be called when an I/O operation fails, or you call
  * io_close() on the connection.  errno will be set to the value
  * io_close() on the connection.  errno will be set to the value
- * after the failed I/O, or at the call to io_close().
+ * after the failed I/O, or at the call to io_close().  The fd
+ * will be closed (unless a duplex) before @finish is called.
  *
  *
  * Example:
  * Example:
  * static void finish(struct io_conn *conn, void *unused)
  * static void finish(struct io_conn *conn, void *unused)

+ 5 - 5
ccan/io/poll.c

@@ -188,11 +188,6 @@ bool add_duplex(struct io_conn *c)
 
 
 void backend_del_conn(struct io_conn *conn)
 void backend_del_conn(struct io_conn *conn)
 {
 {
-	if (conn->finish) {
-		/* Saved by io_close */
-		errno = conn->plan.u1.s;
-		conn->finish(conn, conn->finish_arg);
-	}
 	if (timeout_active(conn))
 	if (timeout_active(conn))
 		backend_del_timeout(conn);
 		backend_del_timeout(conn);
 	io_alloc.free(conn->timeout);
 	io_alloc.free(conn->timeout);
@@ -205,6 +200,11 @@ void backend_del_conn(struct io_conn *conn)
 	} else
 	} else
 		del_fd(&conn->fd);
 		del_fd(&conn->fd);
 	num_closing--;
 	num_closing--;
+	if (conn->finish) {
+		/* Saved by io_close */
+		errno = conn->plan.u1.s;
+		conn->finish(conn, conn->finish_arg);
+	}
 	free_conn(conn);
 	free_conn(conn);
 }
 }