diff --git a/src/cron.c b/src/cron.c index db05562..bd460a8 100644 --- a/src/cron.c +++ b/src/cron.c @@ -37,6 +37,10 @@ #define TFD_SETTIME_FLAGS (TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET) #endif +/** + * At/Cron like timers. + * @file cron.c + */ /** * Create and start an at/cron job watcher @@ -44,20 +48,20 @@ * @param w Pointer to an uev_t watcher * @param cb Callback function for cron job * @param arg Optional callback argument - * @param when First point in time to call @param cb + * @param when First point in time to call @p cb * @param interval For an at job this is zero, for cron the offset interval * - * For at jobs set @param interval to zero and only use @param when. For - * cron jobs, set @param interval to the offset. E.g., if the job should - * run every five minutes set the @param tm_min of struct tm to five. + * For at jobs set @p interval to zero and only use @p when. For + * cron jobs, set @p interval to the offset. E.g., if the job should + * run every five minutes set the @p tm_min of struct tm to five. * * Use mktime() to create the time_t arguments. The special value zero - * may be used for @param when to denote 'now', where 'now' is when the + * may be used for @p when to denote 'now', where 'now' is when the * event loop is started. You can also treat time_t simply as a signed - * integer. E.g., set @param interval to 3600 to create a cron job that + * integer. E.g., set @p interval to 3600 to create a cron job that * runs every hour. * - * @return POSIX OK(0) or non-zero with @param errno set on error. + * @return POSIX OK(0) or non-zero with @p errno set on error. */ int uev_cron_init(uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, time_t when, time_t interval) { @@ -88,10 +92,10 @@ int uev_cron_init(uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, time_t when /** * Reset an at/cron job watcher * @param w Watcher to reset - * @param when First point in time to call @param cb + * @param when First point in time to call @p cb * @param interval For an at job this is zero, for cron the offset interval * - * @return POSIX OK(0) or non-zero with @param errno set on error. + * @return POSIX OK(0) or non-zero with @p errno set on error. */ int uev_cron_set(uev_t *w, time_t when, time_t interval) { @@ -136,7 +140,7 @@ int uev_cron_set(uev_t *w, time_t when, time_t interval) * Start a stopped at/cron job watcher * @param w Watcher to start (again) * - * @return POSIX OK(0) or non-zero with @param errno set on error. + * @return POSIX OK(0) or non-zero with @p errno set on error. */ int uev_cron_start(uev_t *w) { @@ -147,7 +151,7 @@ int uev_cron_start(uev_t *w) * Stop and unregister an at/cron job watcher * @param w Watcher to stop * - * @return POSIX OK(0) or non-zero with @param errno set on error. + * @return POSIX OK(0) or non-zero with @p errno set on error. */ int uev_cron_stop(uev_t *w) { diff --git a/src/event.c b/src/event.c index b1fa34a..3505c68 100644 --- a/src/event.c +++ b/src/event.c @@ -29,6 +29,11 @@ #include "uev.h" +/** + * Linux [eventfd(2)](https://man7.org/linux/man-pages/man2/eventfd.2.html). + * @file event.c + */ + /** * Create a generic event watcher * @param ctx A valid libuEv context @@ -36,7 +41,7 @@ * @param cb Callback when an event is posted * @param arg Optional callback argument * - * @return POSIX OK(0) or non-zero with @param errno set on error. + * @return POSIX OK(0) or non-zero with @p errno set on error. */ int uev_event_init(uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg) { @@ -60,7 +65,7 @@ int uev_event_init(uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg) * Post a generic event * @param w Watcher to post to * - * @return POSIX OK(0) or non-zero with @param errno set on error. + * @return POSIX OK(0) or non-zero with @p errno set on error. */ int uev_event_post(uev_t *w) { @@ -82,7 +87,7 @@ int uev_event_post(uev_t *w) * Stop a generic event watcher * @param w Watcher to stop * - * @return POSIX OK(0) or non-zero with @param errno set on error. + * @return POSIX OK(0) or non-zero with @p errno set on error. */ int uev_event_stop(uev_t *w) { diff --git a/src/io.c b/src/io.c index 37a26ed..ad83309 100644 --- a/src/io.c +++ b/src/io.c @@ -25,6 +25,10 @@ #include #include "uev.h" +/** + * Descriptor backend, capable of watching files, sockets, pipes, etc. + * @file io.c + */ /** * Create an I/O watcher @@ -33,9 +37,9 @@ * @param cb I/O callback * @param arg Optional callback argument * @param fd File descriptor to watch, or -1 to register an empty watcher - * @param events Events to watch for: %UEV_READ, %UEV_WRITE, %UEV_EDGE, %UEV_ONESHOW + * @param events Events to watch for: ::UEV_READ, ::UEV_WRITE, ::UEV_EDGE, ::UEV_ONESHOT * - * @return POSIX OK(0) or non-zero with @param errno set on error. + * @return POSIX OK(0) or non-zero with @p errno set on error. */ int uev_io_init(uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int fd, int events) { @@ -54,9 +58,9 @@ int uev_io_init(uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int fd, int e * Reset an I/O watcher * @param w Pointer to an uev_t watcher * @param fd New file descriptor to monitor - * @param events Requested events to watch for, a mask of %UEV_READ and %UEV_WRITE + * @param events Requested events to watch for, a mask of ::UEV_READ and ::UEV_WRITE * - * @return POSIX OK(0) or non-zero with @param errno set on error. + * @return POSIX OK(0) or non-zero with @p errno set on error. */ int uev_io_set(uev_t *w, int fd, int events) { @@ -73,7 +77,7 @@ int uev_io_set(uev_t *w, int fd, int events) * Start an I/O watcher * @param w Watcher to start (again) * - * @return POSIX OK(0) or non-zero with @param errno set on error. + * @return POSIX OK(0) or non-zero with @p errno set on error. */ int uev_io_start(uev_t *w) { @@ -84,7 +88,7 @@ int uev_io_start(uev_t *w) * Stop an I/O watcher * @param w Watcher to stop * - * @return POSIX OK(0) or non-zero with @param errno set on error. + * @return POSIX OK(0) or non-zero with @p errno set on error. */ int uev_io_stop(uev_t *w) { diff --git a/src/private.h b/src/private.h index 6714f06..09e70f2 100644 --- a/src/private.h +++ b/src/private.h @@ -74,14 +74,14 @@ typedef enum { #define UEV_EVENT_MASK (UEV_ERROR | UEV_READ | UEV_WRITE | UEV_PRI | \ UEV_RDHUP | UEV_HUP | UEV_EDGE | UEV_ONESHOT) -/* Main libuEv context type */ -typedef struct { +/* Main libuEv context type, internal use only! */ +struct uev_ctx { int running; int fd; /* For epoll() */ int maxevents; /* For epoll() */ struct uev *watchers; uint32_t workaround; /* For workarounds, e.g. redirected stdin */ -} uev_ctx_t; +}; /* Forward declare due to dependencys, don't try this at home kids. */ struct uev; @@ -116,7 +116,7 @@ struct uev; uev_type_t /* Internal API for dealing with generic watchers */ -int _uev_watcher_init (uev_ctx_t *ctx, struct uev *w, uev_type_t type, +int _uev_watcher_init (struct uev_ctx *ctx, struct uev *w, uev_type_t type, void (*cb)(struct uev *, void *, int), void *arg, int fd, int events); int _uev_watcher_start (struct uev *w); diff --git a/src/signal.c b/src/signal.c index a9f6caf..6e405c0 100644 --- a/src/signal.c +++ b/src/signal.c @@ -29,6 +29,15 @@ #include "uev.h" +/** + * @file signal.c + * Linux [signalfd(2)](https://man7.org/linux/man-pages/man2/signalfd.2.html). + * + * Notice how uev::siginfo returns a `struct signalfd_siginfo` with useful data + * on the sender of the signal, this information is only available to signal + * callbacks. + */ + /** * Create a signal watcher @@ -38,7 +47,7 @@ * @param arg Optional callback argument * @param signo Signal to watch for * - * @return POSIX OK(0) or non-zero with @param errno set on error. + * @return POSIX OK(0) or non-zero with @p errno set on error. */ int uev_signal_init(uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int signo) { @@ -74,7 +83,7 @@ int uev_signal_init(uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int signo * @param w Watcher to reset * @param signo New signal to watch for * - * @return POSIX OK(0) or non-zero with @param errno set on error. + * @return POSIX OK(0) or non-zero with @p errno set on error. */ int uev_signal_set(uev_t *w, int signo) { @@ -114,7 +123,7 @@ int uev_signal_set(uev_t *w, int signo) * Start a stopped signal watcher * @param w Watcher to start (again) * - * @return POSIX OK(0) or non-zero with @param errno set on error. + * @return POSIX OK(0) or non-zero with @p errno set on error. */ int uev_signal_start(uev_t *w) { @@ -133,7 +142,7 @@ int uev_signal_start(uev_t *w) * Stop a signal watcher * @param w Watcher to stop * - * @return POSIX OK(0) or non-zero with @param errno set on error. + * @return POSIX OK(0) or non-zero with @p errno set on error. */ int uev_signal_stop(uev_t *w) { diff --git a/src/timer.c b/src/timer.c index 45665a0..60ea8ab 100644 --- a/src/timer.c +++ b/src/timer.c @@ -28,6 +28,11 @@ #include "uev.h" +/** + * Monotonic timers, Linux [timerfd(2)](https://man7.org/linux/man-pages/man2/timerfd_create.2.html) + * @file timer.c + */ + static void msec2tspec(int msec, struct timespec *ts) { @@ -46,28 +51,28 @@ static void msec2tspec(int msec, struct timespec *ts) * @param w Pointer to an uev_t watcher * @param cb Callback function * @param arg Optional callback argument - * @param timeout Timeout in milliseconds before @param cb is called - * @param period For periodic timers this is the period time that @param timeout is reset to + * @param timeout Timeout in milliseconds before @p cb is called + * @param period For periodic timers this is the period time that @p timeout is reset to * * This function creates, and optionally starts, a timer watcher. There * are two types of timers: one-shot and periodic. * - * One-shot timers only use @param timeout, @param period is zero. + * One-shot timers only use @p timeout, @p period is zero. * - * Periodic timers can either start their life disabled, with @param - * timeout set to zero, or with the same value as @param period. + * Periodic timers can either start their life disabled, with @p timeout + * set to zero, or with the same value as @p period. * - * When the timeout expires, for either of the two types, @param cb is - * called, with the optional @param arg argument. A one-shot timer ends - * its life there, while a periodic task's @param timeout is reset to - * the @param period and restarted. + * When the timeout expires, for either of the two types, @p cb is + * called, with the optional @p arg argument. A one-shot timer ends its + * life there, while a periodic task's @p timeout is reset to the @p + * period and restarted. * * A timer is automatically started if the event loop is already * running, otherwise it is kept on hold until triggered by calling * uev_run(). * * @see uev_timer_set - * @return POSIX OK(0) or non-zero with @param errno set on error. + * @return POSIX OK(0) or non-zero with @p errno set on error. */ int uev_timer_init(uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int timeout, int period) { @@ -99,14 +104,14 @@ int uev_timer_init(uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int timeou /** * Reset a timer * @param w Watcher to reset - * @param timeout Timeout in milliseconds before @param cb is called, zero disarms timer - * @param period For periodic timers this is the period time that @param timeout is reset to + * @param timeout Timeout in milliseconds before @p cb is called, zero disarms timer + * @param period For periodic timers this is the period time that @p timeout is reset to * - * Note, the @param timeout value must be non-zero. Setting it to zero - * will disarm the timer. This is the underlying Linux function @func - * timerfd_settimer() which has this behavior. + * Note, the @p timeout value must be non-zero. Setting it to zero + * disarms the timer. This is the behavior of the underlying Linux + * function [timerfd_settimer(2)](https://man7.org/linux/man-pages/man2/timerfd_settime.2.html) * - * @return POSIX OK(0) or non-zero with @param errno set on error. + * @return POSIX OK(0) or non-zero with @p errno set on error. */ int uev_timer_set(uev_t *w, int timeout, int period) { @@ -150,7 +155,7 @@ int uev_timer_set(uev_t *w, int timeout, int period) * Start a stopped timer watcher * @param w Watcher to start (again) * - * @return POSIX OK(0) or non-zero with @param errno set on error. + * @return POSIX OK(0) or non-zero with @p errno set on error. */ int uev_timer_start(uev_t *w) { @@ -169,7 +174,7 @@ int uev_timer_start(uev_t *w) * Stop and unregister a timer watcher * @param w Watcher to stop * - * @return POSIX OK(0) or non-zero with @param errno set on error. + * @return POSIX OK(0) or non-zero with @p errno set on error. */ int uev_timer_stop(uev_t *w) { diff --git a/src/uev.c b/src/uev.c index 9b2e6af..5d23a75 100644 --- a/src/uev.c +++ b/src/uev.c @@ -22,6 +22,11 @@ * THE SOFTWARE. */ +/** Micro event loop library + * @file uev.c + * + */ + #include #include /* O_CLOEXEC */ #include /* memset() */ @@ -178,8 +183,8 @@ int _uev_watcher_rearm(uev_t *w) * Create an event loop context * @param ctx Pointer to an uev_ctx_t context to be initialized * - * This function calls @func uev_init1() with @param maxevents set to - * @const UEV_MAX_EVENTS. + * This function calls uev_init1() with @p maxevents set to + * ::UEV_MAX_EVENTS * * @return POSIX OK(0) on success, or non-zero on error. */ @@ -190,22 +195,23 @@ int uev_init(uev_ctx_t *ctx) /** * Create an event loop context - * @param ctx Pointer to an uev_ctx_t context to be initialized + * @param ctx Pointer to an uev_ctx_t context to be initialized * @param maxevents Maximum number of events in event cache * - * This function is the same as @func uev_init() except for the - * @param maxevents argument, which controls the number of events - * in the event cache returned to the main loop. + * This function is the same as uev_init() except for the @p maxevents + * argument, which controls the number of events in the event cache + * returned to the main loop. * * In cases where you have multiple events pending in the cache and some * event may cause later ones, already sent by the kernel to userspace, * to be deleted the pointer returned to the event loop for this later * event may be deleted. * - * There are two ways around this (accessing deleted memory); 1) use - * this function to initialize your event loop and set @param maxevents - * to 1, 2) use a free list in you application that you garbage collect - * at intervals relevant to your application. + * There are two ways around this (accessing deleted memory): + * -# use this function to initialize your event loop and set + * @p maxevents to 1 + * -# use a free list in you application that you garbage collect + * at intervals relevant to your application * * @return POSIX OK(0) on success, or non-zero on error. */ @@ -226,7 +232,7 @@ int uev_init1(uev_ctx_t *ctx, int maxevents) * Terminate the event loop * @param ctx A valid libuEv context * - * @return POSIX OK(0) or non-zero with @param errno set on error. + * @return POSIX OK(0) or non-zero with @p errno set on error. */ int uev_exit(uev_ctx_t *ctx) { @@ -276,11 +282,11 @@ int uev_exit(uev_ctx_t *ctx) /** * Start the event loop * @param ctx A valid libuEv context - * @param flags A mask of %UEV_ONCE and %UEV_NONBLOCK, or zero + * @param flags A mask of ::UEV_ONCE and ::UEV_NONBLOCK, or zero * - * With @flags set to %UEV_ONCE the event loop returns after the first + * With @p flags set to ::UEV_ONCE the event loop returns after the first * event has been served, useful for instance to set a timeout on a file - * descriptor. If @flags also has the %UEV_NONBLOCK flag set the event + * descriptor. If @p flags also has the ::UEV_NONBLOCK flag set the event * loop will return immediately if no event is pending, useful when run * inside another event loop. * diff --git a/src/uev.h b/src/uev.h index b860b8c..445839f 100644 --- a/src/uev.h +++ b/src/uev.h @@ -22,63 +22,83 @@ * THE SOFTWARE. */ +/** + * Micro event loop library + * @file uev.h + * @author Flemming Madsen (2012) + * @author Joachim Wiberg (2013-2021) + * @copyright MIT License + * + * The latest version of this manual and the libuEv software are + * available at https://github.com/troglobit/libuEv/ + */ + #ifndef LIBUEV_UEV_H_ #define LIBUEV_UEV_H_ #include "private.h" -/* Max. number of simulateneous events */ -#define UEV_MAX_EVENTS 10 +#define UEV_MAX_EVENTS 10 /**< Max. number of simulateneous events */ /* I/O events, signal and timer revents are always UEV_READ */ -#define UEV_NONE 0 -#define UEV_ERROR EPOLLERR -#define UEV_READ EPOLLIN -#define UEV_WRITE EPOLLOUT -#define UEV_PRI EPOLLPRI -#define UEV_HUP EPOLLHUP -#define UEV_RDHUP EPOLLRDHUP -#define UEV_EDGE EPOLLET -#define UEV_ONESHOT EPOLLONESHOT +#define UEV_NONE 0 /**< normal loop */ +#define UEV_ERROR EPOLLERR /**< error flag */ +#define UEV_READ EPOLLIN /**< poll for reading */ +#define UEV_WRITE EPOLLOUT /**< poll for writing */ +#define UEV_PRI EPOLLPRI /**< priority message */ +#define UEV_HUP EPOLLHUP /**< hangup event */ +#define UEV_RDHUP EPOLLRDHUP /**< peer shutdown */ +#define UEV_EDGE EPOLLET /**< edge triggered */ +#define UEV_ONESHOT EPOLLONESHOT /**< one-shot event */ /* Run flags */ -#define UEV_ONCE 1 -#define UEV_NONBLOCK 2 +#define UEV_ONCE 1 /**< run loop once */ +#define UEV_NONBLOCK 2 /**< exit if no event */ -/* Macros */ +/** Check if I/O watcher is active or stopped */ #define uev_io_active(w) _uev_watcher_active(w) +/** Check if signal watcher is active or stopped */ #define uev_signal_active(w) _uev_watcher_active(w) +/** Check if timer is active or stopped */ #define uev_timer_active(w) _uev_watcher_active(w) +/** Check if cron timer watcher is active or stopped */ #define uev_cron_active(w) _uev_watcher_active(w) +/** Check if event watcher is active or stopped */ #define uev_event_active(w) _uev_watcher_active(w) -/* Event watcher */ +/** Event loop context, need one per process and thread */ +typedef struct uev_ctx uev_ctx_t; + +/** Event watcher */ typedef struct uev { /* Private data for libuEv internal engine */ uev_private_t type; /* Public data for users to reference */ - int signo; - int fd; - uev_ctx_t *ctx; + int signo; /**< configured signal */ + int fd; /**< active descriptor */ + uev_ctx_t *ctx; /**< watcher context */ /* Extra data for certain watcher types */ - struct signalfd_siginfo siginfo; + struct signalfd_siginfo siginfo; /**< received signal */ } uev_t; -/* - * Generic callback for watchers, @events holds %UEV_READ and/or %UEV_WRITE - * with optional %UEV_PRI (priority data available to read) and any of the - * %UEV_HUP and/or %UEV_RDHUP, which may be used to signal hang-up events. +/** + * Generic callback for watchers, @p events holds ::UEV_READ and/or + * ::UEV_WRITE with optional ::UEV_PRI (priority data available to read) + * and any of the ::UEV_HUP and/or ::UEV_RDHUP, which may be used to + * signal hang-up and peer shutdown events. * - * Note: UEV_ERROR conditions must be handled by all callbacks! - * I/O watchers may also need to check UEV_HUP. Appropriate action, + * Note: ::UEV_ERROR conditions must be handled by all callbacks! I/O + * watchers may also need to check ::UEV_HUP. Appropriate action, * e.g. restart the watcher, is up to the application and is thus * delegated to the callback. */ typedef void (uev_cb_t)(uev_t *w, void *arg, int events); /* Public interface */ + +/** Create an event loop context */ int uev_init (uev_ctx_t *ctx); int uev_init1 (uev_ctx_t *ctx, int maxevents); int uev_exit (uev_ctx_t *ctx);