DML_child Class

Declared:

#include <DML_child.h>    

Derived From:

DML_process

Description

The DML_child class is a class useful for creating subordinate "child" processes. Using these processes, a programmer can split off modular parts of a process, and they will execute simultaneously, according to scheduling and priority. With this method, for instance, a hardware driver, user interface, and number-crunching program can be split into three distinct entities, communicating through various channels.

The DML_child uses the DML_process class as a public base class and so therefore has all the convenience funtions of that class immediately available. A DML_child instance can be created as a "blank" child (which will not spawn a new process), or as a child which spawns a process, given by a filename.

The DML_child class is a companion to the DML_master class. With the use of these two classes, the parent and child classes can coordinate set-up and initialization.

Public Class Members

Public member data:

pid_t proxy
char * name  

Public member functions:

DML_child()
DML_child( const char * )
DML_child( const char *, int )
DML_child( const char *, const char * [ ], int, int )
~DML_child()
setArgs( const char *argv[ ] )
open( const char * )
sendInfoMsg()
int beQuiet()
int beLoud()
attachProxy()
int kick()
DML_child & print()
static printChildren()
static killChildren()  

See Also:

DML_process, DML_master

 

Class Member Functions

 

DML_child::DML_child()

Synopsis:

#include <DML_child.h>


DML_child()
DML_child( const char * )
DML_child( const char *, int )
DML_child( const char *, const char * [ ], int waitResponse, int Verbosity )

Semantics:

There are four forms of this constructor: The first creates a blank DML_child object, without spawning off a process. The process can be spawned later using the open() command.

The second creates a DML_child object and spawns off the file named in the argument. If the file doesn't exist, the object is still created, but most of the other functions will subsequently fail when called.

The third is identical to the second, but if the 2nd argument is passed WAIT_RESPONSE it spawns the child then immediately calls the sendInfoMsg() function.

The fourth allows the user to pass command-line arguments to the child process, and in addition specify a default verbosity for the child. The verbosity is used internally to control the display of printf() messages, and is passed to the child to be used at its discretion.

Code Dissection:

All four forms of this function perform almost the same identical actions. First, the new DML_child object is appended onto the end of the linked list of children. I typically use the same very simple linked-list formulation for many of these classes. Second, the data members are initialized to appropriate "null" values. Third, the arguments to the new child are set and it is actually spawned off. Last, a proxy is attached to the process, if it exists, and it may be sent the infoMsgStruct. The code is self-explanatory.

Results:

A child process is spawned off, and a proxy is attached to the child. The child may or may not be passed additional command-line arguments, or sent the sendInfoMsg() message sequence.

See Also:

~DML_child, DML_child::sendInfoMsg

 

DML_child::~DML_child

Synopsis:

#include <DML_child.h>

~DML_child()

Semantics:

This function simply cleans up after the mess created by the constructor. It terminates the child process as well, so be certain to understand that when any DML_child object goes out of scope, the corresponding child process is terminated. This may not be the desired action: in such cases, use the new operator or declare the object to be static.

Code Dissection:

This function is trivial: it kills the process and removes it from the linked list. If it happens to be the head of the list, it re-assigns the head to the next on the list.

Results:

The subordinate process is terminated.

See Also:

DML_child

 

DML_child::setArgs()

Synopsis:

#include <DML_child.h>

setArgs( const char * argv[ ] )

Semantics:

Typically, one can just pass in the external global variable "_argv" to this function to pass on the arguments of the parent process. Instead, one can construct an argument, which is an array of const char * pointers or char * pointers, detailing the specific arguments of the child process. The first item on the list should always be the name of the executable file which is to be spawned, and this function does NOT do this, nor does it allocate internal storage for this pointer. Make sure, then, that this function is called ONLY just before using the open() command, and that the first argument is changed correctly.

Code Dissection:

Clearly from the code, this function simply re-assigns a pointer. It's kind of dangerous, and should probably be re-written to allocate some internal storage for the arguments, but it never got done that way.

Results:

The arguments are stored, as long as the original array is not modified. They will then be passed on to the child when the open() command is called.

See Also:

DML_child::open, DML_child

 

 

DML_child::open()

Synopsis:

#include <DML_child.h>

open( const char *name )

Semantics:

This function actually spawns off the executable file listed by the argument.

Code Dissection:

The function uses the "spawnvp" function, which takes a vector of command-line arguments and passes them to the child. It checks to see if custom arguments have been specified for the child: if not, it generates an appropriate list of no arguments: the first argument, however, is always the executable file name. In addition, the function copies the name over into the internal storage, truncating it if necessary.

Note that a more advanced implementation might allow the use of the spawnve function, which passes on environment variables, but that functionality is currently not built into the DML_child class.

Results:

The file name specified in the argument is spawned. If that file doesnt' exist, no executable is spawned and most other member functions will likely fail (though not catastrophically).

See Also:

DML_child, spawn functions

 

 

DML_child::sendInfoMsg

Synopsis:

#include <header>

sendInfoMsg()

Semantics:

The Info Message is a tool for synchronizing child and master processes. A master process, which has created a DML_child object and spawned off a child process, can call this function, which effectively waits until the child completes its initialization and responds (manually). Considerable inter-operability is required to use this function, since the programmer must be able to insert function calls into BOTH the parent and child processes. Using this function on a child object which has been previously compiled and doesn't know about the DML_child class will always result in unexpected behaviors (usually the parent who calls this function will hang).

The sendInfoMsg function sends a specific structure to the child object. Information concerning the proxy attached to the child, the child's priority, and the desired child verbosity are transferred. Consequently, this function must be called if the child process needs to know the proxy ID which has been attached to it.

Code Dissection:

A simple message is sent, containing the verbosity and the proxy ID attached to the child. When the message is received, it contains the priority of the child process.

Results:

Communication is established between the processes: the child gets the desired verbosity and the proxy ID attached to it, and the master gets the child's priority.

See Also:

DML_master::sendInfoMsg

 

DML_child::beQuiet() and DML_child::beLoud()

Synopsis:

#include <DML_child.h>


int DML_child::beQuiet()
int DML_child::beLoud()

Semantics:

These functions turn the verbosity flag on and off. This flag is used internally to control the display of printf messages for diagnostic purposes. use beLoud() if you want these messages to be printed to the terminal.

Code Dissection:

Just turns the verbosity flag on and off.

Results:

Returns the previous verbosity state (QUIET or LOUD).

See Also:

 

 

DML_child::attachProxy()

Synopsis:

#include <DML_child.h>


DML_child::attachProxy()

Semantics:

This function attaches a proxy to the child process. This data is stored in the class data area.

Code Dissection:

This function just calls qnx_proxy_attach. See that function's description for details.

Results:

The proxy PID is stored in the class data.

See Also:

DML_child::kick()

 

DML_child::kick

Synopsis:

#include <DML_child.h>

DML_child::kick()

Semantics:

This function triggers the proxy attached to the child. It can be used as a convenient way to control the flow of the child process program.

Code Dissection:

This is just a cover function for the Trigger QNX function.

Results:

The proxy is triggered. What happens next depends on whether or not the child process is listening for the proxy message.

See Also:

Trigger, qnx_proxy_attach, DML_child::attachProxy

 

DML_child::print

Synopsis:

#include <DML_child.h>


DML_child & DML_child::print()

Semantics:

This function prints some information about the child process, including the executable file name, the pid, the proxy pid, etc.

Code Dissection:

This just uses printf functions. A better implementation would be to use the ostream class... more versatile.

Results:

Returns a reference to the current object.

See Also:

DML_child::printChildren()

 

DML_child::printChildren

Synopsis:

#include <DML_child.h>


static DML_child::printChildren()

Semantics:

This prints ALL the child processes which were created by the current process. The list of child processes is maintained as an internal linked list.

Code Dissection:

This function is able to cycle through all the process's children because of the internal linked list. Because it's quick-n-dirty, it might not work correctly if child processes are created and destroyed multiple times. Since it's a static function, it can be called without an object, i.e. in a signal handler.

Results:

Just prints info to the screen.

See Also:

DML_child::print()

 

DML_child::killChildren

Synopsis:

#include <DML_child.h>


static DML_child::killChildren()

Semantics:

This static function is like printChildren, except that it kills all the child processes instead of printing info on them.

Code Dissection:

Note that this function uses the DML_process::kill() function rather than the global kill() function. They're identical, but the syntax is different.

Results:

All child processes will be terminated, unless they've set the Immortal bit in QNX_pflags.

See Also:

DML_child::printChildren, DML_process::kill