5e4a475d |
1 | /* |
2 | * sel.h: subsystem to manage the grubby details of a select loop, |
3 | * buffering data to write, and performing the actual writes and |
4 | * reads. |
5 | */ |
6 | |
7 | #ifndef FIXME_SEL_H |
8 | #define FIXME_SEL_H |
9 | |
10 | typedef struct sel sel; |
11 | typedef struct sel_wfd sel_wfd; |
12 | typedef struct sel_rfd sel_rfd; |
13 | |
14 | /* |
15 | * Callback called when some data is written to a wfd. "bufsize" |
16 | * is the remaining quantity of data buffered in that wfd. |
17 | */ |
18 | typedef void (*sel_written_fn_t)(sel_wfd *wfd, size_t bufsize); |
19 | |
20 | /* |
21 | * Callback called when an error occurs on a wfd, preventing |
22 | * further writing to it. "error" is the errno value. |
23 | */ |
24 | typedef void (*sel_writeerr_fn_t)(sel_wfd *wfd, int error); |
25 | |
26 | /* |
27 | * Callback called when some data is read from an rfd. On EOF, |
28 | * this will be called with len==0. |
29 | */ |
30 | typedef void (*sel_readdata_fn_t)(sel_rfd *rfd, void *data, size_t len); |
31 | |
32 | /* |
33 | * Callback called when an error occurs on an rfd, preventing |
34 | * further reading from it. "error" is the errno value. |
35 | */ |
36 | typedef void (*sel_readerr_fn_t)(sel_rfd *rfd, int error); |
37 | |
38 | /* |
39 | * Create a sel structure, which will oversee a select loop. |
40 | * |
41 | * "ctx" is user-supplied data stored in the sel structure; it can |
42 | * be read and written with sel_get_ctx() and sel_set_ctx(). |
43 | */ |
44 | sel *sel_new(void *ctx); |
45 | |
46 | /* |
47 | * Add a new fd for writing. Returns a sel_wfd which identifies |
48 | * that fd in the sel structure, e.g. for putting data into its |
49 | * output buffer. |
50 | * |
51 | * "ctx" is user-supplied data stored in the sel structure; it can |
52 | * be read and written with sel_wfd_get_ctx() and sel_wfd_set_ctx(). |
53 | * |
54 | * "written" and "writeerr" are called from the event loop when |
55 | * things happen. |
56 | * |
57 | * The fd passed in can be -1, in which case it will be assumed to |
58 | * be unwritable at all times. An actual fd can be passed in later |
59 | * using sel_wfd_setfd. |
60 | */ |
61 | sel_wfd *sel_wfd_add(sel *sel, int fd, |
62 | sel_written_fn_t written, sel_writeerr_fn_t writeerr, |
63 | void *ctx); |
64 | |
65 | /* |
66 | * Add a new fd for reading. Returns a sel_rfd which identifies |
67 | * that fd in the sel structure. |
68 | * |
69 | * "ctx" is user-supplied data stored in the sel structure; it can |
70 | * be read and written with sel_rfd_get_ctx() and sel_rfd_set_ctx(). |
71 | * |
72 | * "readdata" and "readerr" are called from the event loop when |
73 | * things happen. "ctx" is passed to both of them. |
74 | */ |
75 | sel_rfd *sel_rfd_add(sel *sel, int fd, |
76 | sel_readdata_fn_t readdata, sel_readerr_fn_t readerr, |
77 | void *ctx); |
78 | |
79 | /* |
80 | * Write data into the output buffer of a wfd. Returns the new |
81 | * size of the output buffer. (You can call it with len==0 if you |
82 | * just want to know the buffer size; in that situation data==NULL |
83 | * is also safe.) |
84 | */ |
85 | size_t sel_write(sel_wfd *wfd, const void *data, size_t len); |
86 | |
87 | /* |
88 | * Freeze and unfreeze an rfd. When frozen, sel will temporarily |
89 | * not attempt to read from it, but all its state is retained so |
90 | * it can be conveniently unfrozen later. (You might use this |
91 | * facility, for instance, if what you were doing with the |
92 | * incoming data could only accept it at a certain rate: freeze |
93 | * the rfd when you've got lots of backlog, and unfreeze it again |
94 | * when things get calmer.) |
95 | */ |
96 | void sel_rfd_freeze(sel_rfd *rfd); |
97 | void sel_rfd_unfreeze(sel_rfd *rfd); |
98 | |
99 | /* |
100 | * Delete a wfd structure from its containing sel. Returns the |
101 | * underlying fd, which the client may now consider itself to own |
102 | * once more. |
103 | */ |
104 | int sel_wfd_delete(sel_wfd *wfd); |
105 | |
106 | /* |
107 | * Delete an rfd structure from its containing sel. Returns the |
108 | * underlying fd, which the client may now consider itself to own |
109 | * once more. |
110 | */ |
111 | int sel_rfd_delete(sel_rfd *rfd); |
112 | |
113 | /* |
114 | * NOT IMPLEMENTED YET: useful functions here might be ones which |
115 | * enumerated all the wfds/rfds in a sel structure in some |
116 | * fashion, so you could go through them and remove them all while |
117 | * doing sensible things to them. Or, at the very least, just |
118 | * return an arbitrary one of the wfds/rfds. |
119 | */ |
120 | |
121 | /* |
122 | * Free a sel structure and all its remaining wfds and rfds. |
123 | */ |
124 | void sel_free(sel *sel); |
125 | |
126 | /* |
127 | * Read and write the ctx parameters in sel, sel_wfd and sel_rfd. |
128 | */ |
129 | void *sel_get_ctx(sel *sel); |
130 | void sel_set_ctx(sel *sel, void *ctx); |
131 | void *sel_wfd_get_ctx(sel_wfd *wfd); |
132 | void sel_wfd_set_ctx(sel_wfd *wfd, void *ctx); |
133 | void *sel_rfd_get_ctx(sel_rfd *rfd); |
134 | void sel_rfd_set_ctx(sel_rfd *rfd, void *ctx); |
135 | |
136 | /* |
137 | * Run one iteration of the sel event loop, calling callbacks as |
138 | * necessary. Returns zero on success; in the event of a fatal |
139 | * error, returns the errno value. |
140 | * |
141 | * "timeout" is a value in microseconds to limit the length of the |
142 | * select call. Less than zero means to wait indefinitely. |
143 | */ |
144 | int sel_iterate(sel *sel, long timeout); |
145 | |
146 | /* |
147 | * Change the underlying fd in a wfd. If set to -1, no write |
148 | * attempts will take place and the wfd's buffer will simply store |
149 | * everything passed to sel_write(). If later set to something |
150 | * other than -1, all that buffered data will become eligible for |
151 | * real writing. |
152 | */ |
153 | void sel_wfd_setfd(sel_wfd *wfd, int fd); |
154 | |
155 | /* |
156 | * Change the underlying fd in a rfd. If set to -1, no read |
157 | * attempts will take place. |
158 | */ |
159 | void sel_rfd_setfd(sel_rfd *rfd, int fd); |
160 | |
161 | #endif /* FIXME_SEL_H */ |