/*
* UCW Library -- Main Loop
*
- * (c) 2004--2011 Martin Mares <mj@ucw.cz>
+ * (c) 2004--2012 Martin Mares <mj@ucw.cz>
*
* This software may be freely distributed and used according to the terms
* of the GNU Lesser General Public License.
#ifndef _UCW_MAINLOOP_H
#define _UCW_MAINLOOP_H
-#include "ucw/clists.h"
+#include <ucw/clists.h>
+#include <ucw/process.h>
#include <signal.h>
/** The main loop context **/
struct main_context {
- timestamp_t now; /* [*] Current time in milliseconds since the UNIX epoch. See main_get_time(). */
- ucw_time_t now_seconds; /* [*] Current time in seconds since the epoch. */
+ 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;
/**
* Show the current state of a given context (use @main_debug() for the current context).
- * Available only if LibUCW has been compiled with `CONFIG_DEBUG`.
+ * Available only if LibUCW has been compiled with `CONFIG_UCW_DEBUG`.
**/
void main_debug_context(struct main_context *m);
return main_current()->now;
}
-/** An analog of @main_get_now() returning the number of seconds since the system epoch. **/
-static inline ucw_time_t main_get_now_seconds(void)
-{
- return main_current()->now_seconds;
-}
-
/**
* This is a description of a timer.
* You define the handler function and possibly user-defined data you wish
* timer. It is permitted (and usual) to call this function from the
* timer's handler itself if you want the timer to trigger again.
*
- * The @expire parameter is absolute, use @timer_add_rel() for a relative version.
+ * The @expire parameter is absolute (in the same time scale as @main_get_now()),
+ * use @timer_add_rel() for a relative version.
**/
void timer_add(struct main_timer *tm, timestamp_t expires);
/**
* Removes a timer from the active ones. It is permitted (and common) to call
* this function from the timer's handler itself if you want to deactivate
- * the timer.
+ * the timer. Removing an already removed timer does nothing.
**/
void timer_del(struct main_timer *tm);
+/** Tells whether a timer is running. **/
+static inline int timer_is_active(struct main_timer *tm)
+{
+ return !!tm->expires;
+}
+
/**
* Forces refresh of the current timestamp cached in the active context.
* You usually do not need to call this, since it is called every time the
**/
void main_get_time(void);
-/** Show current state of a timer. Available only if LibUCW has been compiled with `CONFIG_DEBUG`. **/
+/** Show current state of a timer. Available only if LibUCW has been compiled with `CONFIG_UCW_DEBUG`. **/
void timer_debug(struct main_timer *tm);
/***
* Inserts a new hook into the loop.
* The hook will be scheduled at least once before next sleep.
* May be called from inside a hook handler too.
+ * Adding an already added hook is permitted and if the hook has been run,
+ * it will be run again before next sleep.
**/
void hook_add(struct main_hook *ho);
/**
* Removes an existing hook from the loop.
* May be called from inside a hook handler (to delete itself or another hook).
+ * Removing an already removed hook does nothing.
**/
void hook_del(struct main_hook *ho);
-/** Show current state of a hook. Available only if LibUCW has been compiled with `CONFIG_DEBUG`. **/
+/** Tells if a hook is active (i.e., added). **/
+static inline int hook_is_active(struct main_hook *ho)
+{
+ return clist_is_linked(&ho->n);
+}
+
+/** Show current state of a hook. Available only if LibUCW has been compiled with `CONFIG_UCW_DEBUG`. **/
void hook_debug(struct main_hook *ho);
* please use this function first.
*
* Can be called from a handler.
+ * Removing an already removed file does nothing.
**/
void file_del(struct main_file *fi);
-/** Show current state of a file. Available only if LibUCW has been compiled with `CONFIG_DEBUG`. **/
+/** Tells if a file is active (i.e., added). **/
+static inline int file_is_active(struct main_file *fi)
+{
+ return clist_is_linked(&fi->n);
+}
+
+/** Show current state of a file. Available only if LibUCW has been compiled with `CONFIG_UCW_DEBUG`. **/
void file_debug(struct main_file *fi);
/***
/** Activate a block I/O structure. **/
void block_io_add(struct main_block_io *bio, int fd);
-/** Deactivate a block I/O structure. **/
+/** Deactivate a block I/O structure. Calling twice is safe. **/
void block_io_del(struct main_block_io *bio);
/**
**/
void block_io_set_timeout(struct main_block_io *bio, timestamp_t expires_delta);
+/** Tells if a @bio is active (i.e., added). **/
+static inline int block_io_is_active(struct main_block_io *bio)
+{
+ return file_is_active(&bio->file);
+}
+
/***
* [[recordio]]
* Asynchronous record I/O
/** Activate a record I/O structure. **/
void rec_io_add(struct main_rec_io *rio, int fd);
-/** Deactivate a record I/O structure. **/
+/** Deactivate a record I/O structure. Calling twice is safe. **/
void rec_io_del(struct main_rec_io *rio);
/**
RIO_EVENT_EOF = 3, /* Read: EOF seen */
};
+/** Tells if a @rio is active (i.e., added). **/
+static inline int rec_io_is_active(struct main_rec_io *rio)
+{
+ return file_is_active(&rio->file);
+}
+
/***
* [[process]]
* Child processes
* Removes the process from the watched set. This is done
* automatically, when the process terminates, so you need it only
* when you do not want to watch a running process any more.
+ * Removing an already removed process does nothing.
*/
void process_del(struct main_process *mp);
**/
int process_fork(struct main_process *mp);
-/** Show current state of a process. Available only if LibUCW has been compiled with `CONFIG_DEBUG`. **/
+/** Tells if a process is active (i.e., added). **/
+static inline int process_is_active(struct main_process *mp)
+{
+ return clist_is_linked(&mp->n);
+}
+
+/** Show current state of a process. Available only if LibUCW has been compiled with `CONFIG_UCW_DEBUG`. **/
void process_debug(struct main_process *pr);
/***
/** Request a signal to be caught and delivered synchronously. **/
void signal_add(struct main_signal *ms);
-/** Cancel a request for signal catching. **/
+/** Cancel a request for signal catching. Calling twice is safe. **/
void signal_del(struct main_signal *ms);
-/** Show current state of a signal catcher. Available only if LibUCW has been compiled with `CONFIG_DEBUG`. **/
+/** Tells if a signal catcher is active (i.e., added). **/
+static inline int signal_is_active(struct main_signal *ms)
+{
+ return clist_is_linked(&ms->n);
+}
+
+/** Show current state of a signal catcher. Available only if LibUCW has been compiled with `CONFIG_UCW_DEBUG`. **/
void signal_debug(struct main_signal *sg);
#endif