1PMLOOP(3) Library Functions Manual PMLOOP(3)
2
3
4
6 pmLoopRegisterChild, pmLoopRegisterIdle, pmLoopRegisterInput,
7 pmLoopRegisterSignal, pmLoopRegisterTimeout, pmLoopUnregisterChild,
8 pmLoopUnregisterIdle, pmLoopUnregisterInput, pmLoopUnregisterSignal,
9 pmLoopUnregisterTimeout, pmLoopStop, pmLoopMain - PMAPI functions for
10 implementing application main loop
11
13 #include <pcp/pmapi.h>
14
15 int pmLoopRegisterChild(pid_t pid,
16 int (*callback)(pid_t pid, int status, const struct rusage *rusage, void *closure),
17 void *closure);
18 int pmLoopRegisterIdle(
19 int (*callback)(void *closure),
20 void *closure);
21 int pmLoopRegisterInput(int fd, int flags,
22 int (*callback)(int fd, int flags, void *closure),
23 void *closure, int priority);
24 int pmLoopRegisterSignal(int sig,
25 int (*callback)(int sig, void *closure),
26 void *closure);
27 int pmLoopRegisterTimeout(int delay_msec,
28 int (*callback)(void *closure),
29 void *closure);
30
31 int pmLoopUnregisterChild(int tag);
32 int pmLoopUnregisterIdle(int tag);
33 int pmLoopUnregisterInput(int tag);
34 int pmLoopUnregisterSignal(int tag);
35 int pmLoopUnregisterTimeout(int tag);
36
37 void pmLoopStop(void);
38 void pmLoopMain(void);
39
40 cc ... -lpcp
41
43 These functions implement a generic UNIX main poll(2) loop which can be
44 found at the heart of many UNIX daemon processes and a number of the
45 associated features which the UNIX process model requires the same code
46 to handle, for example timers and safe delivery of signals. Inspira‐
47 tion for this module came from (in chronological order) the SunView
48 notifier library, the X Intrinsics Toolkit main loop, and the
49 GTK+/libglib main loop feature.
50
51 The module supports the following features:
52
53 * callback to application code from main loop when input or output
54 is possible on a file descriptor
55
56 * callback when a (catchable) signal is delivered
57
58 * callback on a timeout, including recurring timeouts
59
60 * callback when a child process has died (or its status is other‐
61 wise notified via wait3(2)).
62
63 * callback when the main loop is idle
64
65 * all callbacks occur at safe times, e.g. signal callback occurs
66 when main loop is idle and not partway through another callback.
67
68 * a callback is automatically unregisted if the callback's func‐
69 tion returns non-zero value.
70
71 * application code can call a subsidiary main loop, to handle and
72 dispatch all registered callbacks for some time without return‐
73 ing to the main loop.
74
75 int pmLoopRegisterInput(int fd, int flags,
76 int (*callback)(int fd, int flags, void *closure),
77 void *closure, int priority);
78
79 Register callback to be called when input or output becomes pos‐
80 sible on file descriptor fd. The flags are a bitmask of poll(2)
81 flags, e.g. POLLIN will cause the callback to be called when
82 input is available on the file descriptor and POLLOUT is for
83 when output becomes possible. The closure pointer is not inter‐
84 preted in any way, but is passed to the callback; the applica‐
85 tion may use this to pass around a pointer to any data it needs.
86 Priority may be used to force the order of dispatch of callbacks
87 when multiple file descriptors become available at the same
88 time; callbacks are dispatched in increasing order of their pri‐
89 ority number. The return value is a tag which is unique amongst
90 all registered callbacks (e.g. registering the same callback
91 twice gives two different tags) and which can be used to remove
92 the callback using pmLoopUnregisterInput().
93
94 void pmLoopUnregisterInput(int tag);
95
96 Unregisters a file descriptor input callback previously regis‐
97 tered with pmLoopRegisterInput(). This can safely be called
98 from within the callback being deregistered.
99
100 int pmLoopRegisterSignal(int sig,
101 int (*callback)(int sig, void *closure),
102 void *closure);
103
104 Register callback to be called when signal sig is delivered to
105 the process. Some signals cannot be caught, see the signal(7)
106 manpage for details. Catching SIGCHLD is not recommended, see
107 pmLoopRegisterChild() for a better way to detect child process
108 status changes. The closure pointer is not interpreted in any
109 way, but is passed to the callback; the application may use this
110 to pass around a pointer to any data it needs. The return value
111 is a tag which is unique amongst all registered callbacks (e.g.
112 registering the same callback twice gives two different tags)
113 and which can be used to remove the callback using pmLoopUnreg‐
114 isterSignal(). Once registered, a callback stays registered
115 unless explicitly unregistered with pmLoopUnregisterSignal(),
116 and does not need to be re-registered after a signal is deliv‐
117 ered. Note that two or more callbacks can be registered for the
118 same signal; they are dispatched in the reverse of the order in
119 which they were registered.
120
121 void pmLoopUnregisterSignal(int tag);
122
123 Unregisters a signal callback previously registered with
124 pmLoopRegisterSignal(). This can safely be called from within
125 the callback being deregistered.
126
127 int pmLoopRegisterTimeout(int delay_msec,
128 int (*callback)(void *closure),
129 void *closure);
130
131 Register callback to be called after delay_msec milliseconds
132 have elapsed. If delay is 0, the callback is called immedi‐
133 ately. The closure pointer is not interpreted in any way, but
134 is passed to the callback; the application may use this to pass
135 around a pointer to any data it needs. The return value is a
136 tag which is unique amongst all registered callbacks (e.g. reg‐
137 istering the same callback twice gives two different tags) and
138 which can be used to remove the callback using pmLoopUnregister‐
139 Timeout(). Once registered, a callback stays registered until
140 it is either explictly unregisterd or the callback function
141 returns non-zero value.
142
143 void pmLoopUnregisterTimeout(int tag);
144
145 Unregisters a timeout callback previously registered with
146 pmLoopRegisterTimeout(). This can safely be called from within
147 the callback being deregistered.
148
149 int pmLoopRegisterChild(pid_t pid,
150 int (*callback)(pid_t pid, int status, const struct rusage *rusage, void * closure),
151 void *closure);
152
153 Register callback to be called when the child process pid
154 changes status in a way which triggers a wait3(2) notification.
155 Normally, this means the process has called exit() or died in
156 some other manner, but see the wait3(2) manpage. Waiting on a
157 process group (e.g. by passing a negative pid) is not supported.
158 All descendant processes started by the process will be reaped
159 by the module, regardless of whether a child process callback
160 has been registered for them or not. The status and rusage
161 argument to the callback are from the wait3(2) system call, see
162 the wait3(2) manpage for how to use the macros WIFSTOPPED() et
163 al to interpret these. The closure pointer is not interpreted
164 in any way, but is passed to the callback; the application may
165 use this to pass around a pointer to any data it needs. The
166 return value is a tag which is unique amongst all registered
167 callbacks (e.g. registering the same callback twice gives two
168 different tags) and which can be used to remove the callback
169 using pmLoopUnregisterChild(). Once registered, a callback is
170 automatically unregistered if status indicates that the process
171 has died (this is the usual case), otherwise it stays regis‐
172 tered.
173
174 void pmLoopUnregisterChild(int tag);
175
176 Unregisters a child process callback previously registered with
177 pmLoopRegisterChild(). This can safely be called from within
178 the callback being deregistered.
179
180 int pmLoopRegisterIdle(
181 int (*callback)(void *closure),
182 void *closure);
183
184 Register callback to be called whenever the loop module is idle,
185 i.e. no other callbacks are pending. This is useful for doing
186 background processing while still responding to other events.
187 Note that the callback function can be called many thousands of
188 times per second, so this feature should be used with care. The
189 closure pointer is not interpreted in any way, but is passed to
190 the callback; the application may use this to pass around a
191 pointer to any data it needs. The return value is a tag which
192 is unique amongst all registered callbacks (e.g. registering the
193 same callback twice gives two different tags) and which can be
194 used to remove the callback using pmLoopUnregisterIdle(). Once
195 registered, a callback stays registered.
196
197 void pmLoopUnregisterIdle(int tag);
198
199 Unregisters a child process callback previously registered with
200 pmLoopRegisterIdle(). This can safely be called from within the
201 callback being deregistered.
202
203 void pmLoopMain(void);
204
205 This function starts the main loop of an application. It han‐
206 dles various UNIX events and dispatches registered callbacks,
207 not returning until pmLoopStop() is called.
208
209 Note that pmLoopMain() may be called in an callback, which has
210 the effect of running a subsidiary loop, i.e. loop for a while
211 handling events and dispatching callbacks as the main loop would
212 do, but without returning control to the main loop. Such sub‐
213 sidiary loops can be nested.
214
215 void pmLoopStop(void);
216
217 Causes the innermost pmLoopMain() to return when it is next
218 idle, i.e. as soon as the current callback has returned.
219
221 poll(2), wait3(2), signal(7)
222
223
224
225Performance Co-Pilot SGI PMLOOP(3)