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