CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/FWCore/MessageLogger/src/MessageDrop.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     MessageLogger
00004 // Class  :     MessageDrop
00005 //
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:  M. Fischler and Jim Kowalkowsi
00010 //         Created:  Tues Feb 14 16:38:19 CST 2006
00011 // $Id: MessageDrop.cc,v 1.13 2011/06/07 22:24:31 fwyzard Exp $
00012 //
00013 
00014 // system include files
00015 #include "boost/thread/tss.hpp"
00016 #include <cstring>
00017 
00018 // user include files
00019 #include "FWCore/MessageLogger/interface/MessageDrop.h"
00020 
00021 // Change Log
00022 //
00023 // 1 12/13/07 mf        the static drops had been file-global level; moved it
00024 //                      into the instance() method to cure a 24-byte memory
00025 //                      leak reported by valgrind. Suggested by MP.
00026 //
00027 // 2 9/23/10 mf         Variables supporting situations where no thresholds are
00028 //                      low enough to react to LogDebug (or info, or warning)
00029 //
00030 // 3 11/2/10 mf, crj    Prepare moduleContext method:
00031 //                      see MessageServer/src/MessageLogger.cc change 17.
00032 //                      Change is extensive, involving StringProducer and
00033 //                      its derivative classes.
00034 //
00035 // 4 11/29/10 mf        Intitalize all local string-holders in the various
00036 //                      string producers. 
00037 //
00038 // 5  mf 11/30/10       Snapshot method to prepare for invalidation of the   
00039 //                      pointers used to hold module context.  Supports 
00040 //                      surviving throws that cause objects to go out of scope.
00041 //
00042 // 6  mf 12/7/10        Fix in snapshot method to avoid strncpy from
00043 //                      a string to the identical address, which valgrind
00044 //                      reports as an overlap problem.
00045 //
00046 // 7  fwyzard 7/6/11    Add support for discarding LogError-level messages
00047 //                      on a per-module basis (needed at HLT)
00048 
00049 using namespace edm;
00050 
00051 edm::Exception * MessageDrop::ex_p = 0;
00052 bool MessageDrop::debugEnabled=true;
00053 bool MessageDrop::infoEnabled=true;
00054 bool MessageDrop::warningEnabled=true;
00055 bool MessageDrop::errorEnabled=true;
00056 // The following are false at initialization (in case configure is not done)
00057 // and are set true at the start of configure_ordinary_destinations, 
00058 // but are set false once a destination is thresholded to react to the 
00059 // corresponding severity: 
00060 bool MessageDrop::debugAlwaysSuppressed=false;          // change log 2
00061 bool MessageDrop::infoAlwaysSuppressed=false;           // change log 2
00062 bool MessageDrop::warningAlwaysSuppressed=false;        // change log 2
00063 
00064 MessageDrop *
00065 MessageDrop::instance()
00066 {
00067   static boost::thread_specific_ptr<MessageDrop> drops;
00068   MessageDrop* drop = drops.get();
00069   if(drop==0) { 
00070     drops.reset(new MessageDrop);
00071     drop=drops.get(); 
00072   }
00073   return drop;
00074 }
00075 
00076 namespace edm {
00077 namespace messagedrop {
00078 
00079 class StringProducer {
00080   public:
00081     virtual ~StringProducer() {}
00082     virtual std::string theContext() const = 0;
00083     virtual void snapshot() = 0;
00084 };
00085   
00086 class StringProducerWithPhase : public StringProducer
00087 {
00088   typedef std::map<const void*, std::string>::const_iterator NLMiter;
00089   public:
00090     StringProducerWithPhase() 
00091     : name_initial_value_  (" ")                        // change log 4
00092     , label_initial_value_ (" ")                        
00093     , name_                (&name_initial_value_)
00094     , label_               (&label_initial_value_)
00095     , phasePtr_            ("(Startup)")
00096     , moduleID_            (0)
00097     {}
00098     virtual std::string theContext() const {
00099       if (cache_.empty()) {
00100         if (moduleID_ != 0) {
00101           NLMiter nameLableIter = nameLabelMap_.find(moduleID_);
00102           if  (nameLableIter != nameLabelMap_.end()) {
00103             cache_.assign(nameLableIter->second);
00104             cache_.append(phasePtr_);
00105             return cache_; 
00106           }
00107         }
00108         cache_.assign(*name_);
00109         cache_.append(":");
00110         cache_.append(*label_);
00111         nameLabelMap_[moduleID_] = cache_;
00112         cache_.append(phasePtr_);       
00113       }
00114         return cache_;
00115     }
00116     void set(std::string const & name,
00117              std::string const & label,
00118              const void * moduleID,
00119              const char* phase)  {
00120       name_ = &name;
00121       label_ = &label;     
00122       moduleID_ = moduleID;
00123       phasePtr_ = phase;
00124       cache_.clear();        
00125     } 
00126     virtual void snapshot()                             // change log 5
00127     {
00128       snapshot_name_ = *name_;
00129       name_ = &snapshot_name_;
00130       snapshot_label_ = *label_;
00131       label_ = &snapshot_label_;
00132       if ( snapshot_phase_ != phasePtr_ ) {             // change log 6
00133         std::strncpy (snapshot_phase_,phasePtr_,PHASE_MAX_LENGTH);
00134       }
00135       snapshot_phase_[PHASE_MAX_LENGTH] = 0;
00136       phasePtr_ = snapshot_phase_;
00137     }
00138   private:
00139     static const int PHASE_MAX_LENGTH = 32;
00140     std::string const name_initial_value_;
00141     std::string const label_initial_value_;
00142     std::string const * name_;
00143     std::string const * label_;
00144     const char* phasePtr_;
00145     const void * moduleID_;
00146     mutable std::string cache_;
00147     mutable std::map<const void*, std::string> nameLabelMap_;
00148     std::string snapshot_name_;
00149     std::string snapshot_label_;
00150     char snapshot_phase_[PHASE_MAX_LENGTH+1];
00151 };
00152 
00153 class StringProducerPath : public StringProducer{
00154   public:
00155     StringProducerPath() 
00156     : typePtr_("PathNotYetEstablished")                 // change log 4
00157     , path_ (" ") {}
00158      virtual std::string theContext() const {
00159       if ( cache_.empty() ) {
00160         cache_.assign(typePtr_);
00161         cache_.append(path_);
00162       }
00163       return cache_; 
00164     }
00165     void set(const char* type, std::string const & pathname) {
00166       typePtr_ = type;
00167       path_ = pathname;
00168       cache_.clear();        
00169     } 
00170     virtual void snapshot()                             // change log 5
00171     {
00172       if ( snapshot_type_ != typePtr_ ) {               // change log 6
00173         std::strncpy (snapshot_type_,typePtr_,TYPE_MAX_LENGTH);
00174       }
00175       snapshot_type_[TYPE_MAX_LENGTH] = 0;
00176       typePtr_ = snapshot_type_;
00177     }
00178   private:
00179     static const int TYPE_MAX_LENGTH = 32;
00180     const char* typePtr_;
00181     std::string path_;
00182     mutable std::string cache_;
00183     char snapshot_type_[TYPE_MAX_LENGTH+1];
00184 };
00185   
00186 class StringProducerSinglet : public StringProducer{
00187   public:
00188     StringProducerSinglet() : singlet_("(NoModuleName)") {}
00189     virtual std::string theContext() const {
00190       return singlet_;
00191     }
00192     void set(const char * sing) {singlet_ = sing; } 
00193     virtual void snapshot() 
00194     {
00195       if ( snapshot_singlet_ != singlet_ ) {            // change log 6
00196         std::strncpy (snapshot_singlet_,singlet_,SINGLET_MAX_LENGTH);
00197       }
00198       snapshot_singlet_[SINGLET_MAX_LENGTH] = 0;
00199       singlet_ = snapshot_singlet_;
00200     }
00201   private:
00202     static const int SINGLET_MAX_LENGTH = 32;
00203     const char * singlet_;
00204     char snapshot_singlet_[SINGLET_MAX_LENGTH+1];
00205 };
00206 
00207 } // namespace messagedrop
00208 
00209 MessageDrop::MessageDrop()
00210   : moduleName ("")
00211   , runEvent("pre-events")
00212   , jobreport_name()                                    
00213   , jobMode("")                                         
00214   , spWithPhase(new  messagedrop::StringProducerWithPhase)
00215   , spPath (new messagedrop::StringProducerPath)
00216   , spSinglet (new messagedrop::StringProducerSinglet)
00217   , moduleNameProducer (spSinglet)
00218 { 
00219 } 
00220 
00221 MessageDrop::~MessageDrop()
00222 {
00223   delete spSinglet;
00224   delete spPath;
00225   delete spWithPhase;
00226 }
00227 
00228 void MessageDrop::setModuleWithPhase(std::string const & name,
00229                                      std::string const & label,
00230                                      const void * moduleID,
00231                                      const char* phase) {
00232   spWithPhase->set(name, label, moduleID, phase);
00233   moduleNameProducer = spWithPhase;
00234 }                                    
00235  
00236 void MessageDrop::setPath(const char* type, std::string const & pathname) {
00237   spPath->set(type, pathname);
00238   moduleNameProducer = spPath;
00239 }
00240 
00241 void MessageDrop::setSinglet(const char * sing) {
00242   spSinglet->set(sing);
00243   moduleNameProducer = spSinglet;
00244 }
00245 
00246 std::string MessageDrop::moduleContext() {
00247   return moduleNameProducer->theContext();
00248 }
00249 
00250 void MessageDrop::snapshot() {
00251   const_cast<messagedrop::StringProducer *>(moduleNameProducer)->snapshot();
00252 }
00253 
00254 } // namespace edm
00255 
00256 
00257 unsigned char MessageDrop::messageLoggerScribeIsRunning = 0;