00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Process_Manager.h 00006 * 00007 * Process_Manager.h,v 4.48 2006/04/21 16:29:35 wotte Exp 00008 * 00009 * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> 00010 */ 00011 //============================================================================= 00012 00013 #ifndef ACE_PROCESS_MANAGER_H 00014 #define ACE_PROCESS_MANAGER_H 00015 00016 #include /**/ "ace/pre.h" 00017 00018 #include "ace/ACE_export.h" 00019 00020 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00021 # pragma once 00022 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00023 00024 #include "ace/Process.h" 00025 #include "ace/Event_Handler.h" 00026 #include "ace/Time_Value.h" 00027 00028 #if defined (ACE_HAS_THREADS) 00029 # include "ace/Recursive_Thread_Mutex.h" 00030 #endif /* ACE_HAS_THREADS */ 00031 00032 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00033 00034 class ACE_Reactor; 00035 00036 /** 00037 * @class ACE_Process_Descriptor 00038 * 00039 * @brief Information describing each process that's controlled by an 00040 * <ACE_Process_Manager>. 00041 */ 00042 class ACE_Export ACE_Process_Descriptor 00043 { 00044 private: 00045 friend class ACE_Process_Manager; 00046 00047 /// Default ctor/dtor. 00048 ACE_Process_Descriptor (void); 00049 ~ACE_Process_Descriptor (void); 00050 00051 /// Describes the process itself. 00052 ACE_Process *process_; 00053 00054 /// function to call when process exits 00055 ACE_Event_Handler *exit_notify_; 00056 00057 /// Dump the state of an object. 00058 void dump (void) const; 00059 }; 00060 00061 /** 00062 * @class ACE_Process_Manager 00063 * 00064 * @brief Manages a group of processes. 00065 * 00066 * This class allows applications to control groups of processes, 00067 * similar to how the <ACE_Thread_Manager> controls groups of 00068 * threads. Naturally, it doesn't work at all on platforms, such 00069 * as VxWorks or pSoS, that don't support process. 00070 * There are two (main) ways of using <ACE_Process_Manager>, 00071 * depending on how involved you wish to be with the termination 00072 * of managed <ACE_Process>es. If you just want <Process>es to 00073 * go away when they're finished, simply register the 00074 * <Process_Manager> with an <ACE_Reactor>: 00075 * ACE_Process_Manager mgr( 100, some_reactor ) 00076 * -or- 00077 * ACE_Process_Manager mgr; 00078 * ... 00079 * mgr.open( 100, some_reactor ); 00080 * Then, the <Process_Manager> will clean up after any 00081 * <Process>es that it spawns. (On Unix, this means executing a 00082 * wait(2) to collect the exit status -- and avoid zombie 00083 * processes; on Win32, it means closing the process and thread 00084 * HANDLEs that are created when CreateProcess is called.) 00085 * If, on the other hand (and for some inexplicable reason) you 00086 * want to explicitly invoke the terminated <Process> cleanup 00087 * code, then *don't* register the <Process_Manager> with a 00088 * Reactor, and be sure to call one of the 00089 * <Process_Manager::wait> functions whenever there might be 00090 * managed <Process>es that have exited. 00091 * Note that in either case, <Process_Manager> allows you to 00092 * register "<Event_Handlers>" to be called when a specific 00093 * <Process> exits, or when any <Process> without a specific 00094 * <Event_Handler> exits. When a <Process> exits, the 00095 * appropriate <Event_Handler>'s <handle_input> is called; the 00096 * ACE_HANDLE passed is either the Process' HANDLE (on Win32), 00097 * or its pid cast to an ACE_HANDLE (on unix). 00098 * It is also possible to call the <Process_Manager::wait> 00099 * functions even though the <Process_Manager> is registered with 00100 * a <Reactor>. 00101 * Note also that the wait functions are "sloppy" on Unix, 00102 * because there's no good way to wait for a subset of the 00103 * children of a process. The wait functions may end up 00104 * collecting the exit status of a process that's not managed by 00105 * the <Process_Manager> whose <wait> you invoked. It's best to 00106 * only use a single <Process_Manager>, and to create all 00107 * subprocesses by calling that <Process_Manager>'s <spawn> 00108 * method. 00109 * Incidentally, when you register your <Process_Manager> with a 00110 * <Reactor> its notification pipe is used to help "reap" the 00111 * available exit statuses. Therefore, you must not use a 00112 * <Reactor> whose notify pipe has been disabled. Here's the 00113 * sequence of steps used to reap the exit statuses in this case: 00114 * + The <Process_Manager> registers a signal handler for 00115 * SIGCHLD. 00116 * + The SIGCHLD handler, when invoked, uses the <Reactor>'s 00117 * <notify> method to inform the <Reactor> to wake up. 00118 * + Next, the <Reactor> calls the <Process_Manager>'s 00119 * <handle_input>, this happens synchronously, not in 00120 * sighandler-space. 00121 * + The <handle_input> method collects all available exit 00122 * statuses. 00123 */ 00124 class ACE_Export ACE_Process_Manager : protected ACE_Event_Handler 00125 { 00126 public: 00127 friend class ACE_Process_Control; 00128 00129 enum 00130 { 00131 DEFAULT_SIZE = 100 00132 }; 00133 00134 // = Initialization and termination methods. 00135 /** 00136 * Initialize an <ACE_Process_Manager> with a table containing up to 00137 * <size> processes. This table resizes itself automatically as 00138 * needed. If a non-NULL <reactor> is provided, this 00139 * <ACE_Process_Manager> uses it to notify an application when a 00140 * process it controls exits. By default, however, we don't use an 00141 * ACE_Reactor. 00142 */ 00143 ACE_Process_Manager (size_t size = ACE_Process_Manager::DEFAULT_SIZE, 00144 ACE_Reactor *reactor = 0); 00145 00146 /** 00147 * Initialize an <ACE_Process_Manager> with a table containing up to 00148 * <size> processes. This table resizes itself automatically as 00149 * needed. If a non-NULL <reactor> is provided, this 00150 * <ACE_Process_Manager> uses it to notify an application when a 00151 * process it controls exits. By default, however, we don't use an 00152 * ACE_Reactor. 00153 */ 00154 int open (size_t size = DEFAULT_SIZE, 00155 ACE_Reactor *r = 0); 00156 00157 /// Release all resources. Do not wait for processes to exit. 00158 int close (void); 00159 00160 /// Destructor releases all resources and does not wait for processes 00161 /// to exit. 00162 virtual ~ACE_Process_Manager (void); 00163 00164 // = Singleton accessors. 00165 /// Get pointer to a process-wide <ACE_Process_Manager>. 00166 static ACE_Process_Manager *instance (void); 00167 00168 /// Set pointer to a process-wide <ACE_Process_Manager> and return 00169 /// existing pointer. 00170 static ACE_Process_Manager *instance (ACE_Process_Manager *); 00171 00172 /// Delete the dynamically allocated singleton. 00173 static void close_singleton (void); 00174 00175 /// Cleanup method, used by the <ACE_Object_Manager> to destroy the 00176 /// singleton. 00177 static void cleanup (void *instance, void *arg); 00178 00179 // = Process creation methods. 00180 00181 /** 00182 * Create a new process by passing <options> to <proc.spawn>. 00183 * Register <event_handler> to be called back when the process exits. 00184 * 00185 * On success, returns the process id of the child that was created. 00186 * On failure, returns ACE_INVALID_PID. 00187 */ 00188 pid_t spawn (ACE_Process *proc, 00189 ACE_Process_Options &options, 00190 ACE_Event_Handler *event_handler = 0); 00191 00192 /** 00193 * Create a new process by passing <options> to <ACE_Process::spawn>. 00194 * Register <event_handler> to be called back when the process exits. 00195 * 00196 * On success, returns the process id of the child that was created. 00197 * On failure, returns ACE_INVALID_PID. 00198 */ 00199 pid_t spawn (ACE_Process_Options &options, 00200 ACE_Event_Handler *event_handler = 0); 00201 00202 /** 00203 * Create <n> new processes by passing <options> to 00204 * <ACE_Process::spawn>, which is called <n> times. If <child_pids> 00205 * is non-0 it is expected to be an array of <n> <pid_t>'s, which 00206 * are filled in with the process ids of each newly created process. 00207 * Register <event_handler> to be called back when each process exits. 00208 * Returns 0 on success and -1 on failure. 00209 */ 00210 int spawn_n (size_t n, 00211 ACE_Process_Options &options, 00212 pid_t *child_pids = 0, 00213 ACE_Event_Handler *event_Handler = 0); 00214 00215 // = Process synchronization operations. 00216 00217 /** 00218 * Block until there are no more child processes running that were 00219 * <spawn>ed by this <ACE_Process_Manager>. Unlike the <wait> call 00220 * below, this method does not require a signal handler or 00221 * <ACE_OS::sigwait> because it simply blocks synchronously waiting 00222 * for all the children managed by this <ACE_Process_Manager> to 00223 * exit. Note that this does not return any status information 00224 * about the success or failure of exiting child processes, although 00225 * any registered exit_handlers are called. Returns 0 on success 00226 * (and <remove>s the corresponding <ACE_Process_Descriptor> entries 00227 * from the <Process_Manager>; otherwise, returns -1 on failure. 00228 */ 00229 int wait (const ACE_Time_Value &timeout = ACE_Time_Value::max_time); 00230 00231 /** 00232 * Wait up to <timeout> for a single process to terminate. If 00233 * pid==0, waits for any of the managed <Process>es (but see the 00234 * note in the class documentation above for caveats about this -- 00235 * "sloppy process cleanup on unix") If pid != 0, waits for that <Process> 00236 * only. Returns the pid of the Process whose exit was handled, 0 00237 * if a timeout occurred, or ACE_INVALID_PID on error. 00238 */ 00239 pid_t wait (pid_t pid, 00240 const ACE_Time_Value &timeout, 00241 ACE_exitcode *status = 0); 00242 00243 /** 00244 * Wait indefinitely for a single process to terminate. If pid==0, 00245 * waits for any of the managed <Process>es (but see the note in 00246 * the class documentation for caveats about this -- "sloppy Process 00247 * cleanup on unix") If pid != 0, waits for that <Process> only. 00248 * Returns the pid of the process whose exit was handled, or 00249 * ACE_INVALID_PID on error. 00250 */ 00251 pid_t wait (pid_t pid, 00252 ACE_exitcode *status = 0); 00253 00254 /** 00255 * @deprecated 00256 * Reap the result of a single process by calling <ACE_OS::waitpid>, 00257 * therefore, this method is not portable to Win32. If the child is 00258 * successfully reaped, <remove> is called automatically. This 00259 * method does the same thing that the <wait> method directly above 00260 * it does -- It's just here for backwards compatibility. 00261 */ 00262 int reap (pid_t pid = -1, 00263 ACE_exitcode *stat_loc = 0, 00264 int options = WNOHANG); 00265 00266 // = Utility methods. 00267 /** 00268 * Register an Event_Handler to be called back when the specified 00269 * process exits. If pid == ACE_INVALID_PID this handler is called 00270 * when any process with no specific handler exits. 00271 * 00272 * @note In multi-threaded applications, there is a race condition 00273 * if a process exits between the time it is spawned and when its 00274 * handler is registered. To avoid this, register the handler at 00275 * the time the process is spawned. 00276 */ 00277 int register_handler (ACE_Event_Handler *event_handler, 00278 pid_t pid = ACE_INVALID_PID); 00279 00280 /** 00281 * Remove process <pid> from the table. This is called 00282 * automatically by the <reap> method after it successfully reaped a 00283 * <SIGCHLD> signal. It's also possible to call this method 00284 * directly from a signal handler, but don't call both <reap> and 00285 * <remove>! 00286 */ 00287 int remove (pid_t pid); 00288 00289 /** 00290 * Abruptly terminate a single process with id <pid> using the 00291 * <ACE::terminate_process> method. Note that this call is 00292 * potentially dangerous to use since the process being terminated 00293 * may not have a chance to cleanup before it shuts down. Returns 0 00294 * on success and -1 on failure. 00295 */ 00296 int terminate (pid_t pid); 00297 00298 /// On OSs that support signals, send the signal to the specified 00299 /// process. Returns 0 on success and -1 on failure. 00300 int terminate (pid_t pid, 00301 int sig); 00302 00303 /// Return the number of managed Processes. 00304 size_t managed (void) const; 00305 /** 00306 * Sets the scheduling parameters for the <Process> managed by 00307 * <ACE_Process_Manager> identified by pid by passing <params>, <pid> to 00308 * <ACE_OS::sched_params>. Returns 0 on success, -1 on failure, and 00309 * ACE_INVALID_PID when given pid is not managed by 00310 * <ACE_Process_Manager>. 00311 */ 00312 int set_scheduler (const ACE_Sched_Params ¶ms, 00313 pid_t pid); 00314 00315 /** 00316 * Sets the scheduling parameters for all the <Process>es managed by 00317 * <ACE_Process_Manager> by passing <params> to 00318 * <ACE_OS::sched_params>. Returns 0 on success, -1 on failure. 00319 */ 00320 int set_scheduler_all (const ACE_Sched_Params &); 00321 00322 /// Dump the state of an object. 00323 void dump (void) const; 00324 00325 /// Declare the dynamic allocation hooks. 00326 ACE_ALLOC_HOOK_DECLARE; 00327 00328 protected: 00329 // = These methods allow a <Process_Manager> to be an <Event_Handler>. 00330 00331 // As an <Event_Handler>, the <Process_Manager> automagically 00332 // detects child Processes exiting and calls notify_proc_handler() 00333 // and remove(). This means that you don't have to (shouldn't!) 00334 // call the wait(...) methods yourself. 00335 00336 // On Unix, we can't detect individual process termination very 00337 // well; the best method is to catch SIGCHLD and then call the 00338 // polling wait() function to collect any available exit statuses. 00339 // However, we don't want to do this from within a signal handler 00340 // because of the restrictions associated. Therefore (following the 00341 // lead in examples/mumble) we open a bogus handle (to ACE_DEV_NULL) 00342 // and register that handle with our Reactor. Then, when our 00343 // SIGCHLD handler gets invoked, we tell the Reactor that the bogus 00344 // handle is readable. That will cause the handle_input() function 00345 // to be called once we're out of the interrupt context, and 00346 // handle_input() collects exit statuses. 00347 00348 // On Win32, we simply register ourself with the Reactor to deal 00349 // with the Process handle becoming signaled. No muss, no fuss, no 00350 // signal handler, and no dummy handle. 00351 00352 #if !defined(ACE_WIN32) 00353 /// Collect one (or more, on unix) process exit status. 00354 virtual int handle_input (ACE_HANDLE proc); 00355 #endif // !defined(ACE_WIN32) 00356 00357 /** 00358 * On Unix, this routine is called asynchronously when a SIGCHLD is 00359 * received. We just tweak the reactor so that it'll call back our 00360 * <handle_input> function, which allows us to handle Process exits 00361 * synchronously. 00362 * 00363 * On Win32, this routine is called synchronously, and is passed the 00364 * HANDLE of the Process that exited, so we can do all our work here 00365 */ 00366 virtual int handle_signal (int signum, 00367 siginfo_t * = 0, 00368 ucontext_t * = 0); 00369 00370 private: 00371 /// Resize the pool of Process_Descriptors. 00372 int resize (size_t); 00373 00374 /// Locate the index of the table slot occupied by <process_id>. 00375 /// Returns -1 if <process_id> is not in the <process_table_> 00376 ssize_t find_proc (pid_t process_id); 00377 00378 #if defined (ACE_WIN32) 00379 /// Locate the index of the table slot occupied by <process_handle>. 00380 /// Returns ~0 if <process_handle> is not in the <process_table_> 00381 ssize_t find_proc (ACE_HANDLE process_handle); 00382 #endif /* ACE_WIN32 */ 00383 00384 /// Insert a process in the table (checks for duplicates). Omitting 00385 /// the process handle won't work on Win32... 00386 /// Register <event_handler> to be called back when the process exits. 00387 int insert_proc (ACE_Process *process, 00388 ACE_Event_Handler *event_handler = 0); 00389 00390 /** 00391 * Append information about a process, i.e., its <process_id> in the 00392 * <process_table_>. Each entry is added at the end, growing the 00393 * table if necessary. 00394 * Register <event_handler> to be called back when the process exits. 00395 */ 00396 int append_proc (ACE_Process *process, 00397 ACE_Event_Handler *event_handler = 0); 00398 00399 /// Actually removes the process at index <n> from the table. This method 00400 /// must be called with locks held. 00401 int remove_proc (size_t n); 00402 00403 /// If there's a specific handler for the Process at index <n> in the 00404 /// table, or there's a default handler, call it. 00405 int notify_proc_handler (size_t n, 00406 ACE_exitcode status); 00407 00408 /// Vector that describes process state within the Process_Manager. 00409 ACE_Process_Descriptor *process_table_; 00410 00411 /// Maximum number of processes we can manage (should be dynamically 00412 /// allocated). 00413 size_t max_process_table_size_; 00414 00415 /// Current number of processes we are managing. 00416 size_t current_count_; 00417 00418 /// This event handler is used to notify when a process we control 00419 /// exits. 00420 ACE_Event_Handler *default_exit_handler_; 00421 00422 /// Singleton pointer. 00423 static ACE_Process_Manager *instance_; 00424 00425 /// Controls whether the <Process_Manager> is deleted when we shut 00426 /// down (we can only delete it safely if we created it!) 00427 static int delete_instance_; 00428 00429 #if defined (ACE_HAS_THREADS) 00430 /// This lock protects access/ops on <process_table_>. 00431 ACE_Recursive_Thread_Mutex lock_; 00432 #endif /* ACE_HAS_THREADS */ 00433 }; 00434 00435 ACE_END_VERSIONED_NAMESPACE_DECL 00436 00437 #if defined (__ACE_INLINE__) 00438 #include "ace/Process_Manager.inl" 00439 #endif /* __ACE_INLINE__ */ 00440 00441 #include /**/ "ace/post.h" 00442 #endif /* ACE_PROCESS_MANAGER_H */