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.

Public Types

enum  { DEFAULT_SIZE = 100 }

Public Member Functions

 ACE_Process_Manager (size_t size=ACE_Process_Manager::DEFAULT_SIZE, ACE_Reactor *reactor=0)
int open (size_t size=DEFAULT_SIZE, ACE_Reactor *r=0)
int close (void)
 Release all resources. Do not wait for processes to exit.

virtual ~ACE_Process_Manager (void)
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)
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)
int register_handler (ACE_Event_Handler *event_handler, pid_t pid=ACE_INVALID_PID)
int remove (pid_t pid)
int terminate (pid_t pid)
int terminate (pid_t pid, int sig)
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 &)
void dump (void) const
 Dump the state of an object.


Static Public Member Functions

ACE_Process_Managerinstance (void)
 Get pointer to a process-wide .

ACE_Process_Managerinstance (ACE_Process_Manager *)
void close_singleton (void)
 Delete the dynamically allocated singleton.

void cleanup (void *instance, void *arg)

Public Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks.


Protected Member Functions

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)
ssize_t find_proc (ACE_HANDLE process_handle)
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

ACE_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_
ACE_Recursive_Thread_Mutex lock_
 This lock protects access/ops on .


Static Private Attributes

ACE_Process_Managerinstance_ = 0
 Singleton pointer.

int delete_instance_ = 0

Friends

class ACE_Process_Control

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 es. If you just want es to go away when they're finished, simply register the with an <ACE_Reactor>: ACE_Process_Manager mgr( 100, some_reactor ) -or- ACE_Process_Manager mgr; ... mgr.open( 100, some_reactor ); Then, the will clean up after any 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 cleanup code, then *don't* register the with a Reactor, and be sure to call one of the <Process_Manager::wait> functions whenever there might be managed es that have exited. Note that in either case, allows you to register "<Event_Handlers>" to be called when a specific exits, or when any without a specific exits. When a exits, the appropriate 's is called; the ACE_HANDLE passed is either the Process' HANDLE (on Win32), or its pid cast to an ACE_HANDLE (on unix). It is also possible to call the <Process_Manager::wait> functions even though the is registered with a . 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 whose you invoked. It's best to only use a single , and to create all subprocesses by calling that 's method. Incidentally, when you register your with a its notification pipe is used to help "reap" the available exit statuses. Therefore, you must not use a whose notify pipe has been disabled. Here's the sequence of steps used to reap the exit statuses in this case: + The registers a signal handler for SIGCHLD. + The SIGCHLD handler, when invoked, uses the 's method to inform the to wake up. + Next, the calls the 's , this happens synchronously, not in sighandler-space. + The method collects all available exit statuses.

Definition at line 124 of file Process_Manager.h.


Member Enumeration Documentation

anonymous enum
 

Enumeration values:
DEFAULT_SIZE 

Definition at line 129 of file Process_Manager.h.

00130   {
00131     DEFAULT_SIZE = 100
00132   };


Constructor & Destructor Documentation

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

Initialize an with a table containing up to processes. This table resizes itself automatically as needed. If a non-NULL is provided, this 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 246 of file Process_Manager.cpp.

References ACE_ERROR, ACE_LIB_TEXT, ACE_TRACE, LM_ERROR, and open().

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

ACE_Process_Manager::~ACE_Process_Manager void   )  [virtual]
 

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

Definition at line 301 of file Process_Manager.cpp.

References ACE_TRACE, and close().

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


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 in the . Each entry is added at the end, growing the table if necessary. Register to be called back when the process exits.

Definition at line 497 of file Process_Manager.cpp.

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

Referenced by insert_proc(), and spawn().

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

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

Cleanup method, used by the 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 269 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().

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

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_ = 0;
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_LIB_TEXT, ACE_TRACE, current_count_, ACE_Process_Descriptor::dump(), LM_DEBUG, and process_table_.

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_LIB_TEXT ("\nmax_process_table_size_ = %d"), this->max_process_table_size_));
00092   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_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 ACE_HANDLE  process_handle  )  [private]
 

Locate the index of the table slot occupied by . Returns ~0 if is not in the

Definition at line 715 of file Process_Manager.cpp.

References ACE_TRACE, current_count_, ACE_Process::gethandle(), ACE_Process_Descriptor::process_, and process_table_.

00716 {
00717   ACE_TRACE ("ACE_Process_Manager::find_proc");
00718 
00719   for (size_t i = 0; i < this->current_count_; ++i)
00720     if (h == this->process_table_[i].process_->gethandle ())
00721       return i;
00722 
00723   return -1;
00724 }

ssize_t ACE_Process_Manager::find_proc pid_t  process_id  )  [private]
 

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

Definition at line 699 of file Process_Manager.cpp.

References ACE_TRACE, current_count_, ACE_Process::getpid(), pid_t, ACE_Process_Descriptor::process_, and process_table_.

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

00700 {
00701   ACE_TRACE ("ACE_Process_Manager::find_proc");
00702 
00703   for (size_t i = 0; i < this->current_count_; ++i)
00704     if (pid == this->process_table_[i].process_->getpid ())
00705       return i;
00706 
00707   return -1;
00708 }

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 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 341 of file Process_Manager.cpp.

References ACE_ERROR_RETURN, ACE_exitcode, ACE_GUARD_RETURN, ACE_INVALID_PID, ACE_LIB_TEXT, find_proc(), ACE_Process::getpid(), LM_ERROR, ACE_Reactor::notify(), notify_proc_handler(), pid_t, ACE_Process_Descriptor::process_, process_table_, ACE_Event_Handler::reactor(), remove_proc(), siginfo_t::si_handle_, ssize_t, and ucontext_t.

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

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

Definition at line 537 of file Process_Manager.cpp.

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

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

ACE_Process_Manager * ACE_Process_Manager::instance ACE_Process_Manager  )  [static]
 

Set pointer to a process-wide 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_ = 0;
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 .

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_ = 1;
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 in the table, or there's a default handler, call it.

Definition at line 1001 of file Process_Manager.cpp.

References ACE_DEBUG, ACE_exitcode, ACE_LIB_TEXT, current_count_, default_exit_handler_, ACE_Process::exit_code(), ACE_Process_Descriptor::exit_notify_, ACE_Event_Handler::handle_close(), ACE_Event_Handler::handle_exit(), LM_DEBUG, ACE_Process_Descriptor::process_, and process_table_.

Referenced by handle_signal(), and wait().

01003 {
01004   if (i < this->current_count_)
01005     {
01006       ACE_Process_Descriptor &proc_desc =
01007         this->process_table_[i];
01008 
01009       proc_desc.process_->exit_code (exit_code);
01010 
01011       if (proc_desc.exit_notify_ != 0)
01012         proc_desc.exit_notify_->handle_exit (proc_desc.process_);
01013       else if (this->default_exit_handler_ != 0
01014                && this->default_exit_handler_->handle_exit (proc_desc.process_) < 0)
01015         {
01016           this->default_exit_handler_->handle_close
01017             (ACE_INVALID_HANDLE,
01018              0);
01019           this->default_exit_handler_ = 0;
01020         }
01021       return 1;
01022     }
01023   else
01024     {
01025       ACE_DEBUG ((LM_DEBUG,
01026                   ACE_LIB_TEXT ("(%P:%t|%T) ACE_Process_Manager::notify_proc_handler:")
01027                   ACE_LIB_TEXT (" unknown/unmanaged process reaped\n")));
01028       return 0;
01029     }
01030 }

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

Initialize an with a table containing up to processes. This table resizes itself automatically as needed. If a non-NULL is provided, this 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, max_process_table_size_, ACE_Event_Handler::reactor(), ACE_Reactor::register_handler(), resize(), and SIGCHLD.

Referenced by ACE_Process_Manager().

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

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 Win32. If the child is successfully reaped, is called automatically. This method does the same thing that the method directly above it does -- It's just here for backwards compatibility.

Definition at line 983 of file Process_Manager.cpp.

References ACE_BIT_ENABLED, ACE_exitcode, ACE_TRACE, pid_t, wait(), and WNOHANG.

00986 {
00987   ACE_TRACE ("ACE_Process_Manager::reap");
00988 
00989   return this->wait (pid,
00990                      (ACE_BIT_ENABLED (options, WNOHANG)
00991                       ? ACE_Time_Value::zero
00992                       : ACE_Time_Value::max_time),
00993                      stat_loc);
00994 }

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.

Note:
In multi-threaded 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 390 of file Process_Manager.cpp.

References ACE_GUARD_RETURN, ACE_INVALID_PID, default_exit_handler_, ACE_Process_Descriptor::exit_notify_, find_proc(), ACE_Event_Handler::handle_close(), pid_t, process_table_, and ssize_t.

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

int ACE_Process_Manager::remove pid_t  pid  ) 
 

Remove process from the table. This is called automatically by the method after it successfully reaped a signal. It's also possible to call this method directly from a signal handler, but don't call both and !

Definition at line 553 of file Process_Manager.cpp.

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

Referenced by wait().

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

int ACE_Process_Manager::remove_proc size_t  n  )  [private]
 

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

Definition at line 571 of file Process_Manager.cpp.

References ACE_TRACE, current_count_, ACE_Process_Descriptor::exit_notify_, ACE_Process::gethandle(), ACE_Event_Handler::handle_close(), ACE_Process_Descriptor::process_, process_table_, ACE_Event_Handler::reactor(), ACE_Reactor::remove_handler(), and ACE_Process::unmanage().

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

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

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_, max_process_table_size_, and process_table_.

Referenced by append_proc(), and open().

00193 {
00194   ACE_TRACE ("ACE_Process_Manager::resize");
00195 
00196   if (size <= this->max_process_table_size_)
00197     return 0;
00198 
00199   ACE_Process_Descriptor *temp = 0;
00200 
00201   ACE_NEW_RETURN (temp,
00202                   ACE_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 the managed by identified by pid by passing , to <ACE_OS::sched_params>. Returns 0 on success, -1 on failure, and ACE_INVALID_PID when given pid is not managed by .

Definition at line 657 of file Process_Manager.cpp.

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

00659 {
00660   ACE_TRACE ("ACE_Process_Manager::set_scheduler");
00661 
00662   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
00663                             ace_mon, this->lock_, -1));
00664 
00665   // Check to see if the process identified by the given pid is managed by
00666   // this instance of ACE_Process_Manager.
00667   ssize_t const i = this->find_proc (pid);
00668 
00669   if (i == -1)
00670     // set "no such process" error
00671     return ACE_INVALID_PID;
00672 
00673   return ACE_OS::sched_params (params, pid);
00674 }

int ACE_Process_Manager::set_scheduler_all const ACE_Sched_Params  ) 
 

Sets the scheduling parameters for all the es managed by by passing to <ACE_OS::sched_params>. Returns 0 on success, -1 on failure.

Definition at line 677 of file Process_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, current_count_, ACE_Process::getpid(), pid_t, ACE_Process_Descriptor::process_, process_table_, and ACE_OS::sched_params().

00678 {
00679   ACE_TRACE ("ACE_Process_Manager::set_scheduler_all");
00680 
00681   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
00682                             ace_mon, this->lock_, -1));
00683 
00684   for (size_t i = 0; i < this->current_count_; ++i)
00685     {
00686       pid_t const pid = this->process_table_[i].process_->getpid ();
00687       if (ACE_OS::sched_params (params, pid) != 0)
00688         return -1;
00689     }
00690   return 0;
00691 
00692 }

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

Create a new process by passing to <ACE_Process::spawn>. Register 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 422 of file Process_Manager.cpp.

References ACE_INVALID_PID, ACE_NEW_RETURN, pid_t, and spawn().

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

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

Create a new process by passing to <proc.spawn>. Register 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 440 of file Process_Manager.cpp.

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

Referenced by spawn(), and spawn_n().

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

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 new processes by passing to <ACE_Process::spawn>, which is called times. If is non-0 it is expected to be an array of 's, which are filled in with the process ids of each newly created process. Register to be called back when each process exits. Returns 0 on success and -1 on failure.

Definition at line 465 of file Process_Manager.cpp.

References ACE_INVALID_PID, ACE_TRACE, pid_t, and spawn().

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

int ACE_Process_Manager::terminate pid_t  pid,
int  sig
 

On OSs that support signals, send the signal to the specified process. Returns 0 on success and -1 on failure.

Definition at line 637 of file Process_Manager.cpp.

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

00639 {
00640   ACE_TRACE ("ACE_Process_Manager::terminate");
00641 
00642   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00643 
00644   // Check for duplicates and bail out if they're already
00645   // registered...
00646   ssize_t const i = this->find_proc (pid);
00647 
00648   if (i == -1)
00649     // set "no such process" error
00650     return -1;
00651 
00652   return ACE_OS::kill (pid, sig);
00653 }

int ACE_Process_Manager::terminate pid_t  pid  ) 
 

Abruptly terminate a single process with id using the <ACE::terminate_process> 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.

Definition at line 609 of file Process_Manager.cpp.

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

00610 {
00611   ACE_TRACE ("ACE_Process_Manager::terminate");
00612 
00613   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00614 
00615   // Check for duplicates and bail out if they're already
00616   // registered...
00617   ssize_t const i = this->find_proc (pid);
00618 
00619   if (i == -1)
00620     // set "no such process" error
00621     return -1;
00622 
00623   int const result = ACE::terminate_process (pid);
00624 
00625   if (result != -1)
00626     {
00627       // Save/restore errno.
00628       ACE_Errno_Guard error (errno);
00629       this->remove_proc (i);
00630       return 0;
00631     }
00632 
00633   return -1;
00634 }

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

Wait indefinitely for a single process to terminate. If pid==0, waits for any of the managed es (but see the note in the class documentation for caveats about this -- "sloppy Process cleanup on unix") If pid != 0, waits for that only. Returns the pid of the process whose exit was handled, or ACE_INVALID_PID on error.

Definition at line 770 of file Process_Manager.cpp.

References ACE_exitcode, ACE_TRACE, pid_t, and wait().

00772 {
00773   ACE_TRACE ("ACE_Process_Manager::wait");
00774 
00775   return this->wait (pid,
00776                      ACE_Time_Value::max_time,
00777                      status);
00778 }

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

Wait up to for a single process to terminate. If pid==0, waits for any of the managed 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 only. Returns the pid of the Process whose exit was handled, 0 if a timeout occurred, or ACE_INVALID_PID on error.

Definition at line 785 of file Process_Manager.cpp.

References ACE_ASSERT, ACE_DEBUG, ACE_ERROR_RETURN, ACE_exitcode, ACE_GUARD_RETURN, ACE_INVALID_PID, ACE_LIB_TEXT, ACE_NEW_RETURN, ACE_SignalHandler, ACE_TRACE, current_count_, find_proc(), ACE_Process::gethandle(), ACE_Process::getpid(), LM_DEBUG, LM_ERROR, ACE_Time_Value::msec(), notify_proc_handler(), pid_t, ACE_Process_Descriptor::process_, process_table_, ACE_Event_Handler::reactor(), ACE_Sig_Action::register_action(), remove(), remove_proc(), SIGCHLD, ACE_OS::sleep(), ssize_t, ACE_Countdown_Time::update(), ACE_Process::wait(), ACE_OS::waitpid(), and WNOHANG.

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

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 ed by this . Unlike the call below, this method does not require a signal handler or <ACE_OS::sigwait> 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 s the corresponding entries from the ; otherwise, returns -1 on failure.

Definition at line 731 of file Process_Manager.cpp.

References ACE_INVALID_PID, ACE_TRACE, current_count_, ACE_OS::gettimeofday(), and pid_t.

Referenced by reap(), and wait().

00732 {
00733   ACE_TRACE ("ACE_Process_Manager::wait");
00734 
00735   ACE_Time_Value until = timeout;
00736   ACE_Time_Value remaining = timeout;
00737 
00738   if (until < ACE_Time_Value::max_time)
00739     until += ACE_OS::gettimeofday ();
00740 
00741   while (this->current_count_ > 0)
00742     {
00743       pid_t const pid = this->wait (0, remaining);
00744 
00745       if (pid == ACE_INVALID_PID)       // wait() failed
00746         return -1;
00747       else if (pid == 0)     // timeout
00748         break;
00749 
00750       remaining = until < ACE_Time_Value::max_time
00751         ? until - ACE_OS::gettimeofday ()
00752         : ACE_Time_Value::max_time;
00753 
00754       if (remaining <= ACE_Time_Value::zero)
00755         break;
00756 
00757       // else Process terminated...wait for more...
00758     }
00759   return static_cast<int> (this->current_count_);
00760 }


Friends And Related Function Documentation

friend class ACE_Process_Control [friend]
 

Definition at line 127 of file Process_Manager.h.


Member Data Documentation

ACE_Process_Manager::ACE_ALLOC_HOOK_DECLARE
 

Declare the dynamic allocation hooks.

Definition at line 326 of file Process_Manager.h.

size_t ACE_Process_Manager::current_count_ [private]
 

Current number of processes we are managing.

Definition at line 416 of file Process_Manager.h.

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

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 420 of file Process_Manager.h.

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

int ACE_Process_Manager::delete_instance_ = 0 [static, private]
 

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

Definition at line 62 of file Process_Manager.cpp.

Referenced by close_singleton(), and instance().

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

Singleton pointer.

Definition at line 58 of file Process_Manager.cpp.

Referenced by close_singleton(), and instance().

ACE_Recursive_Thread_Mutex ACE_Process_Manager::lock_ [private]
 

This lock protects access/ops on .

Definition at line 431 of file Process_Manager.h.

size_t ACE_Process_Manager::max_process_table_size_ [private]
 

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

Definition at line 413 of file Process_Manager.h.

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

ACE_Process_Descriptor* ACE_Process_Manager::process_table_ [private]
 

Vector that describes process state within the Process_Manager.

Definition at line 409 of file Process_Manager.h.

Referenced by append_proc(), close(), dump(), find_proc(), handle_signal(), notify_proc_handler(), register_handler(), remove_proc(), resize(), set_scheduler_all(), and wait().


The documentation for this class was generated from the following files:
Generated on Thu Nov 9 11:27:22 2006 for ACE by doxygen 1.3.6