Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

modulebase.h

Go to the documentation of this file.
00001 /*
00002 **  ModuleBase -- A base class for modules.  Includes facilities for
00003 **                spawning worker threads, sending heartbeat and error
00004 **                messages to a shared memory ring and checking the
00005 **                same ring for the shutdown flag.
00006 **
00007 **
00008 **  Configuration file:
00009 **  ------------------
00010 **
00011 
00012 # CmdRingName -- name of ring to check for flags and to send TYPE_HEARTBEAT
00013 #                and TYPE_ERROR messages to.  REQUIRED
00014 #
00015 #
00016 CmdRingName  WAVE_RING
00017 
00018 # LoopSleepMS -- Milliseconds to sleep between main loop executions.
00019 #                Default is 1000.  OPTIONAL
00020 #
00021 # LoopSleepMS 500
00022 
00023 **
00024 */
00025 //---------------------------------------------------------------------------
00026 #ifndef modulebaseH
00027 #define modulebaseH
00028 
00029 #include <configurable.h>
00030 #include <threadableobject.h>
00031 #include <string.h>
00032 #include <worm_types.h>
00033 #include <worm_statuscode.h>
00034 #include <globalutils.h>
00035 #include <ringwriter.h>
00036 #include <msgheartbeat.h>
00037 #include <msgerror.h>
00038 
00039 #include <time.h>
00040 
00041 // Default milliseconds to sleep between main loop executions
00042 #define DEF_LOOP_SLEEP_MS  1000
00043 
00044 
00045 
00046 /* Some stuff to standardize the tracking of the worker thread status
00047 ** (an expanded version, WORM_SERVICE_THREAD_INFO, is defined in
00048 **  serverbase.h, for service threads)
00049 */
00050 
00051 enum WORKER_THREAD_STATUS
00052 {
00053     THREAD_STATUS_STARTING  // set by starting thread
00054   , THREAD_STATUS_INIT      // set by worker for any initialization
00055   , THREAD_STATUS_GOOD      // set by worker
00056   , THREAD_STATUS_QUIT      // set by worker
00057   , THREAD_STATUS_ERROR     // set by worker
00058 };
00059 
00060 // Structure for used by derivative classes to track their
00061 // worker threads
00062 typedef struct WORKER_THREAD_INFO
00063 {
00064    TO_THREAD_ID          thread_id;
00065    time_t                lastpulse; // from time(NULL)
00066    WORKER_THREAD_STATUS  status;
00067 } WORKER_THREAD_INFO_STRUCT;
00068 
00069 
00070 //---------------------------------------------------------------------------
00071 class TModuleBase : public TConfigurable
00072                   , public ThreadableObject
00073 {
00074 protected:
00075 
00076 
00077    // ----------------------------------------------------------------------
00078    //                        FOR  TConfigurable
00079 
00080    /*
00081    **  HandleConfigLine()
00082    **
00083    **  PARMS:
00084    **          p_parser -- the parser being used, command string already
00085    **                      in the current token for comparison with Its()
00086    **
00087    ** RETURN:
00088    **          HANDLE_INVALID --  line invalid
00089    **          HANDLE_UNUSED  --  line not used
00090    **          HANDLE_USED    --  line used okay
00091    **
00092    **  Override for child classes to handle command lines
00093    **
00094    ** In ModuleBase class, used as a convenient way to access the TGlobalUtils
00095    ** for module initialization.  This means that derivative classes do not
00096    ** have to deal with TGlobalUtils until needing to use it for lookups and such.
00097    **
00098    ** !!! NOTE: Ensure that derivative classes ALWAYS contain a call to their
00099    **  <super_class>::HandleConfigLine() in their own HandleConfigLine() method...
00100    ** this ensures that all classes in the heirarchy get their shot at the
00101    ** configuration line.
00102    **
00103    */
00104    HANDLE_STATUS HandleConfigLine( ConfigSource * p_parser );
00105 
00106    /* CheckConfig() -- allows derivative classes to report the status of their
00107    **                  the lookup values.
00108    **
00109    ** From within any deriving class, or further derivation, ALWAYS contain a call to
00110    ** <super_class>::CheckConfig() in their own CheckConfig() method...
00111    ** this ensures that all classes in the heirarchy get their chance to report status.
00112    **
00113    ** All implementations should set ConfigStatus value to WORM_STAT_BADSTATE if there
00114    ** is a configuration problem, otherwise leave it alone.
00115    */
00116    void CheckConfig();
00117 
00118 
00119    // ----------------------------------------------------------------------
00120    //                         FOR TModuleBase
00121 
00122    /* Running -- Variable that all worker threads should check
00123    **            in their execution loops to discover if they should
00124    **            continue running or not.
00125    **            Most commonly, the main thread will set this to false
00126    **            if the shutdown flag is found in the command ring.
00127    **            In theory, worker threads might set this to initiate
00128    **            a shutdown upon error.
00129    */
00130    volatile bool Running;
00131 
00132    WORM_LOGGING_LEVEL LoggingLevel;
00133 
00134    TGlobalUtils * MyGlobalUtils;
00135 
00136    WORM_MSGTYPE_ID TYPE_ERROR
00137                  , TYPE_HEARTBEAT
00138                  ;
00139 
00140    GEN_FILENAME ConfigFileName;
00141 
00142    // milliseconds to sleep between main loop executions (default: DEF_LOOP_SLEEP_MS, above)
00143    int LoopSleepMS;
00144 
00145 
00146    // Ring to check for shutdown flags, to post heartbeats, etc.
00147    WORM_RING_ID   CommandRingKey;   // key to transport ring
00148    TRingWriter  * CommandRing;
00149 
00150    /* SendStatus -- Standard method used to send TYPE_HEARTBEAT and
00151    **               TYPE_ERROR messages to CommandRing (the ring).
00152    **
00153    ** PARAMETERS:
00154    **      p_type = must be TYPE_HEARTBEAT or TYPE_ERROR
00155    **      p_ierr = numberic error code (used only with TYPE_ERROR)
00156    **      p_text = message text (used only with TYPE_ERROR)
00157    **
00158    ** Note: The default values make it possible to send a heartbeat with
00159    **       only:  SendStatus(TYPE_HEARTBEAT)
00160    */
00161    void SendStatus( WORM_MSGTYPE_ID   p_type
00162                   , short             p_ierr = 0
00163                   , const char      * p_text = NULL
00164                   );
00165 
00166    /*
00167    ** Message objects used by SendStatus
00168    */
00169    THeartbeatMessage * HeartbeatMsg;
00170    TErrorMessage     * ErrorMsg;
00171 
00172    /* GetDefaultConfigFile -- returns the name of the default configuration file
00173    **                         for the derivative module class.
00174    */
00175    virtual const char * GetDefaultConfigFile() const = 0; // { return ""; }
00176 
00177    /* Heartbeat -- sends a heartbeat at interval, but with no checking of
00178    **              work thread status.
00179    **
00180    **  OVERRIDE as needed for derivative classes
00181    */
00182    virtual void Heartbeat();
00183 
00184    long LastBeat; // second [time(NULL)] of last heartbeat
00185 
00186 
00187    /*  PrepareToRun -- Actions to take prior to starting the main thread looping.
00188    **                  Called once prior to entering the loop.
00189    **                  (See StartThreadFunc, below about starting worker threads.)
00190    **
00191    ** RETURNS:   true = preparations were good
00192    **           false = preparations failed
00193    **
00194    **  OVERRIDE as needed for derivative classes
00195    */
00196    virtual bool PrepareToRun()
00197    {
00198       LoggingLevel = TGlobalUtils::GetLoggingLevel();
00199       return true;
00200    }
00201 
00202    /* CheckForFatal -- allows the main loop to query derived classes
00203    **                  if a fatal error has been encountered.
00204    **
00205    ** RETURNS:  true if an error occurred and must exit.
00206    **          false if no fatal error has occurred.
00207    */
00208    virtual bool CheckForFatal() { return false; }
00209 
00210    /* MainThreadActions -- Actions to be performed in a derived class
00211    **                      with each pass through the main thread loop.
00212    **                      Called by Run().
00213    **
00214    ** RETURN:
00215    **     WORM_STAT_SUCCESS = good actions
00216    **                         The main thread will immediately repeat its loop
00217    **     WORM_STAT_NOMATCH = no actions to take (good return)
00218    **                         The main thread will sleep before repeating its loop
00219    **     WORM_STAT_FAILURE = actions resulted in, or encountered a fatal error
00220    **                         The main thread will leave its loop and exit (-1)
00221    **
00222    **  OVERRIDE as needed for derivative classes
00223    */
00224    virtual WORM_STATUS_CODE MainThreadActions() = 0;
00225 
00226    /*  FinishedRunning -- Actions to take prior after completing the main thread
00227    **                     looping.  Called once, after exiting the loop.
00228    **
00229    **  OVERRIDE as needed for derivative classes, although clean up
00230    **           may also be coded into derived classes destructor methods.
00231    */
00232    virtual bool FinishedRunning() { return true; }
00233 
00234 
00235 public:
00236 
00237    // ----------------------------------------------------------------------
00238    //                        FOR  ThreadableObject
00239 
00240    /* StartThreadFunc() -- Method through which a newly-spawned
00241    **                      thread returns to the "That" object
00242    **                      to start execution.
00243    **
00244    **  If a derivative class needs to start a worker thread, it
00245    **  should call StartThread() or StartThreadWithArg().  A new
00246    **  thread will be started, and will return through this method
00247    **  (which must be overridden in the derivative class).
00248    **  Generally, this method will include a call to a specific
00249    **  method for the handler to run.
00250    **  The methods that are to be entered by newly spawned threads should
00251    **  have the return type  THREAD_RETURN.  Furthermore, all
00252    **  threads should exit loops and return if variable Running is false.
00253    */
00254    virtual void StartThreadFunc( void * p_argument ) { };
00255 
00256 
00257    // ----------------------------------------------------------------------
00258    //                        FOR  TModuleBase
00259 
00260 
00261 
00262    /* ModuleBase -- constructor
00263    **
00264    ** ACTIONS:  Instantiates the global utilities object
00265    **
00266    ** Derivative classes be sure to call this by:
00267    **
00268    **     <derivative_constructor>(.....) : ModuleBase(p_programname, p_configfilename) { }
00269    */
00270    TModuleBase( char * p_programname
00271               , char * p_configfilename = NULL
00272               );
00273 
00274    /* Destructor -- cleans up the global utilities and ring writer objects
00275    **
00276    */
00277    ~TModuleBase();
00278 
00279    /* Run -- the entry point for the main function to start the module
00280    **        running.
00281    **
00282    ** ACTIONS: Parses the command file (.d)
00283    **          Check for good instantiation of the global utilities
00284    **          Call IsReady() to check module configuration variables.
00285    **          Instantiate the ring writer (for heartbeats and errors)
00286    **          Set up Solaris signal handling
00287    **          Call PrepareToRun() enabling derived classes to start
00288    **             worker threads, etc.
00289    **          Enter a loop that:
00290    **             Calls CheckForFatal() to check for fatal errors
00291    **             Looks for shutdown flag on command ring (sets Running = false if so)
00292    **             Sends Heartbeat
00293    **             Calls MainThreadActions() for derived classes to
00294    **                 perform main thread actions.
00295    **             Departs loop on CheckForFatal() == true
00296    **                          or shutdown flag (-1)
00297    **                          or worker thread sets Running = false
00298    **          Calls FinishedRunning() for derived class clean up.
00299    **
00300    ** CAUTION: IT IS USUALLY NOT A GOOD IDEA TO OVERRIDE THIS METHOD.
00301    */
00302    int Run();
00303 };
00304 
00305 #endif

Generated on Tue May 6 09:16:05 2003 for Earthworm Libs by doxygen1.3-rc3