child_proc_watcher, child_proc_watcher_impl

    // Members of dasynq::event_loop<T> instantiation:

    class child_proc_watcher;

    template <class Derived> class child_proc_watcher_impl; // : public child_proc_watcher;


Brief: child_proc_watcher is a member type of the event_loop template class. It represents an event watcher for child process termination. The child_proc_watcher class should not be subclassed directly; the child_proc_watcher_impl template provides a means for subclassing.





Details and Usage

Note: also see the watcher constraints section.

An application may wish to handle child process termination at the same time as other events. The child_proc_watcher allows child process termination to be detected by an event loop.

Note that creating multiple watchers for a single child process is not supported.

Subclassing child_proc_watcher

To specify callback behaviour, child_proc_watcher can be subclassed — however, it should not be directly subclassed; instead, use the child_proc_watcher_impl implementation wrapper template.

Reaping of child processes

Processes which terminate may becomes "zombie" processes until their termination is acknowledged by their parent process, i.e. until they are reaped.

Child processes for which a watcher is added will be reaped automatically, either when their termination is detected or (if possible) immediately after the callback function returns. Note that the event loop may reap all child processes, even those that are not watched (as a necessity of implementation).

Reserving watchers

Since adding a watcher using add_watch can fail, and because it requires that the child process has already been created, the awkward situation can arise that a child process is created but cannot be monitored. There are two ways to avoid this: the first is to reserve a watch (using the reserve_watch function) and add the watch after creating the child process using the add_reserved function instead of the add_watch function; the second way is to perform an "atomic" fork using the fork member function.

"Atomic" fork

The fork member function avoids the problem of creating unwatchable child processes by forking and adding the watch simultaneously. If the watch cannot be created, the child process is either not created or is terminated immediately (before the fork function returns).

Note that, with a multi-threaded event loop, there is a race when creating a child process and watching it, because the child might be reaped before the watch is added (resulting either in failure when adding the watch, or the child termination never being reported via the callback). Using the fork member function to create the child process also avoids this race.

Signalling child processes

Since child processes may be reaped "behind the scenes" by the event loop, signalling them becomes inherently race-prone; any signal sent to a process identified by its numerical process id (pid) could potentially be delivered instead to a new process which has been given the same pid after the original process terminated and was reaped. To avoid this, use the send_signal member function, which guarantees to send a signal only if the process has not yet been reaped.


Brief: The child_proc_watcher_impl provides a basis for implementing child_proc_watcher, using the "curiously recurring template pattern". Instead of subclassing child_proc_watcher directly, subclass an instantiation of child_proc_watcher_impl with the template parameter specified as the subclass itself. For example:

class my_watcher : public event_loop_t::child_proc_watcher_impl<my_watcher>
    // ...

Details and Usage

The callback function must be provided in the subclass and named status_change, with a signature compatible with the following:

rearm status_change(loop_t &, pid_t child, int status);

The status_change function must be public, but need not be virtual. It will be called with the following parameters:

The return value specifies the rearm action.

A child_proc_watcher_impl instantiation has no public or protected members, other than those inherited from child_proc_watcher, which it publicly derives from.