io: call finish function after fd is actually closed.
authorRusty Russell <rusty@rustcorp.com.au>
Sun, 2 Mar 2014 06:05:10 +0000 (16:35 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Sun, 2 Mar 2014 06:05:10 +0000 (16:35 +1030)
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>
ccan/io/io.h
ccan/io/poll.c

index bcdb11fdd0e0c1f1e9a08aac55a13e0afe888d92..ecbeb0b093bf6f0c43054b9a67e1233cff41bf66 100644 (file)
@@ -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
  * 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:
  * static void finish(struct io_conn *conn, void *unused)
index d7b9eb56b950b5a1b4772525c86bb944b3a60c6f..e3f595c9884c0d2fcea42d598ca3321d067069a8 100644 (file)
@@ -188,11 +188,6 @@ bool add_duplex(struct io_conn *c)
 
 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))
                backend_del_timeout(conn);
        io_alloc.free(conn->timeout);
@@ -205,6 +200,11 @@ void backend_del_conn(struct io_conn *conn)
        } else
                del_fd(&conn->fd);
        num_closing--;
+       if (conn->finish) {
+               /* Saved by io_close */
+               errno = conn->plan.u1.s;
+               conn->finish(conn, conn->finish_arg);
+       }
        free_conn(conn);
 }