NAME
pmLoopRegisterChild, pmLoopRegisterIdle, pmLoopRegisterInput,
pmLoopRegisterSignal, pmLoopRegisterTimeout, pmLoopUnregisterChild,
pmLoopUnregisterIdle, pmLoopUnregisterInput, pmLoopUnregisterSignal,
pmLoopUnregisterTimeout, pmLoopStop, pmLoopMain - PMAPI functions for
implementing application main loop
C SYNOPSIS
#include <pcp/pmapi.h>
int pmLoopRegisterChild(pid_t pid,
int (*callback)(pid_t pid, int status, const struct rusage *rusage, void *closure),
void *closure);
int pmLoopRegisterIdle(
int (*callback)(void *closure),
void *closure);
int pmLoopRegisterInput(int fd, int flags,
int (*callback)(int fd, int flags, void *closure),
void *closure, int priority);
int pmLoopRegisterSignal(int sig,
int (*callback)(int sig, void *closure),
void *closure);
int pmLoopRegisterTimeout(int delay_msec,
int (*callback)(void *closure),
void *closure);
int pmLoopUnregisterChild(int tag);
int pmLoopUnregisterIdle(int tag);
int pmLoopUnregisterInput(int tag);
int pmLoopUnregisterSignal(int tag);
int pmLoopUnregisterTimeout(int tag);
void pmLoopStop(void);
void pmLoopMain(void);
cc ... -lpcp
DESCRIPTION
These functions implement a generic UNIX main poll(2) loop which can be
found at the heart of many UNIX daemon processes and a number of the
associated features which the UNIX process model requires the same code
to handle, for example timers and safe delivery of signals.
Inspiration for this module came from (in chronological order) the
SunView notifier library, the X Intrinsics Toolkit main loop, and the
GTK+/libglib main loop feature.
The module supports the following features:
* callback to application code from main loop when input or output
is possible on a file descriptor
* callback when a (catchable) signal is delivered
* callback on a timeout, including recurring timeouts
* callback when a child process has died (or its status is
otherwise notified via wait3(2)).
* callback when the main loop is idle
* all callbacks occur at safe times, e.g. signal callback occurs
when main loop is idle and not partway through another callback.
* a callback is automatically unregisted if the callback’s
function returns non-zero value.
* application code can call a subsidiary main loop, to handle and
dispatch all registered callbacks for some time without
returning to the main loop.
int pmLoopRegisterInput(int fd, int flags,
int (*callback)(int fd, int flags, void *closure),
void *closure, int priority);
Register callback to be called when input or output becomes
possible on file descriptor fd. The flags are a bitmask of
poll(2) flags, e.g. POLLIN will cause the callback to be called
when input is available on the file descriptor and POLLOUT is
for when output becomes possible. The closure pointer is not
interpreted in any way, but is passed to the callback; the
application may use this to pass around a pointer to any data it
needs. Priority may be used to force the order of dispatch of
callbacks when multiple file descriptors become available at the
same time; callbacks are dispatched in increasing order of their
priority number. The return value is a tag which is unique
amongst all registered callbacks (e.g. registering the same
callback twice gives two different tags) and which can be used
to remove the callback using pmLoopUnregisterInput().
void pmLoopUnregisterInput(int tag);
Unregisters a file descriptor input callback previously
registered with pmLoopRegisterInput(). This can safely be
called from within the callback being deregistered.
int pmLoopRegisterSignal(int sig,
int (*callback)(int sig, void *closure),
void *closure);
Register callback to be called when signal sig is delivered to
the process. Some signals cannot be caught, see the signal(7)
manpage for details. Catching SIGCHLD is not recommended, see
pmLoopRegisterChild() for a better way to detect child process
status changes. The closure pointer is not interpreted in any
way, but is passed to the callback; the application may use this
to pass around a pointer to any data it needs. The return value
is a tag which is unique amongst all registered callbacks (e.g.
registering the same callback twice gives two different tags)
and which can be used to remove the callback using
pmLoopUnregisterSignal(). Once registered, a callback stays
registered unless explicitly unregistered with
pmLoopUnregisterSignal(), and does not need to be re-registered
after a signal is delivered. Note that two or more callbacks
can be registered for the same signal; they are dispatched in
the reverse of the order in which they were registered.
void pmLoopUnregisterSignal(int tag);
Unregisters a signal callback previously registered with
pmLoopRegisterSignal(). This can safely be called from within
the callback being deregistered.
int pmLoopRegisterTimeout(int delay_msec,
int (*callback)(void *closure),
void *closure);
Register callback to be called after delay_msec milliseconds
have elapsed. If delay is 0, the callback is called
immediately. The closure pointer is not interpreted in any way,
but is passed to the callback; the application may use this to
pass around a pointer to any data it needs. The return value is
a tag which is unique amongst all registered callbacks (e.g.
registering the same callback twice gives two different tags)
and which can be used to remove the callback using
pmLoopUnregisterTimeout(). Once registered, a callback stays
registered until it is either explictly unregisterd or the
callback function returns non-zero value.
void pmLoopUnregisterTimeout(int tag);
Unregisters a timeout callback previously registered with
pmLoopRegisterTimeout(). This can safely be called from within
the callback being deregistered.
int pmLoopRegisterChild(pid_t pid,
int (*callback)(pid_t pid, int status, const struct rusage *rusage, void * closure),
void *closure);
Register callback to be called when the child process pid
changes status in a way which triggers a wait3(2) notification.
Normally, this means the process has called exit() or died in
some other manner, but see the wait3(2) manpage. Waiting on a
process group (e.g. by passing a negative pid) is not supported.
All descendant processes started by the process will be reaped
by the module, regardless of whether a child process callback
has been registered for them or not. The status and rusage
argument to the callback are from the wait3(2) system call, see
the wait3(2) manpage for how to use the macros WIFSTOPPED() et
al to interpret these. The closure pointer is not interpreted
in any way, but is passed to the callback; the application may
use this to pass around a pointer to any data it needs. The
return value is a tag which is unique amongst all registered
callbacks (e.g. registering the same callback twice gives two
different tags) and which can be used to remove the callback
using pmLoopUnregisterChild(). Once registered, a callback is
automatically unregistered if status indicates that the process
has died (this is the usual case), otherwise it stays
registered.
void pmLoopUnregisterChild(int tag);
Unregisters a child process callback previously registered with
pmLoopRegisterChild(). This can safely be called from within
the callback being deregistered.
int pmLoopRegisterIdle(
int (*callback)(void *closure),
void *closure);
Register callback to be called whenever the loop module is idle,
i.e. no other callbacks are pending. This is useful for doing
background processing while still responding to other events.
Note that the callback function can be called many thousands of
times per second, so this feature should be used with care. The
closure pointer is not interpreted in any way, but is passed to
the callback; the application may use this to pass around a
pointer to any data it needs. The return value is a tag which
is unique amongst all registered callbacks (e.g. registering the
same callback twice gives two different tags) and which can be
used to remove the callback using pmLoopUnregisterIdle(). Once
registered, a callback stays registered.
void pmLoopUnregisterIdle(int tag);
Unregisters a child process callback previously registered with
pmLoopRegisterIdle(). This can safely be called from within the
callback being deregistered.
void pmLoopMain(void);
This function starts the main loop of an application. It
handles various UNIX events and dispatches registered callbacks,
not returning until pmLoopStop() is called.
Note that pmLoopMain() may be called in an callback, which has
the effect of running a subsidiary loop, i.e. loop for a while
handling events and dispatching callbacks as the main loop would
do, but without returning control to the main loop. Such
subsidiary loops can be nested.
void pmLoopStop(void);
Causes the innermost pmLoopMain() to return when it is next
idle, i.e. as soon as the current callback has returned.
SEE ALSO
poll(2), wait3(2), signal(7)