---
name: "pmLoopMain"
section: "3"
platform: "linux"
package: "libpcp3-dev"
version: "3.3.3-squeeze3"
release: "Debian 6.0 (Squeeze)"
platforms: ["linux"]
url: "https://new.carta.tech/pmLoopMain"
---

# pmLoopMain(3)

PMAPI functions for implementing application main loop

## 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)](/poll/2.md) 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)](/wait3/2.md)).

- \*

  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)](/poll/2.md) 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)](/signal/7.md) 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)](/wait3/2.md) notification. Normally, this means the process has called exit() or died in some other manner, but see the [**wait3**(2)](/wait3/2.md) 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)](/wait3/2.md) system call, see the [**wait3**(2)](/wait3/2.md) 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)](/poll/2.md), [**wait3**(2)](/wait3/2.md), [**signal**(7)](/signal/7.md)
