ACE  6.1.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Classes | Public Types | Protected Member Functions | Private Member Functions | Private Attributes | Static Private Attributes | Friends | List of all members
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]

Classes

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

Public Types

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)
 

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_signal (int signum, siginfo_t *=0, ucontext_t *=0)
 
- Protected Member Functions inherited from ACE_Event_Handler
virtual ~ACE_Event_Handler (void)
 Destructor is virtual to enable proper cleanup.
 
virtual ACE_HANDLE get_handle (void) const
 Get the I/O handle.
 
virtual void set_handle (ACE_HANDLE)
 Set the I/O handle.
 
virtual int priority (void) const
 
virtual void priority (int priority)
 Set the priority of the Event_Handler.
 
virtual int handle_input (ACE_HANDLE fd=ACE_INVALID_HANDLE)
 Called when input events occur (e.g., connection or data).
 
virtual int handle_output (ACE_HANDLE fd=ACE_INVALID_HANDLE)
 
virtual int handle_exception (ACE_HANDLE fd=ACE_INVALID_HANDLE)
 Called when an exceptional events occur (e.g., SIGURG).
 
virtual int handle_timeout (const ACE_Time_Value &current_time, const void *act=0)
 
virtual int handle_exit (ACE_Process *)
 Called when a process exits.
 
virtual int handle_close (ACE_HANDLE handle, ACE_Reactor_Mask close_mask)
 
virtual int resume_handler (void)
 
virtual int handle_qos (ACE_HANDLE=ACE_INVALID_HANDLE)
 
virtual int handle_group_qos (ACE_HANDLE=ACE_INVALID_HANDLE)
 
virtual void reactor (ACE_Reactor *reactor)
 Set the event demultiplexors.
 
virtual ACE_Reactorreactor (void) const
 Get the event demultiplexors.
 
virtual
ACE_Reactor_Timer_Interface
reactor_timer_interface (void) const
 Get only the reactor's timer related interface.
 
virtual Reference_Count add_reference (void)
 Increment reference count on the handler.
 
virtual Reference_Count remove_reference (void)
 Decrement reference count on the handler.
 
Reference_Counting_Policyreference_counting_policy (void)
 Current Reference_Counting_Policy.
 
 ACE_Event_Handler (ACE_Reactor *=0, int priority=ACE_Event_Handler::LO_PRIORITY)
 Force ACE_Event_Handler to be an abstract base class.
 

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

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 process_table_.
 

Static Private Attributes

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

Friends

class ACE_Process_Control
 

Utility methods

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks.
 
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.
 

Additional Inherited Members

- Protected Types inherited from ACE_Event_Handler
enum  {
  LO_PRIORITY = 0, HI_PRIORITY = 10, NULL_MASK = 0, READ_MASK = (1 << 0),
  WRITE_MASK = (1 << 1), EXCEPT_MASK = (1 << 2), ACCEPT_MASK = (1 << 3), CONNECT_MASK = (1 << 4),
  TIMER_MASK = (1 << 5), QOS_MASK = (1 << 6), GROUP_QOS_MASK = (1 << 7), SIGNAL_MASK = (1 << 8),
  ALL_EVENTS_MASK, RWE_MASK, DONT_CALL = (1 << 9)
}
 
enum  { ACE_EVENT_HANDLER_NOT_RESUMED = -1, ACE_REACTOR_RESUMES_HANDLER = 0, ACE_APPLICATION_RESUMES_HANDLER }
 
typedef long Reference_Count
 Reference count type.
 
typedef ACE_Atomic_Op
< ACE_SYNCH_MUTEX,
Reference_Count
Atomic_Reference_Count
 Typedef for implementation of reference counting.
 
- Static Protected Member Functions inherited from ACE_Event_Handler
static ACE_THR_FUNC_RETURN read_adapter (void *event_handler)
 
static int register_stdin_handler (ACE_Event_Handler *eh, ACE_Reactor *reactor, ACE_Thread_Manager *thr_mgr, int flags=THR_DETACHED)
 
static int remove_stdin_handler (ACE_Reactor *reactor, ACE_Thread_Manager *thr_mgr)
 Performs the inverse of the register_stdin_handler() method.
 

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:

// ...

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.

Member Enumeration Documentation

anonymous enum
Enumerator:
DEFAULT_SIZE 

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.

ACE_Process_Manager::~ACE_Process_Manager ( void  )
virtual

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

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.

void ACE_Process_Manager::cleanup ( void *  instance,
void *  arg 
)
static

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

int ACE_Process_Manager::close ( void  )

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

void ACE_Process_Manager::close_singleton ( void  )
static

Delete the dynamically allocated singleton.

void ACE_Process_Manager::dump ( void  ) const

Dump the state of an object.

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_

ssize_t ACE_Process_Manager::find_proc ( ACE_HANDLE  process_handle)
private

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

int ACE_Process_Manager::handle_signal ( int  signum,
siginfo_t si = 0,
ucontext_t = 0 
)
protectedvirtual

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.

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.

ACE_Process_Manager * ACE_Process_Manager::instance ( void  )
static

Get pointer to a process-wide ACE_Process_Manager.

ACE_Process_Manager * ACE_Process_Manager::instance ( ACE_Process_Manager tm)
static

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

size_t ACE_Process_Manager::managed ( void  ) const
inline

Return the number of managed processes.

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.

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.

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.
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 wait() method if the waited process exits. This method can also be called after calling terminate() if there's no need to wait() for the terminated process.

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.

int ACE_Process_Manager::resize ( size_t  size)
private

Resize the pool of Process_Descriptors.

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
0on success, -1 on failure, and ACE_INVALID_PID when the specified pid is not managed by this ACE_Process_Manager.
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
0on success, -1 on failure.
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.

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.

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.

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. The process's entry is also not removed from this class's process table. Calling either wait() or remove() after terminate() is advisable.
Return values
0on success and -1 on failure.
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
0on success and -1 on failure.
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
timeoutRelative time to wait for processes to terminate.
Return values
0on success; -1 on failure.
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
pidProcess ID
timeoutRelative time to wait for process to terminate
statusExit status of terminated process
Return values
Thepid of the process which exited, 0 if a timeout occurred, or ACE_INVALID_PID on error.
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
Thepid of the process which exited, or ACE_INVALID_PID on error.

Friends And Related Function Documentation

friend class ACE_Process_Control
friend

Member Data Documentation

ACE_Process_Manager::ACE_ALLOC_HOOK_DECLARE

Declare the dynamic allocation hooks.

size_t ACE_Process_Manager::current_count_
private

Current number of processes we are managing.

ACE_Event_Handler* ACE_Process_Manager::default_exit_handler_
private

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

bool ACE_Process_Manager::delete_instance_ = false
staticprivate

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

ACE_Process_Manager * ACE_Process_Manager::instance_ = 0
staticprivate

Singleton pointer.

ACE_Recursive_Thread_Mutex ACE_Process_Manager::lock_
private

This lock protects access/ops on process_table_.

size_t ACE_Process_Manager::max_process_table_size_
private

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

Process_Descriptor* ACE_Process_Manager::process_table_
private

Vector that describes process state within the Process_Manager.


The documentation for this class was generated from the following files: