CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_3/src/FWCore/MessageService/src/ELrecv.cc

Go to the documentation of this file.
00001 // ----------------------------------------------------------------------
00002 //
00003 // ELrecv.cc    This is the global method which the server-side program calls
00004 //              when it receives a message which originated from ELsend on the
00005 //              client process.
00006 //
00007 // This file defines ELrecv() and its pet context supplier ELservConSup class.
00008 //
00009 // ----------------------------------------------------------------------
00010 
00011 
00012 #include "FWCore/MessageService/interface/ELrecv.h"
00013 #include "FWCore/MessageService/interface/ErrorLog.h"
00014 #include "FWCore/MessageService/interface/ELadministrator.h"
00015 #include "FWCore/MessageService/interface/ELcontextSupplier.h"
00016 
00017 #ifndef CSTRING_INCLUDED
00018   #include <cstring>
00019 #endif
00020 
00021 
00022 namespace edm {
00023 namespace service {
00024 
00025 class ELservConSup : public ELcontextSupplier  {
00026 
00027 public:
00028   ELstring context()                      const  { return con_; }
00029   ELstring summaryContext()               const  { return sumcon_; }
00030   ELstring fullContext()                  const  { return fullcon_; }
00031   void setContext        ( const ELstring & s )  { con_     = s; }
00032   void setSummaryContext ( const ELstring & s )  { sumcon_  = s; }
00033   void setFullContext    ( const ELstring & s )  { fullcon_ = s; }
00034   ELservConSup * clone() const {  return new ELservConSup ( *this );   }
00035 private:
00036   ELstring  con_;
00037   ELstring  sumcon_;
00038   ELstring  fullcon_;
00039 
00040 };
00041 
00042 void  ELrecv ( int nbytes, const char * data )  {
00043   ELrecv ( nbytes, data, "*ELrecv*" );
00044 }
00045 
00046 
00047 void  ELrecv ( int nbytes, const char * data, ELstring localModule )  {
00048 
00049   static const int  MAXITEMCOUNT = 100;
00050 
00051   static ErrorLog           errlog;
00052   static ELservConSup       con;
00053   static ELadministrator *  logger = ELadministrator::instance();
00054 
00055   // Pull out the extended id.  Carefully look at ELcollected::emitXid to
00056   // make certain we take things out in the proper order.
00057 
00058   ELstring process;
00059   ELstring module;
00060   ELstring subroutine;
00061   ELstring id;
00062   ELstring sevString;
00063   int      sevLevel;
00064 
00065   const char *  nextItem = data;
00066 
00067   process = nextItem;
00068   nextItem += strlen(nextItem) + 1;
00069 
00070   if (localModule == "*ELrecv*")  module = nextItem;
00071   else                            module = localModule + ":" + nextItem;
00072   nextItem += strlen(nextItem) + 1;
00073 
00074   subroutine = nextItem;
00075   nextItem += strlen(nextItem) + 1;
00076 
00077   id = nextItem;
00078   nextItem += strlen(nextItem) + 1;
00079 
00080   sevString = nextItem;
00081   nextItem += strlen(nextItem) + 1;
00082   std::istringstream  ist (sevString);
00083   if ( ! (ist >> sevLevel) )  {
00084     // This should not be possible.  But if it does, we don't want to
00085     // kill off the probably critical error monitoring job!
00086     errlog ( ELerror2, "Collection Error" ) <<
00087         "An error message received has an unreadable value of severity level"
00088         << sevString << endmsg;
00089     sevLevel = ELseverityLevel::ELsev_unspecified;
00090   }
00091   if ( sevLevel < ELseverityLevel::ELsev_zeroSeverity ||
00092        sevLevel > ELseverityLevel::ELsev_highestSeverity )  {
00093     // Again, this should not be possible.
00094     errlog ( ELerror2, "Collection Error" ) <<
00095         "An error message received has an out-of-range value of severity level"
00096         << sevString << endmsg;
00097     sevLevel = ELseverityLevel::ELsev_unspecified;
00098   }
00099 
00100   // Pull out the context strings and set up the special supplier.
00101 
00102   ELstring  context;
00103 
00104   context = nextItem;
00105   nextItem += strlen(nextItem) + 1;
00106   con.setSummaryContext( context );
00107 
00108   context = nextItem;
00109   nextItem += strlen(nextItem) + 1;
00110   con.setContext( context );
00111 
00112   context = nextItem;
00113   nextItem += strlen(nextItem) + 1;
00114   con.setFullContext( context );
00115 
00116   // Remember the context supplier, and substitute the special supplier.
00117 
00118   ELcontextSupplier & oldCS = logger->swapContextSupplier(con);
00119 
00120   // Set the module, subroutine, and process according to this xid.
00121 
00122   ELstring  oldProcess = logger->swapProcess(process);
00123   errlog.setModule (module);
00124   errlog.setSubroutine(subroutine);
00125 
00126   // Instantiate a message with the appropriate severity level and id.
00127 
00128   errlog ( ELseverityLevel( ELseverityLevel::ELsev_(sevLevel)), id );
00129 
00130   // Add the remaining items to this message.
00131   //    To avoid any possibility of a completely runaway message, we limit
00132   //    the number of items output to 100 by doing a for instead of a while
00133   //    loop.
00134 
00135   ELstring  item;
00136   int       itemCount;
00137   for ( itemCount = 0; itemCount < MAXITEMCOUNT; itemCount++ )  {
00138     if (*nextItem == 0) break;
00139     item = nextItem;
00140     nextItem += strlen(nextItem) + 1;
00141     errlog << item;
00142   }
00143 
00144   // If the direct ELrecv form was used, end the message,
00145   // thus causing the logging.  If the errlog (nbytes, data) form was
00146   // used, the user will supply the endmsg.
00147 
00148   if ( localModule == "*ELrecv*" )  {
00149     errlog << endmsg;
00150   }
00151 
00152   if ( *nextItem++ != 0 )  {
00153     errlog << endmsg;
00154     errlog ( ELerror2, "Collection Error" ) <<
00155         "Apparent runaway error message on the previous message!" <<
00156         "Truncated after " << MAXITEMCOUNT << "items." << endmsg;
00157   }
00158   int  diff = nextItem - data;
00159   if ( diff != nbytes )  {
00160     errlog << endmsg;
00161     errlog ( ELerror2, "Collection Error" ) <<
00162     "Apparent corrupted transmission of error message"
00163     << "on the previous message!"
00164     << "Total length was" << diff << "nbytes transmitted was" << nbytes
00165     << endmsg;
00166   }
00167 
00168   // End the message, before we swap back the context and process.
00169   // (This is what makes the endmsg in errlog(nbytes, data) << endmsg
00170   // superfluous.)
00171 
00172   errlog << endmsg;
00173 
00174   // Reset the context supplier and process to the remembered value.
00175 
00176   logger->swapContextSupplier(oldCS);
00177   logger->swapProcess(oldProcess);
00178 
00179 } // ELrecv()
00180 
00181 
00182 } // end of namespace service  
00183 } // end of namespace edm