CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/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.14 2011/10/13 22:40:28 wmtan 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     , cache_               ()
00098     , nameLabelMap_        ()
00099     , snapshot_name_       ()
00100     , snapshot_label_      ()
00101     , snapshot_phase_      () {
00102       memset(snapshot_phase_, '\0', sizeof(snapshot_phase_));
00103     }
00104 
00105     virtual std::string theContext() const {
00106       if (cache_.empty()) {
00107         if (moduleID_ != 0) {
00108           NLMiter nameLableIter = nameLabelMap_.find(moduleID_);
00109           if  (nameLableIter != nameLabelMap_.end()) {
00110             cache_.assign(nameLableIter->second);
00111             cache_.append(phasePtr_);
00112             return cache_; 
00113           }
00114         }
00115         cache_.assign(*name_);
00116         cache_.append(":");
00117         cache_.append(*label_);
00118         nameLabelMap_[moduleID_] = cache_;
00119         cache_.append(phasePtr_);       
00120       }
00121         return cache_;
00122     }
00123     void set(std::string const & name,
00124              std::string const & label,
00125              const void * moduleID,
00126              const char* phase)  {
00127       name_ = &name;
00128       label_ = &label;     
00129       moduleID_ = moduleID;
00130       phasePtr_ = phase;
00131       cache_.clear();        
00132     } 
00133     virtual void snapshot()                             // change log 5
00134     {
00135       snapshot_name_ = *name_;
00136       name_ = &snapshot_name_;
00137       snapshot_label_ = *label_;
00138       label_ = &snapshot_label_;
00139       if ( snapshot_phase_ != phasePtr_ ) {             // change log 6
00140         std::strncpy (snapshot_phase_,phasePtr_,PHASE_MAX_LENGTH);
00141       }
00142       snapshot_phase_[PHASE_MAX_LENGTH] = 0;
00143       phasePtr_ = snapshot_phase_;
00144     }
00145   private:
00146     static const int PHASE_MAX_LENGTH = 32;
00147     std::string const name_initial_value_;
00148     std::string const label_initial_value_;
00149     std::string const * name_;
00150     std::string const * label_;
00151     const char* phasePtr_;
00152     const void * moduleID_;
00153     mutable std::string cache_;
00154     mutable std::map<const void*, std::string> nameLabelMap_;
00155     std::string snapshot_name_;
00156     std::string snapshot_label_;
00157     char snapshot_phase_[PHASE_MAX_LENGTH+1];
00158 };
00159 
00160 class StringProducerPath : public StringProducer{
00161   public:
00162     StringProducerPath() 
00163     : typePtr_("PathNotYetEstablished")                 // change log 4
00164     , path_ (" ")
00165     , cache_()
00166     , snapshot_type_() {
00167       memset(snapshot_type_, '\0', sizeof(snapshot_type_));
00168     }
00169      virtual std::string theContext() const {
00170       if ( cache_.empty() ) {
00171         cache_.assign(typePtr_);
00172         cache_.append(path_);
00173       }
00174       return cache_; 
00175     }
00176     void set(const char* type, std::string const & pathname) {
00177       typePtr_ = type;
00178       path_ = pathname;
00179       cache_.clear();        
00180     } 
00181     virtual void snapshot()                             // change log 5
00182     {
00183       if ( snapshot_type_ != typePtr_ ) {               // change log 6
00184         std::strncpy (snapshot_type_,typePtr_,TYPE_MAX_LENGTH);
00185       }
00186       snapshot_type_[TYPE_MAX_LENGTH] = 0;
00187       typePtr_ = snapshot_type_;
00188     }
00189   private:
00190     static const int TYPE_MAX_LENGTH = 32;
00191     const char* typePtr_;
00192     std::string path_;
00193     mutable std::string cache_;
00194     char snapshot_type_[TYPE_MAX_LENGTH+1];
00195 };
00196   
00197 class StringProducerSinglet : public StringProducer{
00198   public:
00199     StringProducerSinglet()
00200     : singlet_("(NoModuleName)")
00201     , snapshot_singlet_() {
00202       memset(snapshot_singlet_, '\0', sizeof(snapshot_singlet_));
00203     }
00204     virtual std::string theContext() const {
00205       return singlet_;
00206     }
00207     void set(const char * sing) {singlet_ = sing; } 
00208     virtual void snapshot() 
00209     {
00210       if ( snapshot_singlet_ != singlet_ ) {            // change log 6
00211         std::strncpy (snapshot_singlet_,singlet_,SINGLET_MAX_LENGTH);
00212       }
00213       snapshot_singlet_[SINGLET_MAX_LENGTH] = 0;
00214       singlet_ = snapshot_singlet_;
00215     }
00216   private:
00217     static const int SINGLET_MAX_LENGTH = 32;
00218     const char * singlet_;
00219     char snapshot_singlet_[SINGLET_MAX_LENGTH+1];
00220 };
00221 
00222 } // namespace messagedrop
00223 
00224 MessageDrop::MessageDrop()
00225   : moduleName ("")
00226   , runEvent("pre-events")
00227   , jobreport_name()                                    
00228   , jobMode("")                                         
00229   , spWithPhase(new  messagedrop::StringProducerWithPhase)
00230   , spPath (new messagedrop::StringProducerPath)
00231   , spSinglet (new messagedrop::StringProducerSinglet)
00232   , moduleNameProducer (spSinglet)
00233 { 
00234 } 
00235 
00236 MessageDrop::~MessageDrop()
00237 {
00238   delete spSinglet;
00239   delete spPath;
00240   delete spWithPhase;
00241 }
00242 
00243 void MessageDrop::setModuleWithPhase(std::string const & name,
00244                                      std::string const & label,
00245                                      const void * moduleID,
00246                                      const char* phase) {
00247   spWithPhase->set(name, label, moduleID, phase);
00248   moduleNameProducer = spWithPhase;
00249 }                                    
00250  
00251 void MessageDrop::setPath(const char* type, std::string const & pathname) {
00252   spPath->set(type, pathname);
00253   moduleNameProducer = spPath;
00254 }
00255 
00256 void MessageDrop::setSinglet(const char * sing) {
00257   spSinglet->set(sing);
00258   moduleNameProducer = spSinglet;
00259 }
00260 
00261 std::string MessageDrop::moduleContext() {
00262   return moduleNameProducer->theContext();
00263 }
00264 
00265 void MessageDrop::snapshot() {
00266   const_cast<messagedrop::StringProducer *>(moduleNameProducer)->snapshot();
00267 }
00268 
00269 } // namespace edm
00270 
00271 
00272 unsigned char MessageDrop::messageLoggerScribeIsRunning = 0;