pmLoopUnregisterTimeout(3) PMAPI functions for implementing application main loop

Other Alias

pmLoopRegisterChild, pmLoopRegisterIdle, pmLoopRegisterInput, pmLoopRegisterSignal, pmLoopRegisterTimeout, pmLoopUnregisterChild, pmLoopUnregisterIdle, pmLoopUnregisterInput, pmLoopUnregisterSignal, pmLoopStop, pmLoopMain

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.