eloop: add initial gtk-doc comments

Add gtk-doc compatible comments to most of the functions in eloop.c.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
David Herrmann 2012-05-19 17:58:08 +02:00
parent 0b8da0ce50
commit 00ff46b701

View File

@ -24,11 +24,27 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* Event Loop
* This provides a basic event loop similar to those provided by glib etc.
* It uses linux specific features like signalfd so it may not be easy to port
* it to other platforms.
/**
* SECTION:eloop
* @short_description: Event loop
* @include: eloop.h
*
* The event loop allows to register event sources and poll them for events.
* When an event occurs, the user-supplied callback is called.
*
* The event-loop allows the callbacks to modify _any_ data they want. They can
* remove themself or other sources from the event loop even in a callback.
*
* Sources can be one of:
* - File descriptors: An fd that is watched for readable/writeable events
* - Timers: An event that occurs after a relative timeout
* - Counters: An event that occurs when the counter is non-zero
* - Signals: An event that occurs when a signal is caught
* - Idle: An event that occurs when nothing else is done
* - Eloop: An event loop itself can be a source of another event loop
*
* A source can be registered for a single event-loop only! You cannot add it to
* multiple event loops simultaneously.
*/
#include <errno.h>
@ -51,20 +67,21 @@
#define LOG_SUBSYSTEM "eloop"
/*
* Event Loop
/**
* ev_eloop:
* @efd: The epoll file descriptor.
* @ref: refcnt of this object
* @fd: Event source around \efd so you can nest event loops
* @cnt: Counter source used for idle events
* @sig_list: Shared signal sources
* @idlers: List of idle sources
* @cur_fds: Current dispatch array of fds
* @cur_fds_cnt: size of \cur_fds
* @exit: true if we should exit the main loop
*
* An event loop is an object where you can register event sources. If you then
* sleep on the event loop, you will be woken up if a single event source is
* firing up. An event loop itself is an event source so you can nest them.
* \efd: The epoll file descriptor.
* \ref: refcnt of this object
* \fd: Event source around \efd so you can nest event loops
* \cnt: Counter source used for idle events
* \sig_list: Shared signal sources
* \idlers: List of idle sources
* \cur_fds: Current dispatch array of fds
* \cur_fds_cnt: size of \cur_fds
* \exit: true if we should exit the main loop
*/
struct ev_eloop {
int efd;
@ -81,16 +98,18 @@ struct ev_eloop {
bool exit;
};
/*
* FD sources
* File descriptors are used internally for all kinds of sources.
* \ref: refcnt for object
* \fd: the actual file desciptor
* \mask: the event mask for this fd (EV_READABLE, EV_WRITABLE, ...)
* \cb: the user callback
* \data: the user data
* \enabled: true if the object is currently enabled
* \loop: NULL or pointer to eloop if bound
/**
* ev_fd:
* @ref: refcnt for object
* @fd: the actual file desciptor
* @mask: the event mask for this fd (EV_READABLE, EV_WRITABLE, ...)
* @cb: the user callback
* @data: the user data
* @enabled: true if the object is currently enabled
* @loop: NULL or pointer to eloop if bound
*
* File descriptors are the most mosic event source. Internally, they are used
* to implement all other kinds of event sources.
*/
struct ev_fd {
unsigned long ref;
@ -103,14 +122,15 @@ struct ev_fd {
struct ev_eloop *loop;
};
/*
* Timer sources
/**
* ev_timer:
* @ref: refcnt of this object
* @cb: user callback
* @data: user data
* @fd: the timerfd file desciptor
* @efd: fd-source for @fd
*
* Based on timerfd this allows firing events based on relative timeouts.
* \ref: refcnt of this object
* \cb: user callback
* \data: user data
* \fd: the timerfd file desciptor
* \efd: fd-source for \fd
*/
struct ev_timer {
unsigned long ref;
@ -121,15 +141,16 @@ struct ev_timer {
struct ev_fd *efd;
};
/*
* Counter Sources
/**
* ev_counter:
* @ref: refcnt of counter object
* @cb: user callback
* @data: user data
* @fd: eventfd file desciptor
* @efd: fd-source for @fd
*
* Counter sources fire if they are non-zero. They are based on the eventfd
* syscall in linux.
* \ref: refcnt of counter object
* \cb: user callback
* \data: user data
* \fd: eventfd file desciptor
* \efd: fd-source for \fd
*/
struct ev_counter {
unsigned long ref;
@ -140,14 +161,15 @@ struct ev_counter {
struct ev_fd *efd;
};
/*
* Shared Signal Sources
/**
* ev_signal_shared:
* @list: list integration into ev_eloop object
* @fd: the signalfd file desciptor for this signal
* @signum: the actual signal number
* @hook: list of registered user callbacks for this signal
*
* A shared signal allows multiple listeners for the same signal. All listeners
* are called if the signal is catched.
* \list: list integration into ev_eloop object
* \fd: the signalfd file desciptor for this signal
* \signum: the actual signal number
* \hook: list of registered user callbacks for this signal
*/
struct ev_signal_shared {
struct kmscon_dlist list;
@ -157,7 +179,7 @@ struct ev_signal_shared {
struct kmscon_hook *hook;
};
/*
/**
* Shared signals
* signalfd allows us to conveniently listen for incoming signals. However, if
* multiple signalfds are registered for the same signal, then only one of them
@ -223,6 +245,18 @@ static void shared_signal_cb(struct ev_fd *fd, int mask, void *data)
}
}
/**
* signal_new:
* @out: Shared signal storage where the new object is stored
* @loop: The event loop where this shared signal is registered
* @signum: Signal number that this shared signal is for
*
* This creates a new shared signal and links it into the list of shared signals
* in @loop. It automatically adds @signum to the signal mask of the current
* thread so the signal is blocked.
*
* Returns: 0 on success, otherwise negative error code
*/
static int signal_new(struct ev_signal_shared **out, struct ev_eloop *loop,
int signum)
{
@ -272,6 +306,15 @@ err_free:
return ret;
}
/**
* signal_free:
* @sig: The shared signal to be freed
*
* This unlinks the given shared signal from the event-loop where it was
* registered and destroys it. This does _not_ unblock the signal number that it
* was associated to. If you want this, you need to do this manually with
* pthread_sigmask().
*/
static void signal_free(struct ev_signal_shared *sig)
{
int fd;
@ -347,6 +390,15 @@ static void eloop_cnt_event(struct ev_counter *cnt, uint64_t num, void *data)
}
}
/**
* ev_eloop_new:
* @out: Storage for the result
*
* This creates a new event-loop with ref-count 1. The new event loop is stored
* in @out and has no registered events.
*
* Returns: 0 on success, otherwise negative error code
*/
int ev_eloop_new(struct ev_eloop **out)
{
struct ev_eloop *loop;
@ -406,6 +458,12 @@ err_free:
return ret;
}
/**
* ev_eloop_ref:
* @loop: Event loop to be modified
*
* This increases the ref-count of @loop by 1.
*/
void ev_eloop_ref(struct ev_eloop *loop)
{
if (!loop)
@ -414,6 +472,15 @@ void ev_eloop_ref(struct ev_eloop *loop)
++loop->ref;
}
/**
* ev_eloop_unref:
* @loop: Event loop to be modified
*
* This decreases the ref-count of @loop by 1. If it drops to zero, the event
* loop is destroyed. Note that every registered event source takes a ref-count
* of the event loop so this ref-count will never drop to zero while there is an
* registered event source.
*/
void ev_eloop_unref(struct ev_eloop *loop)
{
struct ev_signal_shared *sig;
@ -438,6 +505,14 @@ void ev_eloop_unref(struct ev_eloop *loop)
free(loop);
}
/**
* ev_eloop_flush_fd:
* @loop: The event loop where @fd is registered
* @fd: The fd to be flushed
*
* If @loop is currently dispatching events, this will remove all pending events
* of @fd from the current event-list.
*/
void ev_eloop_flush_fd(struct ev_eloop *loop, struct ev_fd *fd)
{
int i;
@ -453,6 +528,24 @@ void ev_eloop_flush_fd(struct ev_eloop *loop, struct ev_fd *fd)
}
}
/**
* ev_eloop_dispatch:
* @loop: Event loop to be dispatched
* @timeout: Timeout in milliseconds
*
* This listens on @loop for incoming events and handles all events that
* occured. This waits at most @timeout milliseconds until returning. If
* @timeout is -1, this waits until the first event arrives. If @timeout is 0,
* then this returns directly if no event is currently pending.
*
* This performs only a single dispatch round. That is, if all sources where
* checked for events and there are no more pending events, this will return. If
* it handled events and the timeout has not elapsed, this will still return.
*
* If ev_eloop_exit() was called on @loop, then this will return immediately.
*
* Returns: 0 on success, otherwise negative error code
*/
int ev_eloop_dispatch(struct ev_eloop *loop, int timeout)
{
struct epoll_event *ep;
@ -517,10 +610,21 @@ int ev_eloop_dispatch(struct ev_eloop *loop, int timeout)
return 0;
}
/* ev_eloop_dispatch() performs one idle-roundtrip. This function performs as
* many idle-roundtrips as needed to run \timeout milliseconds.
* If \timeout is 0, this is equal to ev_eloop_dispath(), if \timeout is <0,
* this runs until \loop->exit becomes true.
/**
* ev_eloop_run:
* @loop: The event loop to be run
* @timeout: Timeout for this operation
*
* This is similar to ev_eloop_dispatch() but runs _exactly_ for @timeout
* milliseconds. It calls ev_eloop_dispatch() as often as it can until the
* timeout has elapsed. If @timeout is -1 this will run until you call
* ev_eloop_exit(). If @timeout is 0 this is equal to calling
* ev_eloop_dispatch() with a timeout of 0.
*
* Calling ev_eloop_exit() will always interrupt this function and make it
* return.
*
* Returns: 0 on success, otherwise a negative error code
*/
int ev_eloop_run(struct ev_eloop *loop, int timeout)
{
@ -560,6 +664,12 @@ int ev_eloop_run(struct ev_eloop *loop, int timeout)
return 0;
}
/**
* ev_eloop_exit:
* @loop: Event loop that should exit
*
* This makes a call to ev_eloop_run() stop.
*/
void ev_eloop_exit(struct ev_eloop *loop)
{
if (!loop)
@ -572,6 +682,16 @@ void ev_eloop_exit(struct ev_eloop *loop)
ev_eloop_exit(loop->fd->loop);
}
/**
* ev_eloop_new_eloop:
* @loop: The parent event-loop where the new event loop is registered
* @out: Storage for new event loop
*
* This creates a new event loop and directly registeres it as event source on
* the parent event loop \loop.
*
* Returns: 0 on success, otherwise negative error code
*/
int ev_eloop_new_eloop(struct ev_eloop *loop, struct ev_eloop **out)
{
struct ev_eloop *el;
@ -595,6 +715,16 @@ int ev_eloop_new_eloop(struct ev_eloop *loop, struct ev_eloop **out)
return 0;
}
/**
* ev_eloop_add_eloop:
* @loop: Parent event loop
* @add: The event loop that is registered as event source on @loop
*
* This registers the existing event loop @add as event source on the parent
* event loop @loop.
*
* Returns: 0 on success, otherwise negative error code
*/
int ev_eloop_add_eloop(struct ev_eloop *loop, struct ev_eloop *add)
{
int ret;
@ -623,6 +753,14 @@ int ev_eloop_add_eloop(struct ev_eloop *loop, struct ev_eloop *add)
return 0;
}
/**
* ev_eloop_rm_eloop:
* @rm: Event loop to be unregistered from its parent
*
* This unregisters the event loop @rm as event source from its parent. If this
* event loop was not registered on any other event loop, then this call does
* nothing.
*/
void ev_eloop_rm_eloop(struct ev_eloop *rm)
{
if (!rm || !rm->fd->loop)
@ -642,6 +780,22 @@ void ev_eloop_rm_eloop(struct ev_eloop *rm)
* called until you enable it again.
*/
/**
* ev_fd_new:
* @out: Storage for result
* @rfd: The actual file desciptor
* @mask: Bitmask of %EV_READABLE and %EV_WRITeABLE flags
* @cb: User callback
* @data: User data
*
* This creates a new file desciptor source that is watched for the events set
* in @mask. @rfd is the system filedescriptor. The resulting object is stored
* in @out. @cb and @data are the user callback and the user-supplied data that
* is passed to the callback on events.
* The FD is automatically watched for EV_HUP and EV_ERR events, too.
*
* Returns: 0 on success, otherwise negative error code
*/
int ev_fd_new(struct ev_fd **out, int rfd, int mask, ev_fd_cb cb, void *data)
{
struct ev_fd *fd;
@ -665,6 +819,12 @@ int ev_fd_new(struct ev_fd **out, int rfd, int mask, ev_fd_cb cb, void *data)
return 0;
}
/**
* ev_fd_ref:
* @fd: FD object
*
* Increases the ref-count of @fd by 1.
*/
void ev_fd_ref(struct ev_fd *fd)
{
if (!fd)
@ -673,6 +833,13 @@ void ev_fd_ref(struct ev_fd *fd)
++fd->ref;
}
/**
* ev_fd_unref:
* @fd: FD object
*
* Decreases the ref-count of @fd by 1. Destroys the object if the ref-count
* drops to zero.
*/
void ev_fd_unref(struct ev_fd *fd)
{
if (!fd || !fd->ref || --fd->ref)
@ -744,6 +911,15 @@ static int fd_epoll_update(struct ev_fd *fd)
return 0;
}
/**
* ev_fd_enable:
* @fd: FD object
*
* This enables @fd. By default every fd object is enabled. If you disabled it
* you can re-enable it with this call.
*
* Returns: 0 on success, otherwise negative error code
*/
int ev_fd_enable(struct ev_fd *fd)
{
int ret;
@ -761,6 +937,13 @@ int ev_fd_enable(struct ev_fd *fd)
return 0;
}
/**
* ev_fd_disable:
* @fd: FD object
*
* Disables @fd. That means, no more events are handled for @fd until you
* re-enable it with ev_fd_enable().
*/
void ev_fd_disable(struct ev_fd *fd)
{
if (!fd || !fd->enabled)
@ -770,16 +953,42 @@ void ev_fd_disable(struct ev_fd *fd)
fd_epoll_remove(fd);
}
/**
* ev_fd_is_enabled:
* @fd: FD object
*
* Returns whether the fd object is enabled or disabled.
*
* Returns: true if @fd is enabled, otherwise false.
*/
bool ev_fd_is_enabled(struct ev_fd *fd)
{
return fd && fd->enabled;
}
/**
* ev_fd_is_bound:
* @fd: FD object
*
* Returns true if the fd object is bound to an event loop.
*
* Returns: true if @fd is bound, otherwise false
*/
bool ev_fd_is_bound(struct ev_fd *fd)
{
return fd && fd->loop;
}
/**
* ev_fd_set_cb_data:
* @fd: FD object
* @cb: New user callback
* @data: New user data
*
* This changes the user callback and user data that were set in ev_fd_new().
* Both can be set to NULL. If @cb is NULL, then the callback will not be called
* anymore.
*/
void ev_fd_set_cb_data(struct ev_fd *fd, ev_fd_cb cb, void *data)
{
if (!fd)
@ -789,6 +998,15 @@ void ev_fd_set_cb_data(struct ev_fd *fd, ev_fd_cb cb, void *data)
fd->data = data;
}
/**
* ev_fd_update:
* @fd: FD object
* @mask: Bitmask of %EV_READABLE and %EV_WRITEABLE
*
* This resets the event mask of @fd to @mask.
*
* Returns: 0 on success, otherwise negative error code
*/
int ev_fd_update(struct ev_fd *fd, int mask)
{
int ret;
@ -812,6 +1030,23 @@ int ev_fd_update(struct ev_fd *fd, int mask)
return 0;
}
/**
* ev_eloop_new_fd:
* @loop: Event loop
* @out: Storage for result
* @rfd: File descriptor
* @mask: Bitmask of %EV_READABLE and %EV_WRITEABLE
* @cb: User callback
* @data: User data
*
* This creates a new fd object like ev_fd_new() and directly registers it in
* the event loop @loop. See ev_fd_new() and ev_eloop_add_fd() for more
* information.
* The ref-count of @out is 1 so you must call ev_eloop_rm_fd() to destroy the
* fd. You must not call ev_fd_unref() unless you called ev_fd_ref() before.
*
* Returns: 0 on success, otherwise negative error code
*/
int ev_eloop_new_fd(struct ev_eloop *loop, struct ev_fd **out, int rfd,
int mask, ev_fd_cb cb, void *data)
{
@ -836,6 +1071,17 @@ int ev_eloop_new_fd(struct ev_eloop *loop, struct ev_fd **out, int rfd,
return 0;
}
/**
* ev_eloop_add_fd:
* @loop: Event loop
* @fd: FD Object
*
* Registers @fd in the event loop @loop. This increases the ref-count of both
* @loop and @fd. From now on the user callback of @fd may get called during
* dispatching.
*
* Returns: 0 on success, otherwise negative error code
*/
int ev_eloop_add_fd(struct ev_eloop *loop, struct ev_fd *fd)
{
int ret;
@ -858,6 +1104,16 @@ int ev_eloop_add_fd(struct ev_eloop *loop, struct ev_fd *fd)
return 0;
}
/**
* ev_eloop_rm_fd:
* @fd: FD object
*
* Removes the fd object @fd from its event loop. If you did not call
* ev_eloop_add_fd() before, this will do nothing.
* This decreases the refcount of @fd and the event loop by 1.
* It is safe to call this in any callback. This makes sure that the current
* dispatcher will not get confused or read invalid memory.
*/
void ev_eloop_rm_fd(struct ev_fd *fd)
{
struct ev_eloop *loop;