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

# ringreaderserver.cpp

Go to the documentation of this file.

    00001 //---------------------------------------------------------------------------
    00002 #include "ringreaderserver.h"
    00003
    00004 //---------------------------------------------------------------------------
    00005
    00006 #include <logger.h>
    00007 #include <worm_exceptions.h>
    00008 #include <comfile.h>
    00009
    00010 #pragma package(smart_init)
    00011
    00012
    00013 //---------------------------------------------------------------------------
    00014 RingReaderServer::RingReaderServer()
    00015 {
    00016    InputRingKey = WORM_RING_INVALID;
    00017    InputRegion.addr = NULL;
    00018    MaxMessageLength = 0;
    00019    MessageBuffer = NULL;
    00020    ServeLogoCount = 0;
    00021 }
    00022 //---------------------------------------------------------------------------
    00023 RingReaderServer::~RingReaderServer()
    00024 {
    00025    if ( InputRingKey != CommandRingKey )
    00026    {
    00027       if ( InputRegion.addr != NULL )
    00028       {
    00029          tport_detach( &InputRegion );
    00030          InputRegion.addr = NULL;
    00031       }
    00032    }
    00033    if ( MessageBuffer != NULL )
    00034    {
    00035       delete( MessageBuffer );
    00036    }
    00037 }
    00038 //---------------------------------------------------------------------------
    00039 HANDLE_STATUS RingReaderServer::HandleConfigLine( ConfigSource * p_parser )
    00040 {
    00041    // Do not manipulate ConfigState herein.
    00042    //
    00043    HANDLE_STATUS r_handled = WormServerBase::HandleConfigLine(p_parser);
    00044
    00045    if ( r_handled == HANDLER_UNUSED )
    00046    {
    00047       // base class didn't use it, check if this class does
    00048
    00049       char * _token;
    00050
    00051       try
    00052       {
    00053          do
    00054          {
    00055
    00056             if( p_parser->Its("ServeLogo") )
    00057             {
    00058                r_handled = HANDLER_USED;
    00059
    00060                if ( ServeLogoCount == SERVE_MAX_LOGOS )
    00061                {
    00062                   throw worm_exception("Attempt to load too many <ServeLogo> lines");
    00063                }
    00064
    00065                // ServeLogo     INST_WILDCARD   MOD_GLASS       TYPE_WILDCARD
    00066
    00067                // INSTALLATION
    00068
    00069                _token = p_parser->String();
    00070
    00071                if ( strlen(_token) == 0 )
    00072                {
    00073                   throw worm_exception("Incomplete <ServeLogo> line (no installation)");
    00074                }
    00075
    00076                ServeLogo[ServeLogoCount].instid = TGlobalUtils::LookupInstallationId(_token);
    00077
    00078                if (   ServeLogo[ServeLogoCount].type == TGlobalUtils::LookupInstallationId("INST_WILDCARD")
    00079                    && strcmp(_token, "INST_WILDCARD") != 0
    00080                   )
    00081                {
    00082                   worm_exception _expt("Unrecognized installation id: ");
    00083                   _expt += _token;
    00084                   _expt += " in <ServeLogo> line";
    00085                   throw _expt;
    00086                }
    00087
    00088                // MODULE
    00089
    00090                _token = p_parser->String();
    00091
    00092                if ( strlen(_token) == 0 )
    00093                {
    00094                   throw worm_exception("Incomplete <ServeLogo> line (no module)");
    00095                }
    00096
    00097                ServeLogo[ServeLogoCount].mod = TGlobalUtils::LookupModuleId(_token);
    00098
    00099                if (   ServeLogo[ServeLogoCount].mod == TGlobalUtils::LookupModuleId("MOD_WILDCARD")
    00100                    && strcmp(_token, "MOD_WILDCARD") != 0
    00101                   )
    00102                {
    00103                   worm_exception _expt("Unrecognized module id: ");
    00104                   _expt += _token;
    00105                   _expt += " in <ServeLogo> line";
    00106                   throw _expt;
    00107                }
    00108
    00109                // MESSAGE TYPE
    00110
    00111                _token = p_parser->String();
    00112
    00113                if ( strlen(_token) == 0 )
    00114                {
    00115                   throw worm_exception("Incomplete <ServeLogo> line (no message type)");
    00116                }
    00117
    00118                ServeLogo[ServeLogoCount].type = TGlobalUtils::LookupMessageTypeId(_token);
    00119
    00120                if (   ServeLogo[ServeLogoCount].type == TGlobalUtils::LookupMessageTypeId("TYPE_WILDCARD")
    00121                    && strcmp(_token, "TYPE_WILDCARD") != 0
    00122                   )
    00123                {
    00124                   worm_exception _expt("Unrecognized message type id: ");
    00125                   _expt += _token;
    00126                   _expt += " in <ServeLogo> line";
    00127                   throw _expt;
    00128                }
    00129
    00130                ServeLogoCount++;
    00131
    00132                continue;
    00133             }
    00134
    00135             if( p_parser->Its("InputRing") )
    00136             {
    00137                r_handled = HANDLER_USED;
    00138                _token = p_parser->String();
    00139                if ( strlen(_token) == 0 )
    00140                {
    00141                  throw worm_exception("missing <InputRing> for input messages");
    00142                }
    00143                strncpy( InputRingName, _token, MAX_RINGNAME_LEN );
    00144
    00145                if ( (InputRingKey = TGlobalUtils::LookupRingKey(InputRingName)) == WORM_RING_INVALID )
    00146                {
    00147                  throw worm_exception("invalid <InputRing>");
    00148                }
    00149                continue;
    00150             }
    00151
    00152             if( p_parser->Its("MaxMsgSize") )
    00153             {
    00154                r_handled = HANDLER_USED;
    00155                int _maxmsglen = p_parser->Int();
    00156                if ( _maxmsglen <= 0 )
    00157                {
    00158                  throw worm_exception("invalid <MaxMsgSize> for input messages");
    00159                }
    00160                MaxMessageLength = _maxmsglen;
    00161                continue;
    00162             }
    00163
    00164          } while( false );
    00165       }
    00166       catch( worm_exception _rte )
    00167       {
    00168          r_handled = HANDLER_INVALID;
    00169          TLogger::Logit( WORM_LOG_TOFILE|WORM_LOG_TOSTDERR|WORM_LOG_TIMESTAMP
    00170                        , "RingReaderServer::HandleConfigLine(): configuration error:\n%s\n"
    00171                        , _rte.what()
    00172                        );
    00173          r_handled = HANDLER_INVALID;
    00174       }
    00175    }
    00176    return r_handled;
    00177 }
    00178 //---------------------------------------------------------------------------
    00179 void RingReaderServer::CheckConfig()
    00180 {
    00181    WormServerBase::CheckConfig();
    00182
    00183    if ( ServeLogoCount == 0 )
    00184    {
    00185       TLogger::Logit( WORM_LOG_TOFILE|WORM_LOG_TOSTDERR|WORM_LOG_TIMESTAMP
    00186                     , "RingReaderServer::HaveMyConfigs(): No <ServeLogo> lines found in the config file\n"
    00187                     );
    00188       ConfigState = WORM_STAT_BADSTATE;
    00189    }
    00190
    00191    if ( InputRingKey == WORM_RING_INVALID )
    00192    {
    00193       TLogger::Logit( WORM_LOG_TOFILE|WORM_LOG_TOSTDERR|WORM_LOG_TIMESTAMP
    00194                     , "RingReaderServer::HaveMyConfigs(): No <InputRing> found in the config file\n"
    00195                     );
    00196       ConfigState = WORM_STAT_BADSTATE;
    00197    }
    00198
    00199    if ( MaxMessageLength <= 1 )
    00200    {
    00201       TLogger::Logit( WORM_LOG_TOFILE|WORM_LOG_TOSTDERR|WORM_LOG_TIMESTAMP
    00202                     , "RingReaderServer::HaveMyConfigs(): No valid <MaxMsgSize> found in the config file\n"
    00203                     );
    00204       ConfigState = WORM_STAT_BADSTATE;
    00205    }
    00206 }
    00207 //---------------------------------------------------------------------------
    00208 bool RingReaderServer::PrepareToRun()
    00209 {
    00210    bool r_state = true;
    00211    try
    00212    {
    00213       if ( TGlobalUtils::LookupMessageTypeId("TYPE_ERROR") == WORM_MSGTYPE_INVALID )
    00214       {
    00215          throw worm_exception("RingReaderServer::PrepareToRun(): message type TYPE_ERROR not found in lookups");
    00216       }
    00217
    00218       if ( (MessageBuffer = new char[MaxMessageLength+1]) == NULL )
    00219       {
    00220          throw worm_exception("RingReaderServer::PrepareToRun(): failed allocating message buffer");
    00221       }
    00222
    00223
    00224       if ( (LoggingLevel = TGlobalUtils::GetLoggingLevel()) == WORM_LOG_DEBUG )
    00225       {
    00226          TLogger::Logit( WORM_LOG_TOFILE|WORM_LOG_TOSTDOUT
    00227                        , "RingReaderServer::PrepareToRun(): A  %s  %d  %d  (%d + 1)\n"
    00228                        , InputRingName
    00229                        , InputRingKey
    00230                        , InputRegion.addr
    00231                        , MaxMessageLength
    00232                        );
    00233       }
    00234
    00235       if ( InputRingKey != CommandRingKey )
    00236       {
    00237          tport_attach( &InputRegion, InputRingKey );
    00238       }
    00239       else
    00240       {
    00241          memcpy( (void *)&InputRegion , (void *)&CommandRegion, sizeof(InputRegion) );
    00242       }
    00243
    00244       if ( TGlobalUtils::GetLoggingLevel() == WORM_LOG_DEBUG )
    00245       {
    00246          TLogger::Logit( WORM_LOG_TOFILE|WORM_LOG_TOSTDOUT
    00247                        , "RingReaderServer::PrepareToRun(): B  %s  %d  %d\n"
    00248                        , InputRingName
    00249                        , InputRingKey
    00250                        , InputRegion.addr
    00251                        );
    00252       }
    00253    }
    00254    catch( worm_exception _rte )
    00255    {
    00256       r_state = false;
    00257    }
    00258    return r_state;
    00259 }
    00260 //---------------------------------------------------------------------------
    00261 WORM_STATUS_CODE RingReaderServer::MainThreadActions()
    00262 {
    00263    static int      _getmsg_status;
    00264         static MSG_LOGO _arrivelogo;      // logo of arriving message
    00265    static long     _arr_msg_len;     // length of arriving message
    00266    static bool     _msg_ready;
    00267    static char     _errormsg[300];   //
    00268
    00269    static InstallWildcard = TGlobalUtils::LookupInstallationId("INST_WILDCARD");
    00270    static ModuleWildcard  = TGlobalUtils::LookupModuleId("MOD_WILDCARD");
    00271    static MessageWildcard = TGlobalUtils::LookupMessageTypeId("TYPE_WILDCARD");
    00272
    00273    WORM_STATUS_CODE r_status = WORM_STAT_SUCCESS;
    00274
    00275    try
    00276    {
    00277       _msg_ready = true;
    00278
    00279       // Get a message from transport ring
    00280       _getmsg_status = tport_getmsg( &InputRegion
    00281                                    ,  ServeLogo
    00282                                    ,  ServeLogoCount
    00283                                    , &_arrivelogo
    00284                                    , &_arr_msg_len
    00285                                    ,  MessageBuffer
    00286                                    ,  MaxMessageLength
    00287                                    );
    00288
    00289       switch( _getmsg_status )
    00290       {
    00291         case GET_OK:
    00292              break;
    00293
    00294         case GET_MISS:
    00295         case GET_MISS_LAPPED:
    00296              // report error, handle message
    00297              SendStatus( TGlobalUtils::LookupMessageTypeId("TYPE_ERROR"), ERR_MISSMSG, "missed messages" );
    00298              break;
    00299
    00300         case GET_MISS_SEQGAP:
    00301              // report error, handle message
    00302              SendStatus( TGlobalUtils::LookupMessageTypeId("TYPE_ERROR"), ERR_MISSMSG, "saw sequence gap" );
    00303              break;
    00304
    00305         case GET_NOTRACK:
    00306              // report error, handle message
    00307              sprintf( _errormsg
    00308                     , "no tracking for logo i%d m%d t%d in %s"
    00309                     , (int)_arrivelogo.instid
    00310                     , (int)_arrivelogo.mod
    00311                     , (int)_arrivelogo.type
    00312                     , InputRingName
    00313                     );
    00314              SendStatus( TGlobalUtils::LookupMessageTypeId("TYPE_ERROR"), ERR_NOTRACK, _errormsg );
    00315              break;
    00316
    00317         case GET_TOOBIG:
    00318              // report error, return to main loop to sleep
    00319              sprintf( _errormsg
    00320                     , "tport msg[%ld] i%d m%d t%d too big. Max is %ld"
    00321                     , _arr_msg_len
    00322                     , (int)_arrivelogo.instid
    00323                     , (int)_arrivelogo.mod
    00324                     , (int)_arrivelogo.type
    00325                     , MaxMessageLength
    00326                     );
    00327              SendStatus( TGlobalUtils::LookupMessageTypeId("TYPE_ERROR"), ERR_TOOBIG, _errormsg );
    00328
    00329              // fall - through
    00330
    00331         case GET_NONE:
    00332              _msg_ready = false;
    00333
    00334              // no message ready, return to main loop to sleep
    00335              break;
    00336       }
    00337
    00338       if ( _msg_ready )
    00339       {
    00340          // NULL-terminate string buffer
    00341          MessageBuffer[_arr_msg_len] = 0;
    00342          // truncate end-of-line if present
    00343          if ( MessageBuffer[_arr_msg_len-1] == '\n' )
    00344          {
    00345             _arr_msg_len--;
    00346             MessageBuffer[_arr_msg_len] = 0;
    00347          }
    00348
    00349          for ( int _i = 0, _sz = ServeLogoCount ; _i < _sz ; _i++ )
    00350          {
    00351             if (   (   ServeLogo[_i].instid == InstallWildcard
    00352                     || _arrivelogo.instid   == InstallWildcard
    00353                     || _arrivelogo.instid   == ServeLogo[_i].instid
    00354                    )
    00355                 && (   ServeLogo[_i].mod == ModuleWildcard
    00356                     || _arrivelogo.mod   == ModuleWildcard
    00357                     || _arrivelogo.mod   == ServeLogo[_i].mod
    00358                    )
    00359                 && (   ServeLogo[_i].type == MessageWildcard
    00360                     || _arrivelogo.type   == MessageWildcard
    00361                     || _arrivelogo.type   == ServeLogo[_i].type
    00362                    )
    00363                )
    00364             {
    00365                if ( ! MessageFromRing(_arrivelogo, MessageBuffer) )
    00366                {
    00367                   throw worm_exception("MessageFromRing() reported failure");
    00368                }
    00369                break;
    00370             }
    00371          }
    00372       }
    00373    }
    00374    catch( worm_exception _rte )
    00375    {
    00376       r_status = WORM_STAT_FAILURE;
    00377    }
    00378
    00379    return r_status;
    00380 }
    00381 //---------------------------------------------------------------------------
    00382 void RingReaderServer::FinishedRunning()
    00383 {
    00384    if ( InputRegion.addr != NULL )
    00385    {
    00386       if ( InputRingKey != CommandRingKey )
    00387       {
    00388          tport_detach( &InputRegion );
    00389       }
    00390       InputRegion.addr = NULL;
    00391    }
    00392 }
    00393 //---------------------------------------------------------------------------
    00394