NAME
Oorb::Task - base class for Task classes in the oorb library
SYNOPSIS
-loorb $(ORBLIBS)
#include "oorb.h"
namespace Oorb
class Task
DESCRIPTION
The
Oorb(3) Task class is an abstract base class, which can be sub-classed to
represent specific tasks run by programs based on the
Oorb(3) library. Each
Task is
intended to be run in a separate thread.
Instances of the
Task class do not exist in isolation. They are launched by an instance of
Oorb::Master(3), and expect access to that instance via an external variable
Om declared
as
extern std::shared_ptr<Oorb::Master> Om;
by
oorb.h and which should be instantiated by the enclosing program. See
Oorb::Master(3)
for further details.
Each
Task has a member
std::mutex called
m_taskMutex which may be used
for data-protection operations internal to the sub-class.
CONSTRUCTORS
-
Task( std::string taskName )
The Task constructor takes the single argument of a string taskName, which uniquely
identifies the task in the enclosing program. The taskName is used to lookup the task in
the management structures of Oorb::Master(3), and to tag log messages emitted by the
Oorb::LogMgrTask(3) for the program.
METHODS
public methods
-
virtual void run( void ) = 0;
The run method must be instantiated in any Task subclass to do the work of that task.
At its most basic, the run method should call the methods documented below of init_run()
at outset, announceTaskReady() when ready to do the work of the thread, and
finalize_run() when done with all processing. In addition, a well-behaved Task should
check its command queue to see if it has been asked to shut down. A barebones implementation would
look like this:
void SubclassTask::run( void )
{
bool spinning;
this->init_run();
// Complete any task setup steps
this->announceTaskReady();
while( ! this->m_stopTask ) {
spinning = true;
// Complete any task processing / action steps
// Set spinning=false if non-negligible processor cycles might have elapsed
if( this->processCommands() > 0 ) {
spinning = false;
}
this->spinSleep( spinning );
}
this->finalize_run();
return;
}
The four methods awaitTaskReady(), pushCommand(), requestTaskStop(), stopping(), awaitTaskStopped() are
used external to the Task by other elements of the enclosing program.
-
void awaitTaskReady( void );
This method waits until the Task is ready to begin normal processing (i.e. has completed all setup steps).
-
void pushCommand( Command* command );
This method is used send commands to the Task. The format of the Command structure is
documented in OorbBasics(3).
-
void requestTaskStop( void );
This method requests that the Task shut down.
-
bool stopping( void );
The stopping() method reports whether a Task is in the midst of shutting down (to be precise,
stopping() returns the setting of the protected m_stopTask member variable).
-
void awaitTaskStopped( double limit_sec );
The awaitTaskStopped() method reports when a Task is totally finished.
Specifically, awaitTaskStopped() waits for a
condition variable to be set as the very last act of the finalize_run() method.
The maximum duration of the wait is limited to the input limit_sec.
protected methods
-
void init_run( void );
-
bool runconfig( void );
-
void announceTaskReady( void );
-
int processCommands( void );
-
void finalize_run( void );
These five commands form the core of a run()-method implementation.
The init_run() and finalize_run() methods are to be
called at the beginning and end of run() method implementations
for subclasses of Task. The init_run() method registers
the Task with the Oorb::Master(3) object controlling
the program, issues a log-message announcement about the Task
starting, and calls the oorb.h macro block_signals()
(except for the signal_manager subclass, which awaits signals
rather than blocking them). The finalize_run() method issues
a log-message announcement about the Task stopping. The
runconfig method returns the value of the m_params.run
configuration variable, announcing a shutdown of the task and
returning the value of m_params.run to the caller. Calling
this routine is optional in subclassed run methods, and should
be .IP "void finalize_run( void );" skipped if the Task
in question should not be allowed the option to not run. If
runconfig returns false to the caller, it is the caller's
responsibility to finish up gracefully and then call finalize_run.
Other jobs may be added to these routines as the interface develops,
so they should not be omitted. The announceTaskReady() method
should be called after the Task has completed all necessary
setup steps and is ready to conduct its routine ongoing processes.
The processCommands() call hands off to the default or
overridden processCommand() method any commands that have
been issued to the Task by other objects. Normally after the
init_run() and announceTaskReady() invocations, and
before the finalize_run() call, the run() method will
execute an indefinite processing loop to handle its assigned jobs.
Generally the processCommands() method should be called once
on each pass through this loop. See the example in the documentation
of the run() method above.
-
void announceTaskReady( void );
-
void spinSleep( bool& spinning );
If spinning is true, the spinSleep() method sleeps for the
internal_timeout_sec period configured in Oorb::Master(3).
If spinning is false, spinSleep() returns immediately.
-
virtual void processCommand( Command* command );
The processCommand() method processes any commands that have
been sent to the Task. The default implementation processes
only one command, Command::STOPTASK, by setting the Task's
public member m_stopTask to true. Other commands may
be added and processed by application programmers. For details on
the Oorb::Command(3) structure, see OorbBasics(3). For the
reference of application programmers who may want to enhance
capabilities, the default implementation of processCommand()
has the following structure:
void
Task::processCommand( Command* command )
{
if( command == nullptr ) {
Om->log()->Complain( "Ignoring null command", "Task::processCommand" );
return;
}
switch( command->command ) {
case Command::STOPTASK:
Om->log()->xVerbose( "Setting task stop flag to 'true'", "Task::processCommand" );
this->m_stopTask = true;
break;
default:
Om->log()->Complain( "Ignoring unsupported command type", "Task::processCommand" );
break;
}
return;
}
-
bool commandAvailable( void );
-
Command* popCommand( void );
The two methods commandAvailable() and popCommand() are used by
processCommands() and should not be needed by application programmers. They are left
protected rather than private to support subclassing.
OBJECT CONFIGURATION PARAMETERS
This class inherits from
Oorb::Configure(3). It has a public
struct with two members.
The
Oorb::LogMsg::Severity(3) enum named
verbosity_task
controls the verbosity of log messages emitted by the task. The
boolean value
run indicates
whether or not the task should run. In
BQConfigure(3) configure calls, the
verbosity_task
variable should be referred to via the string key
verbose. The default setting of
verbose is
notify. The default setting of
run is
true.
Since
Task is a direct sub-class
of
Oorb::Configure(3), it has a public member named
m_params holding one of these
structs.
typedef struct taskParamsStruct {
LogMsg::Severity verbosity_task;
bool run;
} taskParamsStruct;
Sub-classes of
Task may be enhanced with further
BUConfigure(3)-style configuration
parameters as explained in
Oorb::Configure(3).
LIBRARY
-loorb $(ORBLIBS)
ATTRIBUTES
MT-Safe
SEE ALSO
Oorb(3), OorbBasics(3), Oorb::Configure(3), Oorb::Master(3)
AUTHOR
Kent Lindquist