CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/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.12 2010/12/07 22:56:35 fischler 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 using namespace edm;
00047 
00048 edm::Exception * MessageDrop::ex_p = 0;
00049 bool MessageDrop::debugEnabled=true;
00050 bool MessageDrop::infoEnabled=true;
00051 bool MessageDrop::warningEnabled=true;
00052 // The following are false at initialization (in case configure is not done)
00053 // and are set true at the start of configure_ordinary_destinations, 
00054 // but are set false once a destination is thresholded to react to the 
00055 // corresponding severity: 
00056 bool MessageDrop::debugAlwaysSuppressed=false;          // change log 2
00057 bool MessageDrop::infoAlwaysSuppressed=false;           // change log 2
00058 bool MessageDrop::warningAlwaysSuppressed=false;        // change log 2
00059 
00060 MessageDrop *
00061 MessageDrop::instance()
00062 {
00063   static boost::thread_specific_ptr<MessageDrop> drops;
00064   MessageDrop* drop = drops.get();
00065   if(drop==0) { 
00066     drops.reset(new MessageDrop);
00067     drop=drops.get(); 
00068   }
00069   return drop;
00070 }
00071 
00072 namespace edm {
00073 namespace messagedrop {
00074 
00075 class StringProducer {
00076   public:
00077     virtual ~StringProducer() {}
00078     virtual std::string theContext() const = 0;
00079     virtual void snapshot() = 0;
00080 };
00081   
00082 class StringProducerWithPhase : public StringProducer
00083 {
00084   typedef std::map<const void*, std::string>::const_iterator NLMiter;
00085   public:
00086     StringProducerWithPhase() 
00087     : name_initial_value_  (" ")                        // change log 4
00088     , label_initial_value_ (" ")                        
00089     , name_                (&name_initial_value_)
00090     , label_               (&label_initial_value_)
00091     , phasePtr_            ("(Startup)")
00092     , moduleID_            (0)
00093     {}
00094     virtual std::string theContext() const {
00095       if (cache_.empty()) {
00096         if (moduleID_ != 0) {
00097           NLMiter nameLableIter = nameLabelMap_.find(moduleID_);
00098           if  (nameLableIter != nameLabelMap_.end()) {
00099             cache_.assign(nameLableIter->second);
00100             cache_.append(phasePtr_);
00101             return cache_; 
00102           }
00103         }
00104         cache_.assign(*name_);
00105         cache_.append(":");
00106         cache_.append(*label_);
00107         nameLabelMap_[moduleID_] = cache_;
00108         cache_.append(phasePtr_);       
00109       }
00110         return cache_;
00111     }
00112     void set(std::string const & name,
00113              std::string const & label,
00114              const void * moduleID,
00115              const char* phase)  {
00116       name_ = &name;
00117       label_ = &label;     
00118       moduleID_ = moduleID;
00119       phasePtr_ = phase;
00120       cache_.clear();        
00121     } 
00122     virtual void snapshot()                             // change log 5
00123     {
00124       snapshot_name_ = *name_;
00125       name_ = &snapshot_name_;
00126       snapshot_label_ = *label_;
00127       label_ = &snapshot_label_;
00128       if ( snapshot_phase_ != phasePtr_ ) {             // change log 6
00129         std::strncpy (snapshot_phase_,phasePtr_,PHASE_MAX_LENGTH);
00130       }
00131       snapshot_phase_[PHASE_MAX_LENGTH] = 0;
00132       phasePtr_ = snapshot_phase_;
00133     }
00134   private:
00135     static const int PHASE_MAX_LENGTH = 32;
00136     std::string const name_initial_value_;
00137     std::string const label_initial_value_;
00138     std::string const * name_;
00139     std::string const * label_;
00140     const char* phasePtr_;
00141     const void * moduleID_;
00142     mutable std::string cache_;
00143     mutable std::map<const void*, std::string> nameLabelMap_;
00144     std::string snapshot_name_;
00145     std::string snapshot_label_;
00146     char snapshot_phase_[PHASE_MAX_LENGTH+1];
00147 };
00148 
00149 class StringProducerPath : public StringProducer{
00150   public:
00151     StringProducerPath() 
00152     : typePtr_("PathNotYetEstablished")                 // change log 4
00153     , path_ (" ") {}
00154      virtual std::string theContext() const {
00155       if ( cache_.empty() ) {
00156         cache_.assign(typePtr_);
00157         cache_.append(path_);
00158       }
00159       return cache_; 
00160     }
00161     void set(const char* type, std::string const & pathname) {
00162       typePtr_ = type;
00163       path_ = pathname;
00164       cache_.clear();        
00165     } 
00166     virtual void snapshot()                             // change log 5
00167     {
00168       if ( snapshot_type_ != typePtr_ ) {               // change log 6
00169         std::strncpy (snapshot_type_,typePtr_,TYPE_MAX_LENGTH);
00170       }
00171       snapshot_type_[TYPE_MAX_LENGTH] = 0;
00172       typePtr_ = snapshot_type_;
00173     }
00174   private:
00175     static const int TYPE_MAX_LENGTH = 32;
00176     const char* typePtr_;
00177     std::string path_;
00178     mutable std::string cache_;
00179     char snapshot_type_[TYPE_MAX_LENGTH+1];
00180 };
00181   
00182 class StringProducerSinglet : public StringProducer{
00183   public:
00184     StringProducerSinglet() : singlet_("(NoModuleName)") {}
00185     virtual std::string theContext() const {
00186       return singlet_;
00187     }
00188     void set(const char * sing) {singlet_ = sing; } 
00189     virtual void snapshot() 
00190     {
00191       if ( snapshot_singlet_ != singlet_ ) {            // change log 6
00192         std::strncpy (snapshot_singlet_,singlet_,SINGLET_MAX_LENGTH);
00193       }
00194       snapshot_singlet_[SINGLET_MAX_LENGTH] = 0;
00195       singlet_ = snapshot_singlet_;
00196     }
00197   private:
00198     static const int SINGLET_MAX_LENGTH = 32;
00199     const char * singlet_;
00200     char snapshot_singlet_[SINGLET_MAX_LENGTH+1];
00201 };
00202 
00203 } // namespace messagedrop
00204 
00205 MessageDrop::MessageDrop()
00206   : moduleName ("")
00207   , runEvent("pre-events")
00208   , jobreport_name()                                    
00209   , jobMode("")                                         
00210   , spWithPhase(new  messagedrop::StringProducerWithPhase)
00211   , spPath (new messagedrop::StringProducerPath)
00212   , spSinglet (new messagedrop::StringProducerSinglet)
00213   , moduleNameProducer (spSinglet)
00214 { 
00215 } 
00216 
00217 MessageDrop::~MessageDrop()
00218 {
00219   delete spSinglet;
00220   delete spPath;
00221   delete spWithPhase;
00222 }
00223 
00224 void MessageDrop::setModuleWithPhase(std::string const & name,
00225                                      std::string const & label,
00226                                      const void * moduleID,
00227                                      const char* phase) {
00228   spWithPhase->set(name, label, moduleID, phase);
00229   moduleNameProducer = spWithPhase;
00230 }                                    
00231  
00232 void MessageDrop::setPath(const char* type, std::string const & pathname) {
00233   spPath->set(type, pathname);
00234   moduleNameProducer = spPath;
00235 }
00236 
00237 void MessageDrop::setSinglet(const char * sing) {
00238   spSinglet->set(sing);
00239   moduleNameProducer = spSinglet;
00240 }
00241 
00242 std::string MessageDrop::moduleContext() {
00243   return moduleNameProducer->theContext();
00244 }
00245 
00246 void MessageDrop::snapshot() {
00247   const_cast<messagedrop::StringProducer *>(moduleNameProducer)->snapshot();
00248 }
00249 
00250 } // namespace edm
00251 
00252 
00253 unsigned char MessageDrop::messageLoggerScribeIsRunning = 0;