X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Fio%2Fio.h;h=72f805244c91ad89c4404703f4b276608339142f;hp=fb6feb4d0b873e058800a634e7843d77ea1f7964;hb=e2ce04eac30ec613c858bd4cd2ca12e1c464edb8;hpb=a5af4b170139a6e6a0dae7535fb00278ed4639c6 diff --git a/ccan/io/io.h b/ccan/io/io.h index fb6feb4d..72f80524 100644 --- a/ccan/io/io.h +++ b/ccan/io/io.h @@ -8,37 +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; -}; - -enum io_result { - RESULT_AGAIN, - RESULT_FINISHED, - RESULT_CLOSE -}; - -enum io_state { - IO_IO, - IO_FINISHED -}; - /** * struct io_plan - returned from a setup function. * @@ -46,19 +15,54 @@ enum io_state { */ struct io_plan { int pollflag; - enum io_state state; - enum io_result (*io)(struct io_conn *conn); + /* Only NULL if idle. */ + bool (*io)(int fd, struct io_plan *plan); + /* Only NULL if closing. */ struct io_plan (*next)(struct io_conn *, void *arg); 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. @@ -73,10 +77,11 @@ struct io_plan { * 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)) + (io_plan_other(), 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 *), @@ -247,10 +252,11 @@ 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)) + (io_plan_other(), io_duplex_((conn), (plan), \ + typesafe_cb_preargs(void, void *, \ + (finish), (arg), \ + struct io_conn *), \ + (arg))) struct io_conn *io_duplex_(struct io_conn *conn, struct io_plan plan, @@ -264,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() @@ -277,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 */