]> git.ozlabs.org Git - ccan/blob - ccan/io/io_plan.h
io: io_always, and zero-length operations support.
[ccan] / ccan / io / io_plan.h
1 /* Licensed under LGPLv2.1+ - see LICENSE file for details */
2 #ifndef CCAN_IO_PLAN_H
3 #define CCAN_IO_PLAN_H
4 struct io_conn;
5
6 /**
7  * struct io_plan - a plan of what I/O to do.
8  * @pollflag: POLLIN or POLLOUT.
9  * @io: function to call when fd is available for @pollflag.
10  * @next: function to call after @io returns true.
11  * @next_arg: argument to @next.
12  * @u1: scratch area for I/O.
13  * @u2: scratch area for I/O.
14  *
15  * When the fd is POLLIN or POLLOUT (according to @pollflag), @io is
16  * called.  If it returns -1, io_close() becomed the new plan (and errno
17  * is saved).  If it returns 1, @next is called, otherwise @io is
18  * called again when @pollflag is available.
19  *
20  * You can use this to write your own io_plan functions.
21  */
22 struct io_plan {
23         int pollflag;
24         /* Only NULL if idle. */
25         int (*io)(int fd, struct io_plan *plan);
26         /* Only NULL if closing. */
27         struct io_plan (*next)(struct io_conn *, void *arg);
28         void *next_arg;
29
30         union {
31                 char *cp;
32                 void *vp;
33                 const void *const_vp;
34                 size_t s;
35                 char c[sizeof(size_t)];
36         } u1;
37         union {
38                 char *p;
39                 void *vp;
40                 const void *const_vp;
41                 size_t s;
42                 char c[sizeof(size_t)];
43         } u2;
44 };
45
46 #ifdef DEBUG
47 /**
48  * io_debug_conn - routine to select connection(s) to debug.
49  *
50  * If this is set, the routine should return true if the connection is a
51  * debugging candidate.  If so, the callchain for I/O operations on this
52  * connection will be linear, for easier use of a debugger.
53  *
54  * You will also see calls to any callbacks which wake the connection
55  * which is being debugged.
56  *
57  * Example:
58  *      static bool debug_all(struct io_conn *conn)
59  *      {
60  *              return true();
61  *      }
62  *      ...
63  *      io_debug_conn = debug_all;
64  */
65 extern bool (*io_debug_conn)(struct io_conn *conn);
66
67 /**
68  * io_debug - if we're debugging the current connection, call immediately.
69  *
70  * This determines if we are debugging the current connection: if so,
71  * it immediately applies the plan and calls back into io_loop() to
72  * create a linear call chain.
73  *
74  * Example:
75  *      #define io_idle() io_debug(io_idle_())
76  *      struct io_plan io_idle_(void);
77  */
78 struct io_plan io_debug(struct io_plan plan);
79
80 /**
81  * io_debug_io - return from function which actually does I/O.
82  *
83  * This determines if we are debugging the current connection: if so,
84  * it immediately sets the next function and calls into io_loop() to
85  * create a linear call chain.
86  *
87  * Example:
88  *
89  * static int do_write(int fd, struct io_plan *plan)
90  * {
91  *      ssize_t ret = write(fd, plan->u.write.buf, plan->u.write.len);
92  *      if (ret < 0)
93  *              return io_debug_io(-1);
94  *
95  *      plan->u.write.buf += ret;
96  *      plan->u.write.len -= ret;
97  *      return io_debug_io(plan->u.write.len == 0);
98  * }
99  */
100 int io_debug_io(int ret);
101
102 /**
103  * io_plan_no_debug - mark the next plan not to be called immediately.
104  *
105  * Most routines which take a plan are about to apply it to the current
106  * connection.  We (ab)use this pattern for debugging: as soon as such a
107  * plan is created it is called, to create a linear call chain.
108  *
109  * Some routines, like io_break(), io_duplex() and io_wake() take an
110  * io_plan, but they must not be applied immediately to the current
111  * connection, so we call this first.
112  *
113  * Example:
114  * #define io_break(ret, plan) (io_plan_no_debug(), io_break_((ret), (plan)))
115  * struct io_plan io_break_(void *ret, struct io_plan plan);
116  */
117 #define io_plan_no_debug() ((io_plan_nodebug = true))
118
119 extern bool io_plan_nodebug;
120 #else
121 static inline struct io_plan io_debug(struct io_plan plan)
122 {
123         return plan;
124 }
125 static inline int io_debug_io(int ret)
126 {
127         return ret;
128 }
129 #define io_plan_no_debug() (void)0
130 #endif
131
132 #endif /* CCAN_IO_PLAN_H */