X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Fio%2Fio.c;h=b3c4c760eb445f4ed6c188de08dd7bbad4cd2b22;hb=e2ce04eac30ec613c858bd4cd2ca12e1c464edb8;hp=c19b25efe8d12acbe6c5ecc669d01ff54c4801c2;hpb=cef578da77d657701616161f3c3bf826186a024e;p=ccan diff --git a/ccan/io/io.c b/ccan/io/io.c index c19b25ef..b3c4c760 100644 --- a/ccan/io/io.c +++ b/ccan/io/io.c @@ -12,6 +12,45 @@ void *io_loop_return; +#ifdef DEBUG +bool io_plan_for_other; +struct io_conn *current; +bool (*io_debug)(struct io_conn *conn); +bool io_debug_wakeup; + +void io_plan_debug(struct io_plan *plan) +{ + if (io_plan_for_other) { + io_plan_for_other = false; + return; + } + + if (!io_debug || !current) + return; + + if (!io_debug(current) && !io_debug_wakeup) + return; + + io_debug_wakeup = false; + current->plan = *plan; + backend_plan_changed(current); + + /* Call back into the loop immediately. */ + io_loop_return = io_loop(); +} + +static void debug_io_wake(struct io_conn *conn) +{ + /* We want linear if we wake a debugged connection, too. */ + if (io_debug && io_debug(conn)) + io_debug_wakeup = true; +} +#else +static void debug_io_wake(struct io_conn *conn) +{ +} +#endif + struct io_listener *io_new_listener_(int fd, void (*init)(int fd, void *arg), void *arg) @@ -138,6 +177,8 @@ struct io_plan io_write_(const void *data, size_t len, plan.next = cb; plan.next_arg = arg; plan.pollflag = POLLOUT; + + io_plan_debug(&plan); return plan; } @@ -169,6 +210,8 @@ struct io_plan io_read_(void *data, size_t len, plan.next = cb; plan.next_arg = arg; plan.pollflag = POLLIN; + + io_plan_debug(&plan); return plan; } @@ -200,6 +243,7 @@ struct io_plan io_read_partial_(void *data, size_t *len, plan.next_arg = arg; plan.pollflag = POLLIN; + io_plan_debug(&plan); return plan; } @@ -231,6 +275,7 @@ struct io_plan io_write_partial_(const void *data, size_t *len, plan.next_arg = arg; plan.pollflag = POLLOUT; + io_plan_debug(&plan); return plan; } @@ -243,10 +288,11 @@ struct io_plan io_idle(void) /* Never called (overridded by io_wake), but NULL means closing */ plan.next = io_close; + io_plan_debug(&plan); return plan; } -void io_wake(struct io_conn *conn, struct io_plan plan) +void io_wake_(struct io_conn *conn, struct io_plan plan) { /* It might be closing, but we haven't called its finish() yet. */ @@ -255,22 +301,21 @@ void io_wake(struct io_conn *conn, struct io_plan plan) /* It was idle, right? */ assert(!conn->plan.io); conn->plan = plan; - backend_wakeup(conn); -} + backend_plan_changed(conn); -static struct io_plan do_next(struct io_conn *conn) -{ - if (timeout_active(conn)) - backend_del_timeout(conn); - return conn->plan.next(conn, conn->plan.next_arg); + debug_io_wake(conn); } -struct io_plan do_ready(struct io_conn *conn) +void io_ready(struct io_conn *conn) { - if (conn->plan.io(conn->fd.fd, &conn->plan)) - return do_next(conn); - - return conn->plan; + if (conn->plan.io(conn->fd.fd, &conn->plan)) { + set_current(conn); + if (timeout_active(conn)) + backend_del_timeout(conn); + conn->plan = conn->plan.next(conn, conn->plan.next_arg); + backend_plan_changed(conn); + set_current(NULL); + } } /* Useful next functions. */ @@ -283,11 +328,12 @@ struct io_plan io_close(struct io_conn *conn, void *arg) /* This means we're closing. */ plan.next = NULL; + io_plan_debug(&plan); return plan; } /* Exit the loop, returning this (non-NULL) arg. */ -struct io_plan io_break(void *ret, struct io_plan plan) +struct io_plan io_break_(void *ret, struct io_plan plan) { assert(ret); io_loop_return = ret;