| 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 */ |