ACE_Process_Manager Class Reference

Manages a group of processes. More...

#include <Process_Manager.h>

Inheritance diagram for ACE_Process_Manager:

Inheritance graph
[legend]
Collaboration diagram for ACE_Process_Manager:

Collaboration graph
[legend]
List of all members.

Utility methods

int register_handler (ACE_Event_Handler *event_handler, pid_t pid=ACE_INVALID_PID)
int remove (pid_t pid)
size_t managed (void) const
 Return the number of managed processes.
int set_scheduler (const ACE_Sched_Params &params, pid_t pid)
int set_scheduler_all (const ACE_Sched_Params &params)
void dump (void) const
 Dump the state of an object.
 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks.

Public Types

 DEFAULT_SIZE = 100
enum  { DEFAULT_SIZE = 100 }

Public Member Functions

Initialization and termination methods
 ACE_Process_Manager (size_t size=ACE_Process_Manager::DEFAULT_SIZE, ACE_Reactor *reactor=0)
int open (size_t size=ACE_Process_Manager::DEFAULT_SIZE, ACE_Reactor *r=0)
int close (void)
 Release all resources. Do not wait for processes to exit.
virtual ~ACE_Process_Manager (void)
Process creation methods
pid_t spawn (ACE_Process *proc, ACE_Process_Options &options, ACE_Event_Handler *event_handler=0)
pid_t spawn (ACE_Process_Options &options, ACE_Event_Handler *event_handler=0)
int spawn_n (size_t n, ACE_Process_Options &options, pid_t *child_pids=0, ACE_Event_Handler *event_Handler=0)
Process synchronization operations
int terminate (pid_t pid)
int terminate (pid_t pid, int sig)
int wait (const ACE_Time_Value &timeout=ACE_Time_Value::max_time)
pid_t wait (pid_t pid, const ACE_Time_Value &timeout, ACE_exitcode *status=0)
pid_t wait (pid_t pid, ACE_exitcode *status=0)
int reap (pid_t pid=-1, ACE_exitcode *stat_loc=0, int options=WNOHANG)

Static Public Member Functions

Singleton access and control
static ACE_Process_Managerinstance (void)
 Get pointer to a process-wide ACE_Process_Manager.
static ACE_Process_Managerinstance (ACE_Process_Manager *)
static void close_singleton (void)
 Delete the dynamically allocated singleton.
static void cleanup (void *instance, void *arg)

Protected Member Functions

virtual int handle_input (ACE_HANDLE proc)
 Collect one (or more, on unix) process exit status.
virtual int handle_signal (int signum, siginfo_t *=0, ucontext_t *=0)

Private Member Functions

int resize (size_t)
 Resize the pool of Process_Descriptors.
ssize_t find_proc (pid_t process_id)
int insert_proc (ACE_Process *process, ACE_Event_Handler *event_handler=0)
int append_proc (ACE_Process *process, ACE_Event_Handler *event_handler=0)
int remove_proc (size_t n)
int notify_proc_handler (size_t n, ACE_exitcode status)

Private Attributes

Process_Descriptorprocess_table_
 Vector that describes process state within the Process_Manager.
size_t max_process_table_size_
size_t current_count_
 Current number of processes we are managing.
ACE_Event_Handlerdefault_exit_handler_

Static Private Attributes

static ACE_Process_Managerinstance_ = 0
 Singleton pointer.
static bool delete_instance_ = false

Friends

class ACE_Process_Control

Classes

struct  Process_Descriptor
 Information describing each process that's controlled by an ACE_Process_Manager. More...

Detailed Description

Manages a group of processes.

This class allows applications to control groups of processes, similar to how the ACE_Thread_Manager 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 ACE_Process_Manager, depending on how involved you wish to be with the termination of managed processes. If you want processes to simply go away when they're finished, register the ACE_Process_Manager with an ACE_Reactor that can handle notifications of child process exit:

 ACE_Process_Manager mgr;
 // ...
 mgr.open (100, ACE_Reactor::instance ());
In this usage scenario, the ACE_Process_Manager will clean up after any processes 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.)

Note:
When you register a ACE_Process_Manager with a ACE_Reactor, the reactor's notification pipe is used to help reap the available process 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:
  1. The ACE_Process_Manager registers a signal handler for SIGCHLD.
  2. The SIGCHLD handler, when invoked, uses the ACE_Reactor's notify() method to inform the ACE_Reactor to wake up.
  3. The ACE_Reactor calls the ACE_Process_Manager's handle_input() method; this happens synchronously, not in signal context.
  4. The handle_input() method collects all available exit statuses.
If, on the other hand you want to wait "in line" to handle the terminated process cleanup code, call one of the wait functions whenever there might be managed processes that have exited.

Note that in either case, ACE_Process_Manager allows you to register an ACE_Event_Handler to be called when a specific spawned process exits, or when any process without a specific ACE_Event_Handler exits. When a process exits, the appropriate ACE_Event_Handler's handle_input() method is called; the ACE_HANDLE passed is either the process's HANDLE (on Win32), or its pid cast to an ACE_HANDLE (on POSIX). It is also possible to call the wait() functions even when the ACE_Process_Manager is registered with a reactor.

Note:
Be aware 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 ACE_Process_Manager whose wait() you invoked. It's best to only use a single ACE_Process_Manager, and to create all subprocesses by calling that manager's spawn() method.

Definition at line 98 of file Process_Manager.h.


Member Enumeration Documentation

anonymous enum

Enumerator:
DEFAULT_SIZE 

Definition at line 103 of file Process_Manager.h.

00104   {
00105     DEFAULT_SIZE = 100
00106   };


Constructor & Destructor Documentation

ACE_Process_Manager::ACE_Process_Manager ( size_t  size = ACE_Process_Manager::DEFAULT_SIZE,
ACE_Reactor reactor = 0 
)

Initialize an ACE_Process_Manager with a table containing up to size processes. This table resizes itself automatically as needed. If a reactor is provided, this ACE_Process_Manager uses it to notify an application when a process it controls exits. By default, however, we don't use an ACE_Reactor.

Definition at line 245 of file Process_Manager.cpp.

References ACE_ERROR, ACE_TEXT, ACE_TRACE, and LM_ERROR.

00247   : ACE_Event_Handler (),
00248     process_table_ (0),
00249     max_process_table_size_ (0),
00250     current_count_ (0),
00251     default_exit_handler_ (0)
00252 #if defined (ACE_HAS_THREADS)
00253   , lock_ ()
00254 #endif /* ACE_HAS_THREADS */
00255 {
00256   ACE_TRACE ("ACE_Process_Manager::ACE_Process_Manager");
00257 
00258   if (this->open (size,
00259                   r) == -1)
00260     ACE_ERROR ((LM_ERROR,
00261                 ACE_TEXT ("%p\n"),
00262                 ACE_TEXT ("ACE_Process_Manager")));
00263 }

ACE_Process_Manager::~ACE_Process_Manager ( void   )  [virtual]

Destructor releases all resources and does not wait for processes to exit.

Definition at line 300 of file Process_Manager.cpp.

References ACE_TRACE, and close().

00301 {
00302   ACE_TRACE ("ACE_Process_Manager::~ACE_Process_Manager");
00303   this->close ();
00304 }


Member Function Documentation

int ACE_Process_Manager::append_proc ( ACE_Process process,
ACE_Event_Handler event_handler = 0 
) [private]

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. Register event_handler to be called back when the process exits.

Definition at line 496 of file Process_Manager.cpp.

References ACE_TRACE, current_count_, DEFAULT_SIZE, ACE_Process_Manager::Process_Descriptor::exit_notify_, ACE_Process::gethandle(), max_process_table_size_, ACE_Process_Manager::Process_Descriptor::process_, process_table_, ACE_Event_Handler::reactor(), and ACE_Reactor::register_handler().

Referenced by insert_proc().

00498 {
00499   ACE_TRACE ("ACE_Process_Manager::append_proc");
00500 
00501   // Try to resize the array to twice its existing size (or the DEFAULT_SIZE,
00502   // if there are no array entries) if we run out of space...
00503   if (this->current_count_ >= this->max_process_table_size_)
00504     {
00505       size_t new_size = this->max_process_table_size_ * 2;
00506       if (new_size == 0)
00507         new_size = ACE_Process_Manager::DEFAULT_SIZE;
00508       if (this->resize (new_size) == -1)
00509         return -1;
00510     }
00511 
00512   Process_Descriptor &proc_desc =
00513     this->process_table_[this->current_count_];
00514 
00515   proc_desc.process_ = proc;
00516   proc_desc.exit_notify_ = event_handler;
00517 
00518 #if defined (ACE_WIN32)
00519   // If we have a Reactor, then we're supposed to reap Processes
00520   // automagically.  Get a handle to this new Process and tell the
00521   // Reactor we're interested in <handling_input> on it.
00522   ACE_Reactor * const r = this->reactor ();
00523   if (r != 0)
00524     r->register_handler (this, proc->gethandle ());
00525 #endif /* ACE_WIN32 */
00526 
00527   ++this->current_count_;
00528   return 0;
00529 }

ACE_BEGIN_VERSIONED_NAMESPACE_DECL void ACE_Process_Manager::cleanup ( void *  instance,
void *  arg 
) [static]

Cleanup method, used by the ACE_Object_Manager to destroy the singleton.

Definition at line 38 of file Process_Manager.cpp.

References close_singleton().

Referenced by instance().

00039 {
00040   ACE_Process_Manager::close_singleton ();
00041 }

int ACE_Process_Manager::close ( void   ) 

Release all resources. Do not wait for processes to exit.

Definition at line 268 of file Process_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, current_count_, default_exit_handler_, ACE_Event_Handler::handle_close(), max_process_table_size_, process_table_, ACE_Event_Handler::reactor(), ACE_Reactor::remove_handler(), remove_proc(), and SIGCHLD.

Referenced by ~ACE_Process_Manager().

00269 {
00270   ACE_TRACE ("ACE_Process_Manager::close");
00271 
00272   if (this->reactor () != 0)
00273     {
00274 #if !defined (ACE_WIN32) && !defined (ACE_LACKS_UNIX_SIGNALS)
00275       this->reactor ()->remove_handler (SIGCHLD, (ACE_Sig_Action *) 0);
00276 #endif /*  !ACE_WIN32  */
00277       this->reactor (0);
00278     }
00279 
00280   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00281 
00282   if (this->process_table_ != 0)
00283     {
00284       while (this->current_count_ > 0)
00285         this->remove_proc (0);
00286 
00287       delete [] this->process_table_;
00288       this->process_table_ = 0;
00289       this->max_process_table_size_ = 0;
00290       this->current_count_ = 0;
00291     }
00292 
00293   if (this->default_exit_handler_ != 0)
00294       this->default_exit_handler_->handle_close (ACE_INVALID_HANDLE,0);
00295   this->default_exit_handler_ = 0;
00296 
00297   return 0;
00298 }

void ACE_Process_Manager::close_singleton ( void   )  [static]

Delete the dynamically allocated singleton.

Definition at line 176 of file Process_Manager.cpp.

References ACE_GUARD, ACE_TRACE, delete_instance_, and instance_.

Referenced by cleanup().

00177 {
00178   ACE_TRACE ("ACE_Process_Manager::close_singleton");
00179 
00180   ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
00181                      *ACE_Static_Object_Lock::instance ()));
00182 
00183   if (ACE_Process_Manager::delete_instance_)
00184     {
00185       delete ACE_Process_Manager::instance_;
00186       ACE_Process_Manager::instance_ = 0;
00187       ACE_Process_Manager::delete_instance_ = false;
00188     }
00189 }

void ACE_Process_Manager::dump ( void   )  const

Dump the state of an object.

Definition at line 84 of file Process_Manager.cpp.

References ACE_BEGIN_DUMP, ACE_DEBUG, ACE_END_DUMP, ACE_TEXT, ACE_TRACE, current_count_, and LM_DEBUG.

00085 {
00086 #if defined (ACE_HAS_DUMP)
00087   ACE_TRACE ("ACE_Process_Manager::dump");
00088 
00089   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00090 
00091   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("\nmax_process_table_size_ = %d"), this->max_process_table_size_));
00092   ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("\ncurrent_count_ = %d"), this->current_count_));
00093 
00094   for (size_t i = 0; i < this->current_count_; i++)
00095     this->process_table_[i].dump ();
00096 
00097   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00098 #endif /* ACE_HAS_DUMP */
00099 }

ssize_t ACE_Process_Manager::find_proc ( pid_t  process_id  )  [private]

Locate the index of the table slot occupied by process_id. Returns -1 if process_id is not in the process_table_

Definition at line 684 of file Process_Manager.cpp.

References ACE_TRACE, and current_count_.

Referenced by handle_signal(), register_handler(), remove(), set_scheduler(), terminate(), and wait().

00685 {
00686   ACE_TRACE ("ACE_Process_Manager::find_proc");
00687 
00688   for (size_t i = 0; i < this->current_count_; ++i)
00689     if (pid == this->process_table_[i].process_->getpid ())
00690       return i;
00691 
00692   return -1;
00693 }

int ACE_Process_Manager::handle_input ( ACE_HANDLE  proc  )  [protected, virtual]

Collect one (or more, on unix) process exit status.

Reimplemented from ACE_Event_Handler.

Definition at line 315 of file Process_Manager.cpp.

References ACE_INVALID_PID, ACE_TRACE, wait(), and ACE_Time_Value::zero.

00316 {
00317   ACE_TRACE ("ACE_Process_Manager::handle_input");
00318 
00319    pid_t pid;
00320 
00321    do
00322      pid = this->wait (0,
00323                        ACE_Time_Value::zero);
00324    while (pid != 0 && pid != ACE_INVALID_PID);
00325 
00326   return 0;
00327 }

int ACE_Process_Manager::handle_signal ( int  signum,
siginfo_t = 0,
ucontext_t = 0 
) [protected, virtual]

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.

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

Reimplemented from ACE_Event_Handler.

Definition at line 340 of file Process_Manager.cpp.

References ACE_ERROR_RETURN, ACE_GUARD_RETURN, ACE_INVALID_PID, ACE_TEXT, find_proc(), ACE_Process::getpid(), LM_ERROR, ACE_Reactor::notify(), notify_proc_handler(), ACE_Process_Manager::Process_Descriptor::process_, process_table_, ACE_Event_Handler::reactor(), ACE_Event_Handler::READ_MASK, remove_proc(), and siginfo_t::si_handle_.

00343 {
00344 #if defined (ACE_WIN32)
00345   ACE_HANDLE proc = si->si_handle_;
00346   ACE_exitcode status = 0;
00347   BOOL result = ::GetExitCodeProcess (proc,
00348                                       &status);
00349   if (result)
00350     {
00351       if (status != STILL_ACTIVE)
00352         {
00353           {
00354             ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, lock_, -1));
00355 
00356             ssize_t const i = this->find_proc (proc);
00357             if (i == -1)
00358               return -1;
00359 #if 0
00360             pid_t pid = i != -1
00361               ? process_table_[i].process_->getpid ()
00362               : ACE_INVALID_PID;
00363 #endif
00364             this->notify_proc_handler (i, status);
00365             this->remove_proc (i);
00366           }
00367           return -1; // remove this HANDLE/Event_Handler combination
00368         }
00369       else
00370         ACE_ERROR_RETURN ((LM_ERROR,
00371                            ACE_TEXT ("Process still active")
00372                            ACE_TEXT (" -- shouldn't have been called yet!\n")),
00373                           0); // return 0 : stay registered
00374     }
00375   else
00376     {
00377       // <GetExitCodeProcess> failed.
00378       ACE_ERROR_RETURN ((LM_ERROR,
00379                          ACE_TEXT ("GetExitCodeProcess failed")),
00380                         -1); // return -1: unregister
00381     }
00382 #else /* !ACE_WIN32 */
00383   ACE_UNUSED_ARG (si);
00384   return reactor ()->notify (this, ACE_Event_Handler::READ_MASK);
00385 #endif /* !ACE_WIN32 */
00386 }

int ACE_Process_Manager::insert_proc ( ACE_Process process,
ACE_Event_Handler event_handler = 0 
) [private]

Insert a process in the table (checks for duplicates). Omitting the process handle won't work on Win32... Register event_handler to be called back when the process exits.

Definition at line 535 of file Process_Manager.cpp.

References ACE_TRACE, append_proc(), and ACE_Process::getpid().

00537 {
00538   ACE_TRACE ("ACE_Process_Manager::insert_proc");
00539 
00540   // Check for duplicates and bail out if they're already
00541   // registered...
00542   if (this->find_proc (proc->getpid ()) != -1)
00543     return -1;
00544 
00545   return this->append_proc (proc, event_handler);
00546 }

ACE_Process_Manager * ACE_Process_Manager::instance ( ACE_Process_Manager  )  [static]

Set pointer to a process-wide ACE_Process_Manager and return existing pointer.

Definition at line 147 of file Process_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, ACE_Object_Manager::at_exit(), cleanup(), delete_instance_, and instance_.

00148 {
00149   ACE_TRACE ("ACE_Process_Manager::instance");
00150   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00151                             *ACE_Static_Object_Lock::instance (), 0));
00152 
00153   ACE_Process_Manager *t = ACE_Process_Manager::instance_;
00154   // We can't safely delete it since we don't know who created it!
00155   ACE_Process_Manager::delete_instance_ = false;
00156 
00157   // Register with the Object_Manager so that the wrapper to
00158   // delete the proactor will be called when Object_Manager is
00159   // being terminated.
00160 
00161 #if defined ACE_HAS_SIG_C_FUNC
00162   ACE_Object_Manager::at_exit (ACE_Process_Manager::instance_,
00163                                 ACE_Process_Manager_cleanup,
00164                                 0);
00165 #else
00166   ACE_Object_Manager::at_exit (ACE_Process_Manager::instance_,
00167                                 ACE_Process_Manager::cleanup,
00168                                 0);
00169 #endif /* ACE_HAS_SIG_C_FUNC */
00170 
00171   ACE_Process_Manager::instance_ = tm;
00172   return t;
00173 }

ACE_Process_Manager * ACE_Process_Manager::instance ( void   )  [static]

Get pointer to a process-wide ACE_Process_Manager.

Definition at line 109 of file Process_Manager.cpp.

References ACE_GUARD_RETURN, ACE_NEW_RETURN, ACE_TRACE, ACE_Object_Manager::at_exit(), cleanup(), delete_instance_, and instance_.

00110 {
00111   ACE_TRACE ("ACE_Process_Manager::instance");
00112 
00113   if (ACE_Process_Manager::instance_ == 0)
00114     {
00115       // Perform Double-Checked Locking Optimization.
00116       ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00117                                 *ACE_Static_Object_Lock::instance (), 0));
00118 
00119       if (ACE_Process_Manager::instance_ == 0)
00120         {
00121           ACE_NEW_RETURN (ACE_Process_Manager::instance_,
00122                           ACE_Process_Manager,
00123                           0);
00124           ACE_Process_Manager::delete_instance_ = true;
00125 
00126           // Register with the Object_Manager so that the wrapper to
00127           // delete the proactor will be called when Object_Manager is
00128           // being terminated.
00129 
00130 #if defined ACE_HAS_SIG_C_FUNC
00131           ACE_Object_Manager::at_exit (ACE_Process_Manager::instance_,
00132                                        ACE_Process_Manager_cleanup,
00133                                        0);
00134 #else
00135           ACE_Object_Manager::at_exit (ACE_Process_Manager::instance_,
00136                                        ACE_Process_Manager::cleanup,
00137                                        0);
00138 #endif /* ACE_HAS_SIG_C_FUNC */
00139 
00140         }
00141     }
00142 
00143   return ACE_Process_Manager::instance_;
00144 }

ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_INLINE size_t ACE_Process_Manager::managed ( void   )  const

Return the number of managed processes.

Definition at line 8 of file Process_Manager.inl.

References current_count_.

00009 {
00010   return current_count_;
00011 }

int ACE_Process_Manager::notify_proc_handler ( size_t  n,
ACE_exitcode  status 
) [private]

If there's a specific handler for the Process at index n in the table, or there's a default handler, call it.

Definition at line 983 of file Process_Manager.cpp.

References ACE_DEBUG, ACE_TEXT, default_exit_handler_, ACE_Process::exit_code(), ACE_Process_Manager::Process_Descriptor::exit_notify_, ACE_Event_Handler::handle_exit(), LM_DEBUG, ACE_Process_Manager::Process_Descriptor::process_, and process_table_.

Referenced by handle_signal(), and wait().

00985 {
00986   if (i < this->current_count_)
00987     {
00988       Process_Descriptor &proc_desc =
00989         this->process_table_[i];
00990 
00991       proc_desc.process_->exit_code (exit_code);
00992 
00993       if (proc_desc.exit_notify_ != 0)
00994         proc_desc.exit_notify_->handle_exit (proc_desc.process_);
00995       else if (this->default_exit_handler_ != 0
00996                && this->default_exit_handler_->handle_exit (proc_desc.process_) < 0)
00997         {
00998           this->default_exit_handler_->handle_close
00999             (ACE_INVALID_HANDLE,
01000              0);
01001           this->default_exit_handler_ = 0;
01002         }
01003       return 1;
01004     }
01005   else
01006     {
01007       ACE_DEBUG ((LM_DEBUG,
01008                   ACE_TEXT ("(%P:%t|%T) ACE_Process_Manager::notify_proc_handler:")
01009                   ACE_TEXT (" unknown/unmanaged process reaped\n")));
01010       return 0;
01011     }
01012 }

int ACE_Process_Manager::open ( size_t  size = ACE_Process_Manager::DEFAULT_SIZE,
ACE_Reactor r = 0 
)

Initialize an ACE_Process_Manager with a table containing up to size processes. This table resizes itself automatically as needed. If a reactor is provided, this ACE_Process_Manager uses it to notify an application when a process it controls exits. By default, however, we don't use an ACE_Reactor.

Definition at line 222 of file Process_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, ACE_Event_Handler::reactor(), resize(), and SIGCHLD.

00223 {
00224   ACE_TRACE ("ACE_Process_Manager::open");
00225 
00226   if (r)
00227     {
00228       this->reactor (r);
00229 #if !defined (ACE_WIN32) && !defined (ACE_LACKS_UNIX_SIGNALS)
00230       // Register signal handler object.
00231       if (r->register_handler (SIGCHLD, this) == -1)
00232         return -1;
00233 #endif /* !defined(ACE_WIN32) */
00234     }
00235 
00236   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00237 
00238   if (this->max_process_table_size_ < size)
00239     this->resize (size);
00240   return 0;
00241 }

int ACE_Process_Manager::reap ( pid_t  pid = -1,
ACE_exitcode stat_loc = 0,
int  options = WNOHANG 
)

Deprecated:
Reap the result of a single process by calling ACE_OS::waitpid(), therefore, this method is not portable to Windows. If the child is successfully reaped, remove() is called automatically. Use one of the wait() methods instead of this method.

Definition at line 965 of file Process_Manager.cpp.

References ACE_BIT_ENABLED, ACE_TRACE, ACE_Time_Value::max_time, wait(), WNOHANG, and ACE_Time_Value::zero.

00968 {
00969   ACE_TRACE ("ACE_Process_Manager::reap");
00970 
00971   return this->wait (pid,
00972                      (ACE_BIT_ENABLED (options, WNOHANG)
00973                       ? ACE_Time_Value::zero
00974                       : ACE_Time_Value::max_time),
00975                      stat_loc);
00976 }

int ACE_Process_Manager::register_handler ( ACE_Event_Handler event_handler,
pid_t  pid = ACE_INVALID_PID 
)

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.

Warning:
In multithreaded applications, there is a race condition if a process exits between the time it is spawned and when its handler is registered. To avoid this, register the handler at the time the process is spawned.

Definition at line 389 of file Process_Manager.cpp.

References ACE_GUARD_RETURN, ACE_INVALID_PID, default_exit_handler_, ACE_Process_Manager::Process_Descriptor::exit_notify_, find_proc(), ACE_Event_Handler::handle_close(), and process_table_.

00391 {
00392   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00393 
00394   if (pid == ACE_INVALID_PID)
00395     {
00396       if (this->default_exit_handler_ != 0)
00397         this->default_exit_handler_->handle_close (ACE_INVALID_HANDLE, 0);
00398       this->default_exit_handler_ = eh;
00399       return 0;
00400     }
00401 
00402   ssize_t const i = this->find_proc (pid);
00403 
00404   if (i == -1)
00405     {
00406       errno = EINVAL;
00407       return -1;
00408     }
00409 
00410   Process_Descriptor &proc_desc = this->process_table_[i];
00411 
00412   if (proc_desc.exit_notify_ != 0)
00413     proc_desc.exit_notify_->handle_close (ACE_INVALID_HANDLE, 0);
00414   proc_desc.exit_notify_ = eh;
00415   return 0;
00416 }

int ACE_Process_Manager::remove ( pid_t  pid  ) 

Remove process pid from the ACE_Process_Manager's internal records. This is called automatically by the reap() method after it successfully reaps a process. It's also possible to call this method directly from a signal handler, but don't call both reap() and remove()!

Definition at line 551 of file Process_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, find_proc(), and remove_proc().

Referenced by wait().

00552 {
00553   ACE_TRACE ("ACE_Process_Manager::remove");
00554 
00555   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00556 
00557   ssize_t const i = this->find_proc (pid);
00558 
00559   if (i != -1)
00560     return this->remove_proc (i);
00561 
00562   // set "process not found" error
00563   return -1;
00564 }

int ACE_Process_Manager::remove_proc ( size_t  n  )  [private]

Actually removes the process at index n from the table. This method must be called with locks held.

Definition at line 569 of file Process_Manager.cpp.

References ACE_TRACE, current_count_, ACE_Event_Handler::DONT_CALL, ACE_Process_Manager::Process_Descriptor::exit_notify_, ACE_Event_Handler::handle_close(), ACE_Process_Manager::Process_Descriptor::process_, process_table_, ACE_Event_Handler::reactor(), ACE_Reactor::remove_handler(), and ACE_Process::unmanage().

Referenced by close(), handle_signal(), remove(), and wait().

00570 {
00571   ACE_TRACE ("ACE_Process_Manager::remove_proc");
00572 
00573   // If there's an exit_notify_ <Event_Handler> for this pid, call its
00574   // <handle_close> method.
00575 
00576   if (this->process_table_[i].exit_notify_ != 0)
00577     {
00578       this->process_table_[i].exit_notify_->handle_close
00579         (this->process_table_[i].process_->gethandle(),
00580          0);
00581       this->process_table_[i].exit_notify_ = 0;
00582     }
00583 
00584 #if defined (ACE_WIN32)
00585   ACE_Reactor * const r = this->reactor ();
00586   if (r != 0)
00587     r->remove_handler (this->process_table_[i].process_->gethandle (),
00588                        ACE_Event_Handler::DONT_CALL);
00589 #endif /* ACE_WIN32 */
00590 
00591   this->process_table_[i].process_->unmanage ();
00592 
00593   this->process_table_[i].process_ = 0;
00594 
00595   this->current_count_--;
00596 
00597   if (this->current_count_ > 0)
00598     // Compact the table by moving the last item into the slot vacated
00599     // by the index being removed (this is a structure assignment).
00600     this->process_table_[i] =
00601       this->process_table_[this->current_count_];
00602 
00603   return 0;
00604 }

int ACE_Process_Manager::resize ( size_t   )  [private]

Resize the pool of Process_Descriptors.

Definition at line 192 of file Process_Manager.cpp.

References ACE_NEW_RETURN, ACE_TRACE, current_count_, and max_process_table_size_.

Referenced by open().

00193 {
00194   ACE_TRACE ("ACE_Process_Manager::resize");
00195 
00196   if (size <= this->max_process_table_size_)
00197     return 0;
00198 
00199   Process_Descriptor *temp = 0;
00200 
00201   ACE_NEW_RETURN (temp,
00202                   Process_Descriptor[size],
00203                   -1);
00204 
00205   for (size_t i = 0;
00206        i < this->current_count_;
00207        i++)
00208     // Structure assignment.
00209     temp[i] = this->process_table_[i];
00210 
00211   this->max_process_table_size_ = size;
00212 
00213   delete [] this->process_table_;
00214 
00215   this->process_table_ = temp;
00216   return 0;
00217 }

int ACE_Process_Manager::set_scheduler ( const ACE_Sched_Params params,
pid_t  pid 
)

Sets the scheduling parameters for process identified by pid by passing params, pid to ACE_OS::sched_params().

Return values:
0 on success, -1 on failure, and ACE_INVALID_PID when the specified pid is not managed by this ACE_Process_Manager.

Definition at line 644 of file Process_Manager.cpp.

References ACE_GUARD_RETURN, ACE_INVALID_PID, ACE_TRACE, find_proc(), and ACE_OS::sched_params().

00646 {
00647   ACE_TRACE ("ACE_Process_Manager::set_scheduler");
00648 
00649   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
00650                             ace_mon, this->lock_, -1));
00651 
00652   // Check to see if the process identified by the given pid is managed by
00653   // this instance of ACE_Process_Manager.
00654   ssize_t const i = this->find_proc (pid);
00655 
00656   if (i == -1)
00657     // set "no such process" error
00658     return ACE_INVALID_PID;
00659 
00660   return ACE_OS::sched_params (params, pid);
00661 }

int ACE_Process_Manager::set_scheduler_all ( const ACE_Sched_Params params  ) 

Sets the scheduling parameters for all the processes managed by this ACE_Process_Manager by passing params to ACE_OS::sched_params().

Return values:
0 on success, -1 on failure.

Definition at line 664 of file Process_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, current_count_, and ACE_OS::sched_params().

00665 {
00666   ACE_TRACE ("ACE_Process_Manager::set_scheduler_all");
00667 
00668   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
00669                             ace_mon, this->lock_, -1));
00670 
00671   for (size_t i = 0; i < this->current_count_; ++i)
00672     {
00673       pid_t const pid = this->process_table_[i].process_->getpid ();
00674       if (ACE_OS::sched_params (params, pid) != 0)
00675         return -1;
00676     }
00677   return 0;
00678 }

pid_t ACE_Process_Manager::spawn ( ACE_Process_Options options,
ACE_Event_Handler event_handler = 0 
)

Create a new process with the specified options. Register event_handler to be called back when the process exits.

On success, returns the process id of the child that was created. On failure, returns ACE_INVALID_PID.

Definition at line 421 of file Process_Manager.cpp.

References ACE_INVALID_PID, ACE_NEW_RETURN, and spawn().

00423 {
00424   ACE_Process *process = 0;
00425   ACE_NEW_RETURN (process,
00426                   ACE_Managed_Process,
00427                   ACE_INVALID_PID);
00428 
00429   pid_t const pid = spawn (process, options, event_handler);
00430   if (pid == ACE_INVALID_PID || pid == 0)
00431     delete process;
00432 
00433   return pid;
00434 }

pid_t ACE_Process_Manager::spawn ( ACE_Process proc,
ACE_Process_Options options,
ACE_Event_Handler event_handler = 0 
)

Create a new process with specified options. Register event_handler to be called back when the process exits.

On success, returns the process id of the child that was created. On failure, returns ACE_INVALID_PID.

Definition at line 439 of file Process_Manager.cpp.

References ACE_GUARD_RETURN, ACE_INVALID_PID, ACE_TRACE, and ACE_Process::spawn().

Referenced by spawn().

00442 {
00443   ACE_TRACE ("ACE_Process_Manager::spawn");
00444 
00445   pid_t const pid = process->spawn (options);
00446 
00447   // Only include the pid in the parent's table.
00448   if (pid == ACE_INVALID_PID || pid == 0)
00449     return pid;
00450 
00451   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
00452                             ace_mon, this->lock_, -1));
00453 
00454   if (this->append_proc (process, event_handler) == -1)
00455     // bad news: spawned, but not registered in table.
00456     return ACE_INVALID_PID;
00457 
00458   return pid;
00459 }

int ACE_Process_Manager::spawn_n ( size_t  n,
ACE_Process_Options options,
pid_t *  child_pids = 0,
ACE_Event_Handler event_Handler = 0 
)

Create n new processes with the same options. If child_pids is non-0 it is expected to be an array of at least n pid_t, which are filled in with the process IDs of the spawned processes. Register event_handler to be called back when each process exits. Returns 0 on success and -1 on failure.

Definition at line 464 of file Process_Manager.cpp.

References ACE_INVALID_PID, and ACE_TRACE.

00468 {
00469   ACE_TRACE ("ACE_Process_Manager::spawn_n");
00470 
00471   if (child_pids != 0)
00472     for (size_t i = 0;
00473          i < n;
00474          ++i)
00475       child_pids[i] = ACE_INVALID_PID;
00476 
00477   for (size_t i = 0;
00478        i < n;
00479        i++)
00480     {
00481       pid_t const pid = this->spawn (options, event_handler);
00482       if (pid == ACE_INVALID_PID || pid == 0)
00483         // We're in the child or something's gone wrong.
00484         return pid;
00485       else if (child_pids != 0)
00486         child_pids[i] = pid;
00487     }
00488 
00489   return 0;
00490 }

int ACE_Process_Manager::terminate ( pid_t  pid,
int  sig 
)

Sends the specified signal to the specified process.

Note:
This only works on platforms that have signal capability. In particular, it doesn't work on Windows.
Return values:
0 on success and -1 on failure.

Definition at line 625 of file Process_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, find_proc(), and ACE_OS::kill().

00626 {
00627   ACE_TRACE ("ACE_Process_Manager::terminate");
00628 
00629   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00630 
00631   // Check for duplicates and bail out if they're already
00632   // registered...
00633   ssize_t const i = this->find_proc (pid);
00634 
00635   if (i == -1)
00636     // set "no such process" error
00637     return -1;
00638 
00639   return ACE_OS::kill (pid, sig);
00640 }

int ACE_Process_Manager::terminate ( pid_t  pid  ) 

Abruptly terminate a single process with id pid using the ACE::terminate_process() method which works on both signal-capable systems and on Windows.

Note:
This call is potentially dangerous to use since the process being terminated may not have a chance to cleanup before it shuts down.
Return values:
0 on success and -1 on failure.

Definition at line 607 of file Process_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, find_proc(), and ACE::terminate_process().

00608 {
00609   ACE_TRACE ("ACE_Process_Manager::terminate");
00610 
00611   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00612 
00613   // Check for duplicates and bail out if they're already
00614   // registered...
00615   ssize_t const i = this->find_proc (pid);
00616 
00617   if (i == -1)
00618     // set "no such process" error
00619     return -1;
00620 
00621   return ACE::terminate_process (pid);
00622 }

pid_t ACE_Process_Manager::wait ( pid_t  pid,
ACE_exitcode status = 0 
)

Wait indefinitely for a single, specified process to terminate. If pid is 0, waits for any of the managed processes (but see the note concerning "sloppy process cleanup on unix"). If pid != 0, this method waits for that process only.

Return values:
The pid of the process which exited, or ACE_INVALID_PID on error.

Definition at line 755 of file Process_Manager.cpp.

References ACE_TRACE, ACE_Time_Value::max_time, and wait().

00757 {
00758   ACE_TRACE ("ACE_Process_Manager::wait");
00759 
00760   return this->wait (pid,
00761                      ACE_Time_Value::max_time,
00762                      status);
00763 }

pid_t ACE_Process_Manager::wait ( pid_t  pid,
const ACE_Time_Value timeout,
ACE_exitcode status = 0 
)

Wait up to timeout for a single specified process to terminate. If pid is 0, this method waits for any of the managed processes (but see the note concerning "sloppy process cleanup on unix"). If pid != 0, waits for that process only.

Parameters:
pid Process ID
timeout Relative time to wait for process to terminate
status Exit status of terminated process
Return values:
The pid of the process which exited, 0 if a timeout occurred, or ACE_INVALID_PID on error.

Definition at line 770 of file Process_Manager.cpp.

References ACE_ASSERT, ACE_DEBUG, ACE_ERROR_RETURN, ACE_GUARD_RETURN, ACE_INVALID_PID, ACE_NEW_RETURN, ACE_TEXT, ACE_TRACE, find_proc(), ACE_Process::getpid(), LM_DEBUG, LM_ERROR, ACE_Time_Value::max_time, ACE_Time_Value::msec(), notify_proc_handler(), ACE_Process_Manager::Process_Descriptor::process_, process_table_, ACE_Sig_Action::register_action(), remove(), remove_proc(), SIGCHLD, sigchld_nop(), ACE_OS::sleep(), ACE_Process::wait(), ACE_OS::waitpid(), WNOHANG, and ACE_Time_Value::zero.

00773 {
00774   ACE_TRACE ("ACE_Process_Manager::wait");
00775 
00776   ACE_exitcode local_stat = 0;
00777   if (status == 0)
00778     status = &local_stat;
00779 
00780   *status = 0;
00781 
00782   ssize_t idx = -1;
00783   ACE_Process *proc = 0;
00784 
00785   {
00786     // fake context after which the lock is released
00787     ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00788 
00789     if (pid != 0)
00790       {
00791         idx = this->find_proc (pid);
00792         if (idx == -1)
00793           return ACE_INVALID_PID;
00794         else
00795           proc = process_table_[idx].process_;
00796       }
00797     // release the lock.
00798   }
00799   if (proc != 0)
00800     pid = proc->wait (timeout, status);
00801   else
00802     {
00803       ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00804       // Wait for any Process spawned by this Process_Manager.
00805 #if defined (ACE_WIN32)
00806       HANDLE *handles = 0;
00807 
00808       ACE_NEW_RETURN (handles,
00809                       HANDLE[this->current_count_],
00810                       ACE_INVALID_PID);
00811 
00812       for (size_t i = 0;
00813            i < this->current_count_;
00814            ++i)
00815         handles[i] =
00816           process_table_[i].process_->gethandle ();
00817 
00818       DWORD handle_count = static_cast<DWORD> (this->current_count_);
00819       DWORD result = ::WaitForMultipleObjects (handle_count,
00820                                                handles,
00821                                                FALSE,
00822                                                timeout == ACE_Time_Value::max_time
00823                                                ? INFINITE
00824                                                : timeout.msec ());
00825       if (result == WAIT_FAILED)
00826         pid = ACE_INVALID_PID;
00827       else if (result == WAIT_TIMEOUT)
00828         pid = 0;
00829       else
00830         {
00831           // Green Hills produces a warning that result >=
00832           // WAIT_OBJECT_0 is a pointless comparison because
00833           // WAIT_OBJECT_0 is zero and DWORD is unsigned long, so this
00834           // test is skipped for Green Hills.  Same for mingw.
00835 # if defined (ghs) || defined (__MINGW32__) || (defined (_MSC_VER) && _MSC_VER >= 1300)
00836           ACE_ASSERT (result < WAIT_OBJECT_0 + this->current_count_);
00837 # else
00838           ACE_ASSERT (result >= WAIT_OBJECT_0
00839                       && result < WAIT_OBJECT_0 + this->current_count_);
00840 # endif
00841 
00842           idx = this->find_proc (handles[result - WAIT_OBJECT_0]);
00843 
00844           if (idx != -1)
00845             {
00846               pid = process_table_[idx].process_->getpid ();
00847               result = ::GetExitCodeProcess (handles[result - WAIT_OBJECT_0],
00848                                              status);
00849               if (result == 0)
00850                 {
00851                   // <GetExitCodeProcess> failed!
00852                   this->remove_proc (idx);
00853                   pid = ACE_INVALID_PID;
00854                 }
00855             }
00856           else
00857             {
00858               // uh oh...handle removed from process_table_, even though
00859               // we're holding a lock!
00860               delete [] handles;
00861               ACE_ERROR_RETURN ((LM_ERROR,
00862                                  ACE_TEXT ("Process removed")
00863                                  ACE_TEXT (" -- somebody's ignoring the lock!\n")),
00864                                 -1);
00865             }
00866         }
00867 
00868       delete [] handles;
00869 #else /* !defined(ACE_WIN32) */
00870       if (timeout == ACE_Time_Value::max_time)
00871         pid = ACE_OS::waitpid (-1, status, 0);
00872       else if (timeout == ACE_Time_Value::zero)
00873         pid = ACE_OS::waitpid (-1, status, WNOHANG);
00874       else
00875         {
00876 # if defined (ACE_LACKS_UNIX_SIGNALS)
00877           pid = 0;
00878           ACE_Time_Value sleeptm (1);    // 1 msec
00879           if (sleeptm > timeout)         // if sleeptime > waittime
00880             sleeptm = timeout;
00881           ACE_Time_Value tmo (timeout);  // Need one we can change
00882           for (ACE_Countdown_Time time_left (&tmo); tmo > ACE_Time_Value::zero ; time_left.update ())
00883             {
00884               pid = ACE_OS::waitpid (-1, status, WNOHANG);
00885               if (pid > 0 || pid == ACE_INVALID_PID)
00886                 break;          // Got a child or an error - all done
00887 
00888               // pid 0, nothing is ready yet, so wait.
00889               // Do a (very) short sleep (only this thread sleeps).
00890               ACE_OS::sleep (sleeptm);
00891             }
00892 # else
00893           // Force generation of SIGCHLD, even though we don't want to
00894           // catch it - just need it to interrupt the sleep below.
00895           // If this object has a reactor set, assume it was given at
00896           // open(), and there's already a SIGCHLD action set, so no
00897           // action is needed here.
00898           ACE_Sig_Action old_action;
00899           if (this->reactor () == 0)
00900             {
00901               ACE_Sig_Action do_sigchld ((ACE_SignalHandler)sigchld_nop);
00902               do_sigchld.register_action (SIGCHLD, &old_action);
00903             }
00904 
00905           ACE_Time_Value tmo (timeout);  // Need one we can change
00906           for (ACE_Countdown_Time time_left (&tmo); ; time_left.update ())
00907             {
00908               pid = ACE_OS::waitpid (-1, status, WNOHANG);
00909 #   if defined (ACE_VXWORKS) && (ACE_VXWORKS >= 0x600)
00910               if (pid > 0 || (pid == ACE_INVALID_PID && errno != EINTR))
00911 #   else
00912                 if (pid > 0 || pid == ACE_INVALID_PID)
00913 #   endif
00914                   break;          // Got a child or an error - all done
00915 
00916               // pid 0, nothing is ready yet, so wait.
00917               // Do a sleep (only this thread sleeps) til something
00918               // happens. This relies on SIGCHLD interrupting the sleep.
00919               // If SIGCHLD isn't delivered, we'll need to do something
00920               // with sigaction to force it.
00921               if (-1 == ACE_OS::sleep (tmo) && errno == EINTR)
00922                 continue;
00923               // Timed out
00924               pid = 0;
00925               break;
00926             }
00927 
00928           // Restore the previous SIGCHLD action if it was changed.
00929           if (this->reactor () == 0)
00930             old_action.register_action (SIGCHLD);
00931 # endif /* !ACE_LACKS_UNIX_SIGNALS */
00932         }
00933 #endif /* !defined (ACE_WIN32) */
00934     }
00935 
00936   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00937   if (pid != ACE_INVALID_PID && pid != 0)
00938     {
00939       //we always need to get our id, because we could have been moved in the table meanwhile
00940       idx = this->find_proc (pid);
00941       if (idx == -1)
00942         {
00943           // oops, reaped an unmanaged process!
00944           ACE_DEBUG ((LM_DEBUG,
00945                       ACE_TEXT ("(%P|%t) oops, reaped unmanaged %d\n"),
00946                       pid));
00947           return pid;
00948         }
00949       else
00950         proc = process_table_[idx].process_;
00951       if (proc != 0)
00952         ACE_ASSERT (pid == proc->getpid ());
00953 
00954       this->notify_proc_handler (idx,
00955                                  *status);
00956       this->remove (pid);
00957     }
00958 
00959   return pid;
00960 }

int ACE_Process_Manager::wait ( const ACE_Time_Value timeout = ACE_Time_Value::max_time  ) 

Block until there are no more child processes running that were spawned by this ACE_Process_Manager. Unlike the wait() method below, this method does not require a signal handler or use of ACE_OS::sigwait() because it simply blocks synchronously waiting for all the children managed by this ACE_Process_Manager 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.

Parameters:
timeout Relative time to wait for processes to terminate.
Return values:
0 on success; -1 on failure.

Definition at line 716 of file Process_Manager.cpp.

References ACE_INVALID_PID, ACE_TRACE, ACE_OS::gettimeofday(), ACE_Time_Value::max_time, and ACE_Time_Value::zero.

Referenced by handle_input(), reap(), and wait().

00717 {
00718   ACE_TRACE ("ACE_Process_Manager::wait");
00719 
00720   ACE_Time_Value until = timeout;
00721   ACE_Time_Value remaining = timeout;
00722 
00723   if (until < ACE_Time_Value::max_time)
00724     until += ACE_OS::gettimeofday ();
00725 
00726   while (this->current_count_ > 0)
00727     {
00728       pid_t const pid = this->wait (0, remaining);
00729 
00730       if (pid == ACE_INVALID_PID)       // wait() failed
00731         return -1;
00732       else if (pid == 0)     // timeout
00733         break;
00734 
00735       remaining = until < ACE_Time_Value::max_time
00736         ? until - ACE_OS::gettimeofday ()
00737         : ACE_Time_Value::max_time;
00738 
00739       if (remaining <= ACE_Time_Value::zero)
00740         break;
00741 
00742       // else Process terminated...wait for more...
00743     }
00744   return static_cast<int> (this->current_count_);
00745 }


Friends And Related Function Documentation

friend class ACE_Process_Control [friend]

Definition at line 101 of file Process_Manager.h.


Member Data Documentation

ACE_Process_Manager::ACE_ALLOC_HOOK_DECLARE

Declare the dynamic allocation hooks.

Definition at line 336 of file Process_Manager.h.

size_t ACE_Process_Manager::current_count_ [private]

Current number of processes we are managing.

Definition at line 451 of file Process_Manager.h.

Referenced by append_proc(), close(), dump(), find_proc(), managed(), remove_proc(), resize(), and set_scheduler_all().

ACE_Event_Handler* ACE_Process_Manager::default_exit_handler_ [private]

This event handler is used to notify when a process we control exits.

Definition at line 455 of file Process_Manager.h.

Referenced by close(), notify_proc_handler(), and register_handler().

bool ACE_Process_Manager::delete_instance_ = false [static, private]

Controls whether the <Process_Manager> is deleted when we shut down (we can only delete it safely if we created it!)

Definition at line 462 of file Process_Manager.h.

Referenced by close_singleton(), and instance().

ACE_Process_Manager * ACE_Process_Manager::instance_ = 0 [static, private]

Singleton pointer.

Definition at line 458 of file Process_Manager.h.

Referenced by close_singleton(), and instance().

size_t ACE_Process_Manager::max_process_table_size_ [private]

Maximum number of processes we can manage (should be dynamically allocated).

Definition at line 448 of file Process_Manager.h.

Referenced by append_proc(), close(), and resize().

Process_Descriptor* ACE_Process_Manager::process_table_ [private]

Vector that describes process state within the Process_Manager.

Definition at line 444 of file Process_Manager.h.

Referenced by append_proc(), close(), handle_signal(), notify_proc_handler(), register_handler(), remove_proc(), and wait().


The documentation for this class was generated from the following files:
Generated on Tue Feb 2 17:35:27 2010 for ACE by  doxygen 1.4.7