X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Fio%2Fio_plan.h;h=1d503133b6ddb24f4f50cb2e4d12c4fb3e9732d3;hb=1d415706a6e948fe6dcc3b5dab45812b297f77a1;hp=21a1921734f41e83d2ed836e157e4849496fb8ad;hpb=6109a0a6140acbbfe5e998f7d7ea1215f035cb90;p=ccan diff --git a/ccan/io/io_plan.h b/ccan/io/io_plan.h index 21a19217..1d503133 100644 --- a/ccan/io/io_plan.h +++ b/ccan/io/io_plan.h @@ -4,9 +4,9 @@ struct io_conn; /** - * union io_plan_arg - scratch space for struct io_plan read/write fns. + * union io_plan_union - type for struct io_plan read/write fns. */ -union io_plan_arg { +union io_plan_union { char *cp; void *vp; const void *const_vp; @@ -14,17 +14,11 @@ union io_plan_arg { char c[sizeof(size_t)]; }; -enum io_plan_status { - /* As before calling next function. */ - IO_UNSET, - /* Normal. */ - IO_POLLING, - /* Waiting for io_wake */ - IO_WAITING, - /* Always do this. */ - IO_ALWAYS, - /* Closing (both plans will be the same). */ - IO_CLOSING +/** + * struct io_plan_arg - scratch space for struct io_plan read/write fns. + */ +struct io_plan_arg { + union io_plan_union u1, u2; }; enum io_direction { @@ -33,26 +27,52 @@ enum io_direction { }; /** - * struct io_plan - one half of I/O to do - * @status: the status of this plan. - * @io: function to call when fd becomes read/writable, returns 0 to be - * called again, 1 if it's finished, and -1 on error (fd will be closed) - * @next: the next function which is called if io returns 1. - * @next_arg: the argument to @next - * @u1, @u2: scratch space for @io. + * io_plan_arg - get a conn's io_plan_arg for a given direction. + * @conn: the connection. + * @dir: IO_IN or IO_OUT. + * + * This is how an io helper gets scratch space to store into; you must call + * io_set_plan() when you've initialized it. + * + * Example: + * #include + * + * // Simple helper to read a single char. + * static int do_readchar(int fd, struct io_plan_arg *arg) + * { + * return read(fd, arg->u1.cp, 1) <= 0 ? -1 : 1; + * } + * + * static struct io_plan *io_read_char_(struct io_conn *conn, char *in, + * struct io_plan *(*next)(struct io_conn*,void*), + * void *next_arg) + * { + * struct io_plan_arg *arg = io_plan_arg(conn, IO_IN); + * + * // Store information we need in the plan unions u1 and u2. + * arg->u1.cp = in; + * + * return io_set_plan(conn, IO_IN, do_readchar, next, next_arg); + * } */ -struct io_plan { - enum io_plan_status status; - - int (*io)(int fd, struct io_plan *plan); - - struct io_plan *(*next)(struct io_conn *, void *arg); - void *next_arg; - - union io_plan_arg u1, u2; -}; - -/* Helper to get a conn's io_plan. */ -struct io_plan *io_get_plan(struct io_conn *conn, enum io_direction dir); +struct io_plan_arg *io_plan_arg(struct io_conn *conn, enum io_direction dir); +/** + * io_set_plan - set a conn's io_plan. + * @conn: the connection. + * @dir: IO_IN or IO_OUT. + * @io: the IO function to call when the fd is ready. + * @next: the next callback when @io returns 1. + * @next_arg: the argument to @next. + * + * If @conn has debug set, the io function will be called immediately, + * so it's important that this be the last thing in your function! + * + * See also: + * io_get_plan_arg() + */ +struct io_plan *io_set_plan(struct io_conn *conn, enum io_direction dir, + int (*io)(int fd, struct io_plan_arg *arg), + struct io_plan *(*next)(struct io_conn *, void *), + void *next_arg); #endif /* CCAN_IO_PLAN_H */