Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 10:00:30

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
0003 *                                                                                   *
0004 * This software is distributed under the terms of the Apache version 2 licence,     *
0005 * copied verbatim in the file "LICENSE".                                            *
0006 *                                                                                   *
0007 * In applying this licence, CERN does not waive the privileges and immunities       *
0008 * granted to it by virtue of its status as an Intergovernmental Organization        *
0009 * or submit itself to any jurisdiction.                                             *
0010 \***********************************************************************************/
0011 #ifndef GAUDIKERNEL_GUARDS_H
0012 #define GAUDIKERNEL_GUARDS_H 1
0013 // ============================================================================
0014 // Include files
0015 // ============================================================================
0016 // STD & STL
0017 // ============================================================================
0018 #include <exception>
0019 // ============================================================================
0020 // GaudiKernel
0021 // ============================================================================
0022 #include "GaudiKernel/IAuditor.h"
0023 #include "GaudiKernel/IExceptionSvc.h"
0024 #include "GaudiKernel/INamedInterface.h"
0025 #include "GaudiKernel/SmartIF.h"
0026 // ============================================================================
0027 // forward declaration
0028 // ============================================================================
0029 class GaudiException;
0030 // ============================================================================
0031 namespace Gaudi {
0032   /** @namespace Gaudi::Guards Guards.h GaudiKernel/Guards.h
0033    *  Collection of very simple classes which allows to
0034    *  execution of some functions within  the given well-defined
0035    *  and exception-safe context.
0036    *  In addition these utilities allow to remove many
0037    *  ugly lines from many ancient base classes
0038    *
0039    *  The namespace contains two simple guards:
0040    *    - class Gaudi::Guards::ExceptionGuard
0041    *    - class Gaudi::Guards::AuditorGuard
0042    *
0043    *  Please note tha the class Gaudi::Utils::AlgContext is also
0044    *   some kind of "guard".
0045    *
0046    *  All these guards could work together in very collaborative way:
0047    *
0048    *  @code
0049    *
0050    *  StatusCode Algorithm::sysInitialize ()
0051    *   {
0052    *    // create the message stream:
0053    *    MsgStream log ( msgSvc() , name() ) ;
0054    *
0055    *    // lock the scope for Auditor Service
0056    *    Gaudi::Guards::AuditorGuard auditor
0057    *           ( this                           ,
0058    *             auditorSvc()                   ,   ///< Auditor Service
0059    *             &IAuditorSvc::beforeInitialize ,   ///< "pre"-action
0060    *             &IAuditorsvc::afterInitialize  ) ; ///< "post"-action
0061    *
0062    *    // Lock the scope for Algorithm Context Service:
0063    *    Gaudi::Utils::AlgContext context ( this , m_contextSvc ) ;
0064    *
0065    *    // execute IAlgorithm::initialize within "try{}catch(..)" clause:
0066    *    Gaudi::Guards::ExceptionGuard guard
0067    *        ( this                                 , ///< OBJECT
0068    *          std::mem_fn(&IAlgorithm::initialize) , ///< FUNCTOR
0069    *          log                                  , ///< STREAM
0070    *          m_exceptionSvc ) ; ///< (optional) Exception Service
0071    *
0072    *    return guard ;  /// return the result of functor evaluation
0073    *   }
0074    *  @endcode
0075    *
0076    *  C++ guarantees the proper execution of all "post"-actions for all
0077    *  involved guards  when the scope is destroyed.
0078    *
0079    *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0080    *  @date   2007-03-07
0081    */
0082   namespace Guards {
0083     /** @class ExceptionGuard Guards.h GaudiKernel/Guards.h
0084      *  The most simple guard - it execute the certain code
0085      *  withing  typical "try {} catch" clause, used in
0086      *  Auditor, Algorithm, AlgTool, etc.. classes
0087      *
0088      *  The usage is fairly trivial:
0089      *
0090      *  @code
0091      *
0092      *  // get the stream:
0093      *  MsgStream& log = ... ;
0094      *
0095      *  // create the guard object and execute this->initialize()
0096      *  // within the  standard "try"-clause:
0097      *  Gaudi::Guards::Guard guard
0098      *          ( this                               ,   ///< OBJECT
0099      *            std::mem_fn(&IAuditor::initialize) ,   ///< FUNCTOR
0100      *            log                                ) ; ///< stream
0101      *
0102      *  // extract the status code"
0103      *  StatusCode sc = guard.code() ;
0104      *
0105      *  @endcode
0106      *
0107      *  The utility could be reused for member-function, regular functions, etc..
0108      *  It could be easily combined with STL-idioms
0109      *  Essentially it required only the semantical validity of the
0110      *  expression "StatusCode sc = fun(obj)"
0111      *
0112      *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0113      *  @date   2007-03-07
0114      */
0115     class GAUDI_API ExceptionGuard {
0116     public:
0117       /* constructor form the object/scope, function and log-stream
0118        * @param obj the object/scope
0119        * @param fun function to be used
0120        * @param log output log-stream
0121        */
0122       template <class OBJECT, class FUNCTION>
0123       ExceptionGuard( OBJECT obj, FUNCTION fun, MsgStream& log, IExceptionSvc* svc = 0 ) {
0124         try {
0125           // execute the functor:
0126           m_sc = fun( obj ); ///< execute the functor
0127           // in the case of error try use Exception Service
0128           if ( svc && m_sc.isFailure() ) { m_sc = svc->handleErr( *obj, m_sc ); }
0129         } catch ( const GaudiException& e ) {
0130           // Use the local handler and then (if possible) the Exception Service
0131           handle( e, log );
0132           if ( svc ) { m_sc = svc->handle( *obj, e ); }
0133         } catch ( const std::exception& e ) {
0134           // Use the local handler and then (if possible) the Exception Service
0135           handle( e, log );
0136           if ( svc ) { m_sc = svc->handle( *obj, e ); }
0137         } catch ( ... ) {
0138           // Use the local handler and then (if possible) the Exception Service
0139           handle( log );
0140           if ( svc ) { m_sc = svc->handle( *obj ); }
0141         }
0142       }
0143       /// destructor
0144       ~ExceptionGuard();
0145 
0146     public:
0147       /// the result of function evaluation
0148       const StatusCode& code() const { return m_sc; }
0149       /// cast operator, useful for the implicit conversions
0150       operator const StatusCode&() const { return code(); }
0151 
0152     private:
0153       // delete default/copy constructor and assignment
0154       ExceptionGuard()                                   = delete;
0155       ExceptionGuard( const ExceptionGuard& )            = delete;
0156       ExceptionGuard& operator=( const ExceptionGuard& ) = delete;
0157 
0158     protected:
0159       /// local handler of GaudiException
0160       void handle( const GaudiException& e, MsgStream& s );
0161       /// local handler of std::exception
0162       void handle( const std::exception& e, MsgStream& s );
0163       /// local handler of UNKNOWN exceptions
0164       void handle( MsgStream& s );
0165 
0166     private:
0167       // status code: result of the function evaluation
0168       StatusCode m_sc = StatusCode::FAILURE; ///< status code : result of function evaluation
0169     };
0170     // ========================================================================
0171     /** @class AuditorGuard Guards.h GaudiKernel/Guards.h
0172      *  It is a simple guard,
0173      *  which "locks" the scope for the Auditor Service
0174      *  is am exception-safe way
0175      *
0176      *  The pattern ensures that "post-action" will be always executed
0177      *
0178      *  @code
0179      *
0180      *  StatusCode Algorithm::sysInitialize ()
0181      *   {
0182      *      AuditorGuard auditor ( this ,
0183      *        auditSvc()                ,   ///< pointer to Auditor Service
0184      *        IAuditor::Initialize      ) ; ///< event to audit
0185      *      ...
0186      *      StatusCode sc = ... ;
0187      *      ...
0188      *      return sc ;                  ///< RETURN
0189      *   }
0190      *
0191      *  @endcode
0192      *
0193      *  @code
0194      *
0195      *  StatusCode Algorithm::sysExecute ()
0196      *   {
0197      *      AuditorGuard auditor ( this       ,
0198      *        auditSvc()                      ,   ///< pointer to Auditor Service
0199      *        IAuditor::execute               ) ; ///< event to audit
0200      *      ...
0201      *      StatusCode sc = ... ;
0202      *      ...
0203      *      auditor.setCode ( sc ) ;
0204      *      ...
0205      *      return sc ;                  ///< RETURN
0206      *   }
0207      *
0208      *  @endcode
0209      *
0210      *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0211      *  @date 2007-03-07
0212      */
0213     class GAUDI_API AuditorGuard final {
0214     public:
0215       /// constructor
0216       AuditorGuard( INamedInterface* obj, IAuditor* svc, IAuditor::StandardEventType evt );
0217       /// constructor
0218       AuditorGuard( INamedInterface* obj, IAuditor* svc, IAuditor::CustomEventTypeRef evt );
0219 
0220       /// constructor
0221       AuditorGuard( INamedInterface* obj, IAuditor* svc, IAuditor::StandardEventType evt, const StatusCode& sc );
0222       /// constructor
0223       AuditorGuard( INamedInterface* obj, IAuditor* svc, IAuditor::CustomEventTypeRef evt, const StatusCode& sc );
0224       /// constructor
0225       AuditorGuard( std::string name, IAuditor* svc, IAuditor::StandardEventType evt );
0226       /// constructor
0227       AuditorGuard( std::string name, IAuditor* svc, IAuditor::CustomEventTypeRef evt );
0228 
0229       /// constructor
0230       AuditorGuard( std::string name, IAuditor* svc, IAuditor::StandardEventType evt, const StatusCode& sc );
0231       /// constructor
0232       AuditorGuard( std::string name, IAuditor* svc, IAuditor::CustomEventTypeRef evt, const StatusCode& sc );
0233 
0234       /// dectructor
0235       ~AuditorGuard();
0236 
0237     public:
0238       // get the status code
0239       const StatusCode& code() const { return *m_sc; }
0240 
0241     private:
0242       // delete the default/copy constructor and assigment
0243       AuditorGuard()                                       = delete;
0244       AuditorGuard( const AuditorGuard& right )            = delete;
0245       AuditorGuard& operator=( const AuditorGuard& right ) = delete;
0246 
0247     private:
0248       /// the guarded object
0249       INamedInterface* m_obj = nullptr;
0250       /// the guarded object name (if there is no INamedInterface)
0251       std::string m_objName;
0252       /// auditor service
0253       SmartIF<IAuditor> m_svc = nullptr;
0254       /// Event type (standard events)
0255       IAuditor::StandardEventType m_evt;
0256       /// Event type (custom events)
0257       IAuditor::CustomEventType m_cevt;
0258       /// Pointer to a status code instance, to be passed to the "after" function if needed
0259       /// The instance must have a scope larger than the one of the guard.
0260       /// No check is performed.
0261       const StatusCode* m_sc = nullptr;
0262       /// Flag to remember which event type was used.
0263       bool m_customEvtType = false;
0264 
0265       inline void i_before() {
0266         if ( m_svc ) { // if the service is not available, we cannot do anything
0267           if ( m_obj ) {
0268             if ( m_customEvtType ) {
0269               m_svc->before( m_cevt, m_obj );
0270             } else {
0271               m_svc->before( m_evt, m_obj );
0272             }
0273           } else { // use object name
0274             if ( m_customEvtType ) {
0275               m_svc->before( m_cevt, m_objName );
0276             } else {
0277               m_svc->before( m_evt, m_objName );
0278             }
0279           }
0280         }
0281       }
0282 
0283       inline void i_after() {
0284         if ( m_svc ) { // if the service is not available, we cannot do anything
0285           if ( m_obj ) {
0286             if ( m_customEvtType ) {
0287               if ( m_sc ) {
0288                 m_svc->after( m_cevt, m_obj, *m_sc );
0289               } else {
0290                 m_svc->after( m_cevt, m_obj );
0291               }
0292             } else {
0293               if ( m_sc ) {
0294                 m_svc->after( m_evt, m_obj, *m_sc );
0295               } else {
0296                 m_svc->after( m_evt, m_obj );
0297               }
0298             }
0299           } else { // use object name
0300             if ( m_customEvtType ) {
0301               if ( m_sc ) {
0302                 m_svc->after( m_cevt, m_objName, *m_sc );
0303               } else {
0304                 m_svc->after( m_cevt, m_objName );
0305               }
0306             } else {
0307               if ( m_sc ) {
0308                 m_svc->after( m_evt, m_objName, *m_sc );
0309               } else {
0310                 m_svc->after( m_evt, m_objName );
0311               }
0312             }
0313           }
0314           m_svc.reset();
0315         }
0316       }
0317     };
0318   } // namespace Guards
0319 } // end of namespace Gaudi
0320 
0321 // ============================================================================
0322 // The END
0323 // ============================================================================
0324 #endif // GAUDIKERNEL_GUARDS_H