X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Fio%2Fio.h;h=5820f87750059ebf3fd9a1bfaaac14a0bbc51df8;hp=b7249e3a6b916a4ac966b77d81d00e244fd64319;hb=0f16a4197c94bfa84dad56d0cb9a9c20438d0a45;hpb=cef578da77d657701616161f3c3bf826186a024e diff --git a/ccan/io/io.h b/ccan/io/io.h index b7249e3a..5820f877 100644 --- a/ccan/io/io.h +++ b/ccan/io/io.h @@ -8,26 +8,6 @@ struct io_conn; -struct io_state_read { - char *buf; - size_t len; -}; - -struct io_state_write { - const char *buf; - size_t len; -}; - -struct io_state_readpart { - char *buf; - size_t *lenp; -}; - -struct io_state_writepart { - const char *buf; - size_t *lenp; -}; - /** * struct io_plan - returned from a setup function. * @@ -42,35 +22,79 @@ struct io_plan { void *next_arg; union { - struct io_state_read read; - struct io_state_write write; - struct io_state_readpart readpart; - struct io_state_writepart writepart; + struct { + char *buf; + size_t len; + } read; + struct { + const char *buf; + size_t len; + } write; + struct { + char *buf; + size_t *lenp; + } readpart; + struct { + const char *buf; + size_t *lenp; + } writepart; + struct { + void *p; + size_t len; + } ptr_len; + struct { + void *p1; + void *p2; + } ptr_ptr; + struct { + size_t len1; + size_t len2; + } len_len; } u; }; +#ifdef DEBUG +extern bool io_plan_for_other; +extern bool (*io_debug)(struct io_conn *conn); +#define io_plan_other() ((io_plan_for_other = true)) +void io_plan_debug(struct io_plan *plan); +#else +#define io_plan_other() (void)0 +static inline void io_plan_debug(struct io_plan *plan) { } +#endif + /** * io_new_conn - create a new connection. * @fd: the file descriptor. * @plan: the first I/O function. - * @finish: the function to call when it's closed or fails. - * @arg: the argument to @finish. * * This creates a connection which owns @fd. @plan will be called on the - * next io_loop(), and @finish will be called when an I/O operation - * fails, or you call io_close() on the connection. + * next io_loop(). * * Returns NULL on error (and sets errno). */ -#define io_new_conn(fd, plan, finish, arg) \ - io_new_conn_((fd), (plan), \ - typesafe_cb_preargs(void, void *, (finish), (arg), \ - struct io_conn *), \ - (arg)) -struct io_conn *io_new_conn_(int fd, - struct io_plan plan, - void (*finish)(struct io_conn *, void *), - void *arg); +#define io_new_conn(fd, plan) \ + (io_plan_other(), io_new_conn_((fd), (plan))) +struct io_conn *io_new_conn_(int fd, struct io_plan plan); + +/** + * io_set_finish - set finish function on a connection. + * @conn: the connection. + * @finish: the function to call when it's closed or fails. + * @arg: the argument to @finish. + * + * @finish will be called when an I/O operation fails, or you call + * io_close() on the connection. + */ +#define io_set_finish(conn, finish, arg) \ + io_set_finish_((conn), \ + typesafe_cb_preargs(void, void *, \ + (finish), (arg), \ + struct io_conn *), \ + (arg)) +void io_set_finish_(struct io_conn *conn, + void (*finish)(struct io_conn *, void *), + void *arg); /** * io_new_listener - create a new accepting listener. @@ -226,8 +250,6 @@ bool io_timeout_(struct io_conn *conn, struct timespec ts, * io_duplex - split an fd into two connections. * @conn: a connection. * @plan: the first I/O function to call. - * @finish: the function to call when it's closed or fails. - * @arg: the argument to @finish. * * Sometimes you want to be able to simultaneously read and write on a * single fd, but io forces a linear call sequence. The solition is @@ -236,16 +258,10 @@ bool io_timeout_(struct io_conn *conn, struct timespec ts, * * You must io_close() both of them to close the fd. */ -#define io_duplex(conn, plan, finish, arg) \ - io_duplex_((conn), (plan), \ - typesafe_cb_preargs(void, void *, (finish), (arg), \ - struct io_conn *), \ - (arg)) +#define io_duplex(conn, plan) \ + (io_plan_other(), io_duplex_((conn), (plan))) -struct io_conn *io_duplex_(struct io_conn *conn, - struct io_plan plan, - void (*finish)(struct io_conn *, void *), - void *arg); +struct io_conn *io_duplex_(struct io_conn *conn, struct io_plan plan); /** * io_wake - wake up an idle connection. @@ -254,7 +270,8 @@ struct io_conn *io_duplex_(struct io_conn *conn, * * This makes @conn do I/O the next time around the io_loop(). */ -void io_wake(struct io_conn *conn, struct io_plan plan); +#define io_wake(conn, plan) (io_plan_other(), io_wake_((conn), (plan))) +void io_wake_(struct io_conn *conn, struct io_plan plan); /** * io_break - return from io_loop() @@ -267,7 +284,8 @@ void io_wake(struct io_conn *conn, struct io_plan plan); * * If io_loop() is called again, then @plan will be carried out. */ -struct io_plan io_break(void *ret, struct io_plan plan); +#define io_break(ret, plan) (io_plan_other(), io_break_((ret), (plan))) +struct io_plan io_break_(void *ret, struct io_plan plan); /* FIXME: io_recvfrom/io_sendto */