2 * UCW Library -- Main Loop
4 * (c) 2004--2005 Martin Mares <mj@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU Lesser General Public License.
10 #ifndef _UCW_MAINLOOP_H
11 #define _UCW_MAINLOOP_H
13 #include "ucw/clists.h"
20 * The description of structures contain some fields marked as `[*]`.
21 * These are the only ones that are user defined. The rest is for
22 * internal use and you must initialize it to zeroes.
30 * This part allows you to know the current time and request
31 * to have your function called when the time comes.
34 extern timestamp_t main_now; /** Current time in milliseconds since UNIX epoch. See @main_get_time(). **/
35 extern ucw_time_t main_now_seconds; /** Current time in seconds since the epoch. **/
36 extern clist main_timer_list, main_file_list, main_hook_list, main_process_list;
39 * This is a description of a timer.
40 * You fill it with a handler function, any user-defined data and
41 * add it using @timer_add().
43 * The handler() function must add it again or delete it with
49 void (*handler)(struct main_timer *tm); /* [*] Function to be called when the timer expires. */
50 void *data; /* [*] Data for use by the handler */
54 * Adds a new timer into the mainloop to be watched and called,
55 * when it expires. It can be used to modify an already running
58 * The @expire parameter is absolute -- you may use
59 * <<var_main_now,`main_now`>>, if you need it relative to now.
61 void timer_add(struct main_timer *tm, timestamp_t expires);
63 * Removes a timer from the watched ones. You need to call this, when
64 * the timer expires and you do not want to use it any more. It can be
65 * used to remove a still active timer too.
67 void timer_del(struct main_timer *tm);
70 * Forces refresh of <<var_main_now,`main_now`>>. You do not usually
71 * need to call this, since it is called every time the loop polls for
72 * changes. It is here if you need extra precision or some of the
73 * hooks takes a long time.
75 void main_get_time(void);
79 * Activity on file descriptors
80 * ----------------------------
82 * You can let the mainloop watch over a set of file descriptors
85 * //TODO: This probably needs some example how the handlers can be
86 * //used, describe the use of this part of module.
91 int fd; /* [*] File descriptor */
92 int (*read_handler)(struct main_file *fi); /* [*] To be called when ready for reading/writing; must call file_chg() afterwards */
93 int (*write_handler)(struct main_file *fi);
94 void (*error_handler)(struct main_file *fi, int cause); /* [*] Handler to call on errors */
95 void *data; /* [*] Data for use by the handlers */
96 byte *rbuf; /* Read/write pointers for use by file_read/write */
100 void (*read_done)(struct main_file *fi); /* [*] Called when file_read is finished; rpos < rlen if EOF */
101 void (*write_done)(struct main_file *fi); /* [*] Called when file_write is finished */
102 struct main_timer timer;
103 struct pollfd *pollfd;
106 enum main_file_err_cause {
112 void file_add(struct main_file *fi);
113 void file_chg(struct main_file *fi);
114 void file_del(struct main_file *fi);
115 void file_read(struct main_file *fi, void *buf, uns len);
116 void file_write(struct main_file *fi, void *buf, uns len);
117 void file_set_timeout(struct main_file *fi, timestamp_t expires);
118 void file_close_all(void); /* Close all known main_file's; frequently used after fork() */
125 * The hooks can be called whenever the mainloop perform an iteration.
126 * You can shutdown the mainloop from within them or request next call
127 * only when the loop is idle (for background operations).
131 * A hook. It contains the function to call and some user data.
133 * The handler() must return one value from
134 * <<enum_main_hook_return,`main_hook_return`>>.
138 int (*handler)(struct main_hook *ho); /* [*] Hook function; returns HOOK_xxx */
139 void *data; /* [*] For use by the handler */
143 * Return value of the hook handler().
144 * Specifies what should happen next.
146 enum main_hook_return {
147 HOOK_IDLE, /* Call again when the main loop becomes idle again */
148 HOOK_RETRY, /* Call again as soon as possible */
149 HOOK_DONE = -1, /* Shut down the main loop if all hooks return this value */
150 HOOK_SHUTDOWN = -2 /* Shut down the main loop immediately */
154 * Inserts a new hook into the loop.
156 void hook_add(struct main_hook *ho);
158 * Removes an existing hook from the loop.
160 void hook_del(struct main_hook *ho);
167 * The main loop can watch child processes and notify you,
168 * when some of them terminates.
172 * Description of a watched process.
173 * You fill in the handler() and `data`.
174 * The rest is set with @process_fork().
176 struct main_process {
178 int pid; /* Process id (0=not running) */
179 int status; /* Exit status (-1=fork failed) */
180 char status_msg[EXIT_STATUS_MSG_SIZE];
181 void (*handler)(struct main_process *mp); /* [*] Called when the process exits; process_del done automatically */
182 void *data; /* [*] For use by the handler */
186 * Asks the mainloop to watch this process.
187 * As it is done automatically in @process_fork(), you need this only
188 * if you removed the process previously by @process_del().
190 void process_add(struct main_process *mp);
192 * Removes the process from the watched set. This is done
193 * automatically, when the process terminates, so you need it only
194 * when you do not want to watch a running process any more.
196 void process_del(struct main_process *mp);
198 * Forks and fills the @mp with information about the new process.
200 * If the fork() succeeds, it:
202 * - Returns 0 in the child.
203 * - Returns 1 in the parent and calls @process_add() on it.
205 * In the case of unsuccessful fork(), it:
207 * - Fills in the `status_msg` and sets `status` to -1.
208 * - Calls the handler() as if the process terminated.
211 int process_fork(struct main_process *mp);
215 * Control of the mainloop
216 * -----------------------
218 * These functions control the mainloop as a whole.
221 extern uns main_shutdown; /** Setting this to nonzero forces the @main_loop() function to terminate. **/
222 void main_init(void); /** Initializes the mainloop structures. Call before any `*_add` function. **/
224 * Start the mainloop.
225 * It will watch the provided objects and call callbacks.
226 * Terminates when someone sets <<var_main_shutdown,`main_shutdown`>>
227 * to nonzero, when all <<hook,hooks>> return
228 * <<enum_main_hook_return,`HOOK_DONE`>> or at last one <<hook,hook>>
229 * returns <<enum_main_hook_return,`HOOK_SHUTDOWN`>>.
231 void main_loop(void);
232 void main_debug(void); /** Prints a lot of debug information about current status of the mainloop. **/