File: ACE_Process_Manager.3

package info (click to toggle)
ace 5.2.1-1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 26,856 kB
  • ctags: 18,677
  • sloc: cpp: 171,831; makefile: 48,840; sh: 10,192; perl: 8,582; exp: 787; yacc: 387; lex: 140; csh: 20
file content (356 lines) | stat: -rw-r--r-- 17,318 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
.TH ACE_Process_Manager 3 "1 Dec 2001" "ACE" \" -*- nroff -*-
.ad l
.nh
.SH NAME
ACE_Process_Manager \- Manages a group of processes. 
.SH SYNOPSIS
.br
.PP
\fC#include <Process_Manager.h>\fR
.PP
Inherits \fBACE_Event_Handler\fR.
.PP
.SS Public Types

.in +1c
.ti -1c
.RI "enum { \fBDEFAULT_SIZE\fR = 100 }"
.br
.in -1c
.SS Public Methods

.in +1c
.ti -1c
.RI "\fBACE_Process_Manager\fR (size_t size = ACE_Process_Manager::DEFAULT_SIZE, \fBACE_Reactor\fR *reactor = 0)"
.br
.ti -1c
.RI "int \fBopen\fR (size_t size = DEFAULT_SIZE, \fBACE_Reactor\fR *r = 0)"
.br
.ti -1c
.RI "int \fBclose\fR (void)"
.br
.RI "\fIRelease all resources. Do not wait for processes to exit.\fR"
.ti -1c
.RI "virtual \fB~ACE_Process_Manager\fR (void)"
.br
.RI "\fIDestructor releases all resources and does not wait for processes to exit.\fR"
.ti -1c
.RI "\fBpid_t\fR \fBspawn\fR (\fBACE_Process\fR *proc, \fBACE_Process_Options\fR &options)"
.br
.ti -1c
.RI "\fBpid_t\fR \fBspawn\fR (\fBACE_Process_Options\fR &options)"
.br
.ti -1c
.RI "int \fBspawn_n\fR (size_t n, \fBACE_Process_Options\fR &options, \fBpid_t\fR *child_pids = 0)"
.br
.ti -1c
.RI "int \fBwait\fR (const \fBACE_Time_Value\fR &timeout = \fBACE_Time_Value::max_time\fR)"
.br
.ti -1c
.RI "\fBpid_t\fR \fBwait\fR (\fBpid_t\fR pid, const \fBACE_Time_Value\fR &timeout, \fBACE_exitcode\fR *status = 0)"
.br
.ti -1c
.RI "\fBpid_t\fR \fBwait\fR (\fBpid_t\fR pid, \fBACE_exitcode\fR *status = 0)"
.br
.ti -1c
.RI "int \fBreap\fR (\fBpid_t\fR pid = -1, \fBACE_exitcode\fR *stat_loc = 0, int options = WNOHANG)"
.br
.ti -1c
.RI "int \fBregister_handler\fR (\fBACE_Event_Handler\fR *event_handler, \fBpid_t\fR pid = ACE_INVALID_PID)"
.br
.ti -1c
.RI "int \fBremove\fR (\fBpid_t\fR pid)"
.br
.ti -1c
.RI "int \fBterminate\fR (\fBpid_t\fR pid)"
.br
.ti -1c
.RI "int \fBterminate\fR (\fBpid_t\fR pid, int sig)"
.br
.RI "\fIOn OSs that support signals, send the signal to the specified process. Returns 0 on success and -1 on failure.\fR"
.ti -1c
.RI "size_t \fBmanaged\fR (void) const"
.br
.RI "\fIReturn the number of managed Processes.\fR"
.ti -1c
.RI "void \fBdump\fR (void) const"
.br
.RI "\fIDump the state of an object.\fR"
.in -1c
.SS Public Attributes

.in +1c
.ti -1c
.RI "\fBACE_ALLOC_HOOK_DECLARE\fR"
.br
.RI "\fIDeclare the dynamic allocation hooks.\fR"
.in -1c
.SS Static Public Methods

.in +1c
.ti -1c
.RI "ACE_Process_Manager* \fBinstance\fR (void)"
.br
.RI "\fIGet pointer to a process-wide .\fR"
.ti -1c
.RI "ACE_Process_Manager* \fBinstance\fR (ACE_Process_Manager *)"
.br
.RI "\fISet pointer to a process-wide  and return existing pointer.\fR"
.ti -1c
.RI "void \fBclose_singleton\fR (void)"
.br
.RI "\fIDelete the dynamically allocated singleton.\fR"
.ti -1c
.RI "void \fBcleanup\fR (void *instance, void *arg)"
.br
.RI "\fICleanup method, used by the  to destroy the singleton.\fR"
.in -1c
.SS Protected Methods

.in +1c
.ti -1c
.RI "virtual int \fBhandle_signal\fR (int signum, \fBsiginfo_t\fR * = 0, \fBucontext_t\fR * = 0)"
.br
.in -1c
.SS Private Methods

.in +1c
.ti -1c
.RI "int \fBresize\fR (size_t)"
.br
.RI "\fIResize the pool of Process_Descriptors.\fR"
.ti -1c
.RI "\fBssize_t\fR \fBfind_proc\fR (\fBpid_t\fR process_id)"
.br
.RI "\fILocate the index of the table slot occupied by <process_id>. Returns -1 if <process_id> is not in the <process_table_>.\fR"
.ti -1c
.RI "\fBssize_t\fR \fBfind_proc\fR (ACE_HANDLE process_handle)"
.br
.RI "\fILocate the index of the table slot occupied by <process_handle>. Returns ~0 if <process_handle> is not in the <process_table_>.\fR"
.ti -1c
.RI "int \fBinsert_proc\fR (\fBACE_Process\fR *process)"
.br
.RI "\fIInsert a process in the table (checks for duplicates). Omitting the process handle won't work on Win32...\fR"
.ti -1c
.RI "int \fBappend_proc\fR (\fBACE_Process\fR *process)"
.br
.ti -1c
.RI "int \fBremove_proc\fR (size_t n)"
.br
.RI "\fIActually removes the process at index <n> from the table. This method must be called with locks held.\fR"
.ti -1c
.RI "int \fBnotify_proc_handler\fR (size_t n, \fBACE_exitcode\fR status)"
.br
.RI "\fIIf there's a specific handler for the Process at index <n> in the table, or there's a default handler, call it.\fR"
.in -1c
.SS Private Attributes

.in +1c
.ti -1c
.RI "\fBACE_Process_Descriptor\fR* \fBprocess_table_\fR"
.br
.RI "\fIVector that describes process state within the Process_Manager.\fR"
.ti -1c
.RI "size_t \fBmax_process_table_size_\fR"
.br
.RI "\fIMaximum number of processes we can manage (should be dynamically allocated).\fR"
.ti -1c
.RI "size_t \fBcurrent_count_\fR"
.br
.RI "\fICurrent number of processes we are managing.\fR"
.ti -1c
.RI "\fBACE_Event_Handler\fR* \fBdefault_exit_handler_\fR"
.br
.RI "\fIThis event handler is used to notify when a process we control exits.\fR"
.ti -1c
.RI "\fBACE_Recursive_Thread_Mutex\fR \fBlock_\fR"
.br
.RI "\fIThis lock protects access/ops on <process_table_>.\fR"
.in -1c
.SS Static Private Attributes

.in +1c
.ti -1c
.RI "ACE_Process_Manager* \fBinstance_\fR"
.br
.RI "\fISingleton pointer.\fR"
.ti -1c
.RI "int \fBdelete_instance_\fR"
.br
.RI "\fIControls whether the <Process_Manager> is deleted when we shut down (we can only delete it safely if we created it!).\fR"
.in -1c
.SS Friends

.in +1c
.ti -1c
.RI "class \fBACE_Process_Control\fR"
.br
.in -1c
.SH DETAILED DESCRIPTION
.PP 
Manages a group of processes.
.PP
.PP
 This class allows applications to control groups of processes, similar to how the  controls groups of threads. Naturally, it doesn't work at all on platforms, such as VxWorks or pSoS, that don't support process. There are two (main) ways of using , depending on how involved you wish to be with the termination of managed es. If you just want <Process>es to go away when they're finished, simply register the <Process_Manager> with an : ACE_Process_Manager mgr( 100, some_reactor ) -or- ACE_Process_Manager mgr; ... mgr.open( 100, some_reactor ); Then, the <Process_Manager> will clean up after any <Process>es that it spawns. (On Unix, this means executing a wait(2) to collect the exit status -- and avoid zombie processes; on Win32, it means closing the process and thread HANDLEs that are created when CreateProcess is called.) If, on the other hand (and for some inexplicable reason) you want to explicitly invoke the terminated <Process> cleanup code, then *don't* register the <Process_Manager> with a Reactor, and be sure to call one of the <Process_Manager::wait> functions whenever there might be managed <Process>es that have exited. Note that in either case, <Process_Manager> allows you to register "<Event_Handlers>" to be called when a specific <Process> exits, or when any <Process> without a specific <Event_Handler> exits. When a <Process> exits, the appropriate <Event_Handler>'s <handle_input> is called; the  passed is either the Process' HANDLE (on Win32), or its pid cast to an  (on unix). It is also possible to call the <Process_Manager::wait> functions even though the <Process_Manager> is registered with a <Reactor>. Note also that the wait functions are "sloppy" on Unix, because there's no good way to wait for a subset of the children of a process. The wait functions may end up collecting the exit status of a process that's not managed by the <Process_Manager> whose <wait> you invoked. It's best to only use a single <Process_Manager>, and to create all subprocesses by calling that <Process_Manager>'s <spawn> method.  Incidentally, when you register your <Process_Manager> with a <Reactor> its notification pipe is used to help "reap" the available exit statuses. Therefore, you must not use a <Reactor> whose notify pipe has been disabled. Here's the sequence of steps used to reap the exit statuses in this case: + The <Process_Manager> registers a signal handler for SIGCHLD. + The SIGCHLD handler, when invoked, uses the <Reactor>'s <notify> method to inform the <Reactor> to wake up. + Next, the <Reactor> calls the <Process_Manager>'s <handle_input>, this happens synchronously, not in sighandler-space. + The <handle_input> method collects all available exit statuses. 
.PP
.SH MEMBER ENUMERATION DOCUMENTATION
.PP 
.SS anonymous enum
.PP
\fBEnumeration values:\fR
.in +1c
.TP
\fB\fIDEFAULT_SIZE\fR \fR
.SH CONSTRUCTOR & DESTRUCTOR DOCUMENTATION
.PP 
.SS ACE_Process_Manager::ACE_Process_Manager (size_t size = ACE_Process_Manager::DEFAULT_SIZE, \fBACE_Reactor\fR * reactor = 0)
.PP
Initialize an  with a table containing up to <size> processes. This table resizes itself automatically as needed. If a non-NULL <reactor> is provided, this  uses it to notify an application when a process it controls exits. By default, however, we don't use an . 
.SS ACE_Process_Manager::~ACE_Process_Manager (void)\fC [virtual]\fR
.PP
Destructor releases all resources and does not wait for processes to exit.
.PP
.SH MEMBER FUNCTION DOCUMENTATION
.PP 
.SS int ACE_Process_Manager::append_proc (\fBACE_Process\fR * process)\fC [private]\fR
.PP
Append information about a process, i.e., its <process_id> in the <process_table_>. Each entry is added at the end, growing the table if necessary. 
.SS void ACE_Process_Manager::cleanup (void * instance, void * arg)\fC [static]\fR
.PP
Cleanup method, used by the  to destroy the singleton.
.PP
.SS int ACE_Process_Manager::close (void)
.PP
Release all resources. Do not wait for processes to exit.
.PP
.SS void ACE_Process_Manager::close_singleton (void)\fC [static]\fR
.PP
Delete the dynamically allocated singleton.
.PP
.SS void ACE_Process_Manager::dump (void) const
.PP
Dump the state of an object.
.PP
.SS \fBssize_t\fR ACE_Process_Manager::find_proc (ACE_HANDLE process_handle)\fC [private]\fR
.PP
Locate the index of the table slot occupied by <process_handle>. Returns ~0 if <process_handle> is not in the <process_table_>.
.PP
.SS \fBssize_t\fR ACE_Process_Manager::find_proc (\fBpid_t\fR process_id)\fC [private]\fR
.PP
Locate the index of the table slot occupied by <process_id>. Returns -1 if <process_id> is not in the <process_table_>.
.PP
.SS int ACE_Process_Manager::handle_signal (int signum, \fBsiginfo_t\fR * = 0, \fBucontext_t\fR * = 0)\fC [protected, virtual]\fR
.PP
On Unix, this routine is called asynchronously when a SIGCHLD is received. We just tweak the reactor so that it'll call back our <handle_input> function, which allows us to handle Process exits synchronously.
.PP
On Win32, this routine is called synchronously, and is passed the HANDLE of the Process that exited, so we can do all our work here 
.PP
Reimplemented from \fBACE_Event_Handler\fR.
.SS int ACE_Process_Manager::insert_proc (\fBACE_Process\fR * process)\fC [private]\fR
.PP
Insert a process in the table (checks for duplicates). Omitting the process handle won't work on Win32...
.PP
.SS ACE_Process_Manager * ACE_Process_Manager::instance (ACE_Process_Manager *)\fC [static]\fR
.PP
Set pointer to a process-wide  and return existing pointer.
.PP
.SS ACE_Process_Manager * ACE_Process_Manager::instance (void)\fC [static]\fR
.PP
Get pointer to a process-wide .
.PP
.SS size_t ACE_Process_Manager::managed (void) const
.PP
Return the number of managed Processes.
.PP
.SS int ACE_Process_Manager::notify_proc_handler (size_t n, \fBACE_exitcode\fR status)\fC [private]\fR
.PP
If there's a specific handler for the Process at index <n> in the table, or there's a default handler, call it.
.PP
.SS int ACE_Process_Manager::open (size_t size = DEFAULT_SIZE, \fBACE_Reactor\fR * r = 0)
.PP
Initialize an  with a table containing up to <size> processes. This table resizes itself automatically as needed. If a non-NULL <reactor> is provided, this  uses it to notify an application when a process it controls exits. By default, however, we don't use an . 
.SS int ACE_Process_Manager::reap (\fBpid_t\fR pid = -1, \fBACE_exitcode\fR * stat_loc = 0, int options = WNOHANG)
.PP
Reap the result of a single process by calling , therefore, this method is not portable to Win32. If the child is successfully reaped, <remove> is called automatically. This method does the same thing that the <wait> method directly above it does -- It's just here for backwards compatibility. 
.SS int ACE_Process_Manager::register_handler (\fBACE_Event_Handler\fR * event_handler, \fBpid_t\fR pid = ACE_INVALID_PID)
.PP
Register an Event_Handler to be called back when the specified process exits. If pid == ACE_INVALID_PID this handler is called when any process with no specific handler exits. 
.SS int ACE_Process_Manager::remove (\fBpid_t\fR pid)
.PP
Remove process <pid> from the table. This is called automatically by the <reap> method after it successfully reaped a <SIGCHLD> signal. It's also possible to call this method directly from a signal handler, but don't call both <reap> and <remove>! 
.SS int ACE_Process_Manager::remove_proc (size_t n)\fC [private]\fR
.PP
Actually removes the process at index <n> from the table. This method must be called with locks held.
.PP
.SS int ACE_Process_Manager::resize (size_t)\fC [private]\fR
.PP
Resize the pool of Process_Descriptors.
.PP
.SS \fBpid_t\fR ACE_Process_Manager::spawn (\fBACE_Process_Options\fR & options)
.PP
Create a new process by passing <options> to . On success, returns the process id of the child that was created. On failure, returns ACE_INVALID_PID. 
.SS \fBpid_t\fR ACE_Process_Manager::spawn (\fBACE_Process\fR * proc, \fBACE_Process_Options\fR & options)
.PP
Create a new process by passing <options> to <proc.spawn>. On success, returns the process id of the child that was created. On failure, returns ACE_INVALID_PID. 
.SS int ACE_Process_Manager::spawn_n (size_t n, \fBACE_Process_Options\fR & options, \fBpid_t\fR * child_pids = 0)
.PP
Create <n> new processes by passing <options> to , which is called <n> times. If <child_pids> is non-0 it is expected to be an array of <n> <pid_t>'s, which are filled in with the process ids of each newly created process. Returns 0 on success and -1 on failure. 
.SS int ACE_Process_Manager::terminate (\fBpid_t\fR pid, int sig)
.PP
On OSs that support signals, send the signal to the specified process. Returns 0 on success and -1 on failure.
.PP
.SS int ACE_Process_Manager::terminate (\fBpid_t\fR pid)
.PP
Abruptly terminate a single process with id <pid> using the  method. Note that this call is potentially dangerous to use since the process being terminated may not have a chance to cleanup before it shuts down. Returns 0 on success and -1 on failure. 
.SS \fBpid_t\fR ACE_Process_Manager::wait (\fBpid_t\fR pid, \fBACE_exitcode\fR * status = 0)
.PP
Wait indefinitely for a single process to terminate. If pid==0, waits for any of the managed <Process>es (but see the note in the class documentation for caveats about this -- "sloppy Process cleanup on unix") If pid != 0, waits for that <Process> only. Returns the pid of the process whose exit was handled, or ACE_INVALID_PID on error. 
.SS \fBpid_t\fR ACE_Process_Manager::wait (\fBpid_t\fR pid, const \fBACE_Time_Value\fR & timeout, \fBACE_exitcode\fR * status = 0)
.PP
Wait up to <timeout> for a single process to terminate. If pid==0, waits for any of the managed <Process>es (but see the note in the class documentation above for caveats about this -- "sloppy process cleanup on unix") If pid != 0, waits for that <Process> only. Returns the pid of the Process whose exit was handled, 0 if a timeout occurred, or ACE_INVALID_PID on error. 
.SS int ACE_Process_Manager::wait (const \fBACE_Time_Value\fR & timeout = \fBACE_Time_Value::max_time\fR)
.PP
Block until there are no more child processes running that were <spawn>ed by this . Unlike the <wait> call below, this method does not require a signal handler or  because it simply blocks synchronously waiting for all the children managed by this  to exit. Note that this does not return any status information about the success or failure of exiting child processes, although any registered exit_handlers are called. Returns 0 on success (and <remove>s the corresponding  entries from the <Process_Manager>; otherwise, returns -1 on failure. 
.SH FRIENDS AND RELATED FUNCTION DOCUMENTATION
.PP 
.SS class ACE_Process_Control\fC [friend]\fR
.PP
.SH MEMBER DATA DOCUMENTATION
.PP 
.SS ACE_Process_Manager::ACE_ALLOC_HOOK_DECLARE
.PP
Declare the dynamic allocation hooks.
.PP
.SS size_t ACE_Process_Manager::current_count_\fC [private]\fR
.PP
Current number of processes we are managing.
.PP
.SS \fBACE_Event_Handler\fR * ACE_Process_Manager::default_exit_handler_\fC [private]\fR
.PP
This event handler is used to notify when a process we control exits.
.PP
.SS int ACE_Process_Manager::delete_instance_\fC [static, private]\fR
.PP
Controls whether the <Process_Manager> is deleted when we shut down (we can only delete it safely if we created it!).
.PP
.SS ACE_Process_Manager * ACE_Process_Manager::instance_\fC [static, private]\fR
.PP
Singleton pointer.
.PP
.SS \fBACE_Recursive_Thread_Mutex\fR ACE_Process_Manager::lock_\fC [private]\fR
.PP
This lock protects access/ops on <process_table_>.
.PP
.SS size_t ACE_Process_Manager::max_process_table_size_\fC [private]\fR
.PP
Maximum number of processes we can manage (should be dynamically allocated).
.PP
.SS \fBACE_Process_Descriptor\fR * ACE_Process_Manager::process_table_\fC [private]\fR
.PP
Vector that describes process state within the Process_Manager.
.PP


.SH AUTHOR
.PP 
Generated automatically by Doxygen for ACE from the source code.