File indexing completed on 2025-01-18 09:57:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #ifndef COMMONMESSAGING_H_
0019 #define COMMONMESSAGING_H_
0020 #include "GaudiKernel/GaudiException.h"
0021 #include "GaudiKernel/IMessageSvc.h"
0022 #include "GaudiKernel/IService.h"
0023 #include "GaudiKernel/ISvcLocator.h"
0024 #include "GaudiKernel/MsgStream.h"
0025 #include "GaudiKernel/SmartIF.h"
0026 #include "GaudiKernel/detected.h"
0027 #include <boost/thread/tss.hpp>
0028
0029 #include <memory>
0030 #include <utility>
0031
0032
0033
0034
0035
0036 #define generate_( method, ret, args ) \
0037 \
0038 template <typename T> \
0039 using _has_##method = decltype( std::declval<const T&>().method args ); \
0040 \
0041 template <typename T> \
0042 using has_##method = Gaudi::cpp17::is_detected<_has_##method, T>; \
0043 \
0044 template <typename Base> \
0045 struct add_##method : public Base { \
0046 using Base::Base; \
0047 virtual ~add_##method() = default; \
0048 virtual ret method args const = 0; \
0049 };
0050
0051 namespace implementation_detail {
0052 generate_( name, const std::string&, () )
0053
0054 generate_( serviceLocator, SmartIF<ISvcLocator>&, () )
0055 }
0056 #undef generate_
0057
0058 template <typename Base>
0059 using add_name =
0060 std::conditional_t<implementation_detail::has_name<Base>::value, Base, implementation_detail::add_name<Base>>;
0061 template <typename Base>
0062 using add_serviceLocator = std::conditional_t<implementation_detail::has_serviceLocator<Base>::value, Base,
0063 implementation_detail::add_serviceLocator<Base>>;
0064
0065 template <typename Base>
0066 class CommonMessaging;
0067
0068 class CommonMessagingBase {
0069 public:
0070
0071 virtual ~CommonMessagingBase() = default;
0072
0073 virtual void create_msgStream() const = 0;
0074
0075
0076
0077
0078 const SmartIF<IMessageSvc>& msgSvc() const { return m_msgsvc; }
0079
0080
0081 MsgStream& msgStream() const {
0082 if ( !m_msgStream.get() ) create_msgStream();
0083 return *m_msgStream;
0084 }
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096 MsgStream& msgStream( const MSG::Level level ) const { return msgStream() << level; }
0097
0098
0099 MsgStream& always() const { return msgStream( MSG::ALWAYS ); }
0100
0101
0102 MsgStream& fatal() const { return msgStream( MSG::FATAL ); }
0103
0104
0105 MsgStream& err() const { return msgStream( MSG::ERROR ); }
0106
0107
0108 MsgStream& error() const { return msgStream( MSG::ERROR ); }
0109
0110
0111 MsgStream& warning() const { return msgStream( MSG::WARNING ); }
0112
0113
0114 MsgStream& info() const { return msgStream( MSG::INFO ); }
0115
0116
0117 MsgStream& debug() const { return msgStream( MSG::DEBUG ); }
0118
0119
0120 MsgStream& verbose() const { return msgStream( MSG::VERBOSE ); }
0121
0122
0123 MsgStream& msg() const { return msgStream( MSG::INFO ); }
0124
0125 private:
0126 template <typename Base>
0127 friend class CommonMessaging;
0128
0129 mutable bool m_commonMessagingReady = false;
0130 mutable MSG::Level m_level = MSG::NIL;
0131
0132
0133 mutable boost::thread_specific_ptr<MsgStream> m_msgStream;
0134
0135
0136 mutable SmartIF<IMessageSvc> m_msgsvc;
0137 };
0138
0139 template <typename BASE>
0140 class GAUDI_API CommonMessaging : public add_serviceLocator<add_name<BASE>>, public CommonMessagingBase {
0141 public:
0142 using base_class = CommonMessaging;
0143
0144
0145 using add_serviceLocator<add_name<BASE>>::add_serviceLocator;
0146
0147
0148 MSG::Level msgLevel() const {
0149 if ( m_commonMessagingReady ) return m_level;
0150 return setUpMessaging();
0151 }
0152
0153
0154 bool msgLevel( MSG::Level lvl ) const { return msgLevel() <= lvl; }
0155
0156 private:
0157
0158 void create_msgStream() const override final { m_msgStream.reset( new MsgStream( msgSvc(), this->name() ) ); }
0159
0160
0161 void initMessaging() const {
0162 if ( !m_msgsvc ) {
0163
0164 m_msgsvc = this->serviceLocator();
0165 }
0166 create_msgStream();
0167 m_level = MSG::Level( m_msgStream.get() ? m_msgStream->level() : MSG::NIL );
0168
0169 m_commonMessagingReady = m_msgsvc;
0170 }
0171
0172 protected:
0173
0174 MSG::Level setUpMessaging() const {
0175 if ( !m_commonMessagingReady ) { initMessaging(); }
0176 return m_level;
0177 }
0178
0179 MSG::Level resetMessaging() {
0180 m_commonMessagingReady = false;
0181 return setUpMessaging();
0182 }
0183
0184
0185 void updateMsgStreamOutputLevel( int level ) {
0186 setUpMessaging();
0187 if ( level != MSG::NIL && level != m_level ) {
0188 if ( msgSvc() ) msgSvc()->setOutputLevel( this->name(), level );
0189 if ( m_msgStream.get() ) m_msgStream->setLevel( level );
0190 if ( MSG::Level( level ) <= MSG::DEBUG )
0191 debug() << "Property update for OutputLevel : new value = " << level << endmsg;
0192 m_level = MSG::Level( level );
0193 }
0194 }
0195 };
0196
0197 #endif