+#ifdef CONFIG_UCW_CLEAN_ABI
+#define block_io_add ucw_block_io_add
+#define block_io_del ucw_block_io_del
+#define block_io_read ucw_block_io_read
+#define block_io_set_timeout ucw_block_io_set_timeout
+#define block_io_write ucw_block_io_write
+#define file_add ucw_file_add
+#define file_chg ucw_file_chg
+#define file_debug ucw_file_debug
+#define file_del ucw_file_del
+#define hook_add ucw_hook_add
+#define hook_debug ucw_hook_debug
+#define hook_del ucw_hook_del
+#define main_cleanup ucw_main_cleanup
+#define main_current ucw_main_current
+#define main_debug_context ucw_main_debug_context
+#define main_delete ucw_main_delete
+#define main_destroy ucw_main_destroy
+#define main_get_time ucw_main_get_time
+#define main_init ucw_main_init
+#define main_loop ucw_main_loop
+#define main_new ucw_main_new
+#define main_step ucw_main_step
+#define main_switch_context ucw_main_switch_context
+#define main_teardown ucw_main_teardown
+#define process_add ucw_process_add
+#define process_debug ucw_process_debug
+#define process_del ucw_process_del
+#define process_fork ucw_process_fork
+#define rec_io_add ucw_rec_io_add
+#define rec_io_del ucw_rec_io_del
+#define rec_io_parse_line ucw_rec_io_parse_line
+#define rec_io_set_timeout ucw_rec_io_set_timeout
+#define rec_io_start_read ucw_rec_io_start_read
+#define rec_io_stop_read ucw_rec_io_stop_read
+#define rec_io_write ucw_rec_io_write
+#define signal_add ucw_signal_add
+#define signal_debug ucw_signal_debug
+#define signal_del ucw_signal_del
+#define timer_add ucw_timer_add
+#define timer_add_rel ucw_timer_add_rel
+#define timer_debug ucw_timer_debug
+#define timer_del ucw_timer_del
+#endif
+
+/***
+ * [[basic]]
+ * Basic operations
+ * ----------------
+ *
+ * First of all, let us take a look at the basic operations with main loop contexts.
+ ***/
+
+/** The main loop context **/
+struct main_context {
+ timestamp_t now; /* [*] Current time in milliseconds since an unknown epoch. See main_get_time(). */
+ timestamp_t idle_time; /* [*] Total time in milliseconds spent by waiting for events. */
+ uns shutdown; /* [*] Setting this to nonzero forces the main_loop() function to terminate. */
+ clist file_list;
+ clist file_active_list;
+ clist hook_list;
+ clist hook_done_list;
+ clist process_list;
+ clist signal_list;
+ uns file_cnt;
+ uns single_step;
+#ifdef CONFIG_UCW_EPOLL
+ int epoll_fd; /* File descriptor used for epoll */
+ struct epoll_event *epoll_events;
+ clist file_recalc_list;
+#else
+ uns poll_table_obsolete;
+ struct pollfd *poll_table;
+ struct main_file **poll_file_table;
+#endif
+ struct main_timer **timer_table; /* Growing array containing the heap of timers */
+ sigset_t want_signals;
+ int sig_pipe_send;
+ int sig_pipe_recv;
+ struct main_file *sig_pipe_file;
+ struct main_signal *sigchld_handler;
+};
+
+struct main_context *main_new(void); /** Create a new context. **/
+
+/**
+ * Delete a context, assuming it does have any event handlers attached. Does nothing if @m is NULL.
+ * It is allowed to call @main_delete() from a hook function of the same context, but you must
+ * never return to the main loop -- e.g., you can exit() the process instead.
+ **/
+void main_delete(struct main_context *m);
+
+/**
+ * Delete a context. If there are any event handlers attached, they are deactivated
+ * (but the responsibility to free the memory there were allocated from lies upon you).
+ * If there are any file handlers, the corresponding file descriptors are closed.
+ **/
+void main_destroy(struct main_context *m);
+
+/** Switch the current context of the calling thread. Returns the previous current context. **/
+struct main_context *main_switch_context(struct main_context *m);
+
+/** Return the current context. Dies if there is none or if the context has been deleted. **/
+struct main_context *main_current(void);
+
+/** Initialize the main loop module and create a top-level context. **/
+void main_init(void);
+
+/** Deinitialize the main loop module, calling @main_delete() on the top-level context. **/
+void main_cleanup(void);
+
+/**
+ * Deinitialize the main loop module, calling @main_destroy() on the top-level context.
+ * This is especially useful in a freshly forked-off child process.
+ **/
+void main_teardown(void);
+
+/**
+ * Start the event loop on the current context.
+ * It will watch the provided objects and call callbacks.
+ * Terminates when someone calls @main_shut_down(),
+ * or when all <<hook,hooks>> return <<enum_main_hook_return,`HOOK_DONE`>>
+ * or at last one <<hook,hook>> returns <<enum_main_hook_return,`HOOK_SHUTDOWN`>>.
+ **/
+void main_loop(void);
+
+/**
+ * Perform a single iteration of the main loop.
+ * Check if there are any events ready and process them.
+ * If there are none, do not wait.
+ **/
+void main_step(void);