Skip to content
Snippets Groups Projects
Commit de943f93 authored by Frank Winklmeier's avatar Frank Winklmeier
Browse files

AthenaKernel: delete MsgStreamMember class

`MsgStreamMember` is not thread-safe and superseded by `AthMessaging`.
parent 6b14ab7e
No related merge requests found
// This file's extension implies that it's C, but it's really -*- C++ -*-.
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#ifndef ATHENAKERNEL_MSGSTREAMEMBER_H
#define ATHENAKERNEL_MSGSTREAMEMBER_H 1
/** @file MsgStreamMember.h
* @brief MsgStreamMember is designed to be a data member of a Gaudi component
* that sets up and give access safely and efficiently to a
* MsgStream object
*
* $Id: MsgStreamMember.h,v 1.1 2008-07-14 22:10:14 calaf Exp $
* @author Paolo Calafiura - Atlas collaboration
*/
#include <string>
//strictly speaking this could be in the cxx file, by putting it here we allow
//clients to use MsgStreamMember as a self-contained replacement for MsgStream
#include "GaudiKernel/MsgStream.h"
#include "AthenaKernel/getMessageSvc.h" /* IMessageSvcHolder */
class MsgStream;
namespace Athena {
/** @class MsgStreamMember
* @brief designed to be a data member of a Gaudi component
* that sets up and give access safely and efficiently to a
* MsgStream object. The main advantage over a plain MsgStream
* is that MsgStreamMember can delay the instantiation of the
* MsgStream (and of IMessageSvc) till the last possible moment
* and will manage IMessageSvc ref count for you.
*
*/
class MsgStreamMember {
public:
/// standard constructor (looks like MsgStream's)
/// In
/// We take ownership (addRef) ims here, and release it in the destructor
/// This makes it work with e.g. Algorithm::msgSvc which is propertly
/// released in ~Algorithm. Notice that m_stream is set lazily in get()
/// @param label: the label to be printed by the stream (usually name())
MsgStreamMember(IMessageSvc *ims, const std::string& label) :
m_ims(ims), m_label(label), m_stream(0) {}
/// this constructor will take IMessageSvc* from getMessageSvc()
/// slow, meant to be used from a class without access to IMessageSvc*
/// m_ims and m_stream set lazily in get()
/// @param label: the label to be printed by the stream (usually name())
MsgStreamMember(const std::string& label) :
m_ims(), m_label(label), m_stream(0) {}
/// allows to create the MsgStream immediately
/// @param o: if o is @c Athena::Options::Eager it will create a MsgStream
/// @param label: the label to be printed by the stream (usually name())
/// @c MsgStream instance there and then.
MsgStreamMember(const Options::CreateOptions o, const std::string& label);
MsgStreamMember() : m_ims(), m_label(""), m_stream(0) {}
MsgStreamMember(const MsgStreamMember& rhs) :
m_ims(rhs.m_ims), m_label(rhs.m_label), m_stream(0) {}
MsgStreamMember& operator= (const MsgStreamMember& rhs);
/// we own the stream
~MsgStreamMember();
/// upon first access sets m_ims as needed
MsgStream& get();
private:
IMessageSvcHolder m_ims;
/// the label to be printed by the stream (usually name())
std::string m_label;
MsgStream* m_stream;
};
}
template <typename T>
MsgStream& operator << (Athena::MsgStreamMember& stream, const T& rhs) {
return (stream.get() << rhs);
}
#endif
......@@ -38,11 +38,6 @@ atlas_add_test( getMessageSvc_test
LOG_IGNORE_PATTERN "^Wall clock time"
LINK_LIBRARIES GaudiKernel TestTools AthenaKernel )
atlas_add_test( MsgStreamMember_test
SOURCES test/MsgStreamMember_test.cxx
LOG_IGNORE_PATTERN "^Wall clock time |ref count"
LINK_LIBRARIES TestTools AthenaKernel )
atlas_add_test( DirSearchPath_test
SOURCES test/DirSearchPath_test.cxx
INCLUDE_DIRS ${Boost_INCLUDE_DIRS}
......
ApplicationMgr SUCCESS
====================================================================================================================================
Welcome to ApplicationMgr $Revision: 1.77 $
running on lxplus251.cern.ch on Sat Oct 23 02:26:38 2010
====================================================================================================================================
ApplicationMgr INFO Application Manager Configured successfully
EventLoopMgr WARNING Unable to locate service "EventSelector"
EventLoopMgr WARNING No events will be processed from external input.
HistogramPersis... INFO 'CnvServices':[ 'HbookHistSvc' , 'RootHistSvc' ]
HistogramPersis...WARNING Histograms saving not required.
ApplicationMgr INFO Application Manager Initialized successfully
ApplicationMgr Ready
Initial message svc ref count 11
Mine SUCCESS *** Mine works ***
Yours SUCCESS *** Yours works too ***
Hers SUCCESS *** reporting ***
Foo SUCCESS bla
Foo SUCCESS bla
Foo SUCCESS bla
Foo SUCCESS bla
Foo SUCCESS bla
Foo SUCCESS bla
Foo SUCCESS bla
Foo SUCCESS bla
Foo SUCCESS bla
Foo SUCCESS bla
Wall clock time to create a MsgStreamMember (microsec)4.678
Wall clock time to print bla using MsgStreamMember (microsec)17
Final ref count 1013
*** MsgStreamMember_test OK ***
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
/** @file MsgStreamMember.cxx
* @brief MsgStreamMember implementation
*
* $Id: MsgStreamMember.cxx,v 1.1 2008-07-14 22:10:14 calaf Exp $
* @author Paolo Calafiura - Atlas collaboration
*/
#include "AthenaKernel/MsgStreamMember.h"
using namespace Athena;
/// @param o: if o is @c Athena::Options::Eager it will create a
/// @c MsgStream instance there and then.
MsgStreamMember::MsgStreamMember(const Athena::Options::CreateOptions opt,
const std::string& label) :
m_ims(opt), m_label(label), m_stream (0)
{
if (opt == Athena::Options::Eager) m_stream = new MsgStream(m_ims.get(), m_label);
}
MsgStreamMember& MsgStreamMember::operator= (const MsgStreamMember& rhs)
{
if (this != &rhs) {
m_ims = rhs.m_ims;
m_label = rhs.m_label;
m_stream = 0;
}
return *this;
}
MsgStreamMember::~MsgStreamMember() { delete m_stream; }
/// upon first access sets m_ims as needed
MsgStream& MsgStreamMember::get() {
if (0 == m_stream) m_stream = new MsgStream(m_ims.get(), m_label);
return *m_stream;
}
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
/**
* @file MsgStreamMember_test.cxx
* @brief Example/Regression test for @class Athena::MsgStreamMember
*
* @author Paolo Calafiura
* $Id: MsgStreamMember_test.cxx,v 1.1 2008-07-14 22:10:14 calaf Exp $
*/
#undef NDEBUG
#include <cassert>
#include "TestTools/initGaudi.h"
#include "AthenaKernel/MsgStreamMember.h"
using namespace Athena;
class Mine {
public:
Mine() :
//this is how you would set m_stream in a (data)obj w/o access to IMessageSvc*
m_stream(name()) {}
const std::string& name() const {
static const std::string n("Mine");
return n;
}
void printIt() {
m_stream << MSG::ALWAYS << "*** Mine works ***" <<endmsg;
}
private:
MsgStreamMember m_stream;
};
class Yours {
public:
Yours(IMessageSvc* ims) :
//this would be the typical way to construct m_stream in e.g. a Service
m_stream(ims, name()) {}
const std::string& name() const {
static const std::string n("Yours");
return n;
}
void printIt() {
m_stream << MSG::ALWAYS << "*** Yours works too ***" <<endmsg;
}
private:
Athena::MsgStreamMember m_stream;
};
class Hers {
public:
Hers(IMessageSvc* ims) {
//this would be another (less preferred) way to construct m_stream
m_stream = MsgStreamMember(ims, name());
}
const std::string& name() const {
static const std::string n("Hers");
return n;
}
void printIt() {
m_stream << MSG::ALWAYS << "*** reporting ***" <<endmsg;
}
private:
Athena::MsgStreamMember m_stream;
};
int main() {
ISvcLocator* pDum;
assert( Athena_test::initGaudi(pDum) );
IMessageSvc *pMS(Athena::getMessageSvc());
assert( pMS );
//usual nasty trick to get the ref count
pMS->addRef();
unsigned int refCount(pMS->release());
std::cout << "Initial message svc ref count " << refCount << std::endl;
{
Mine my;
my.printIt();
Yours you(pMS);
Yours alsoYours(you);
alsoYours.printIt();
Hers her(pMS);
her.printIt();
} //my, you, etc destructors called
MsgStreamMember mm(Athena::Options::Eager, "Foo");
longlong t0(System::currentTime(System::microSec));
for (int i=0; i<1000; ++i) MsgStreamMember(Athena::Options::Eager, "Foo");
// pMS->addRef();
// std::cout << "ref count after eager creation " << pMS->release() << std::endl;
longlong t1(System::currentTime(System::microSec));
for (int i=0; i<10; ++i) mm << MSG::ALWAYS << "bla" << endmsg;
longlong t2(System::currentTime(System::microSec));
std::cout << "Wall clock time to create a MsgStreamMember (microsec)" << (t1-t0) * 1e-3 <<std::endl;
std::cout << "Wall clock time to print bla using MsgStreamMember (microsec)" << (t2-t1) * 0.1 <<std::endl;
pMS->addRef();
unsigned int refCountAfter(pMS->release());
std::cout << "Final ref count " << refCountAfter << std::endl;
///FIXME Gaudi bug#74192 assert(refCountAfter == refCount);
std::cout << "*** MsgStreamMember_test OK ***" <<std::endl;
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment