Menu

[2d617b]: / src / Appender.cpp  Maximize  Restore  History

Download this file

124 lines (108 with data), 4.6 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
* Appender.cpp
*
* Copyright 2000, LifeLine Networks BV (www.lifeline.nl). All rights reserved.
* Copyright 2000, Bastiaan Bakker. All rights reserved.
*
* See the COPYING file for the terms of usage and distribution.
*/
#include "PortabilityImpl.hh"
#include <log4cpp/Appender.hh>
#include <iostream>
namespace log4cpp {
static int appenders_nifty_counter; // zero initialized at load time
static char appenderMapStorage_buf[sizeof(Appender::AppenderMapStorage)]; // memory for the nifty-counter singleton object
Appender::AppenderMapStorage &Appender::_appenderMapStorageInstance = reinterpret_cast<Appender::AppenderMapStorage&> (appenderMapStorage_buf); // memory for placement new
Appender::AppenderMapStorage::AppenderMapStorage() {
_allAppenders = new AppenderMap();
}
Appender::AppenderMapStorage::~AppenderMapStorage() {
_deleteAllAppenders();
delete _allAppenders;
}
Appender::AppenderMapStorageInitializer::AppenderMapStorageInitializer() {
if (appenders_nifty_counter++ == 0) {
// MSVC's <crtdbg.h> requires redefinition of the new operator, but could not deal with placement new form of it
#ifdef MSVC_MEMORY_LEAK_CHECK
#pragma push_macro("new")
#define new new
#endif // MSVC_MEMORY_LEAK_CHECK
new (&_appenderMapStorageInstance) AppenderMapStorage(); // placement new
#ifdef MSVC_MEMORY_LEAK_CHECK
#pragma pop_macro("new")
#endif // MSVC_MEMORY_LEAK_CHECK
}
}
Appender::AppenderMapStorageInitializer::~AppenderMapStorageInitializer() {
if (--appenders_nifty_counter == 0) {
(&_appenderMapStorageInstance)->~AppenderMapStorage ();
}
}
/* assume _appenderMapMutex locked */
Appender::AppenderMap& Appender::_getAllAppenders() {
return *_appenderMapStorageInstance._allAppenders;
}
Appender* Appender::getAppender(const std::string& name) {
threading::ScopedLock lock(_appenderMapStorageInstance._appenderMapMutex);
AppenderMap& allAppenders = Appender::_getAllAppenders();
AppenderMap::iterator i = allAppenders.find(name);
return (allAppenders.end() == i) ? NULL : ((*i).second);
}
void Appender::_addAppender(Appender* appender) {
//REQUIRE(_allAppenders.find(appender->getName()) == _getAllAppenders().end())
threading::ScopedLock lock(_appenderMapStorageInstance._appenderMapMutex);
_getAllAppenders()[appender->getName()] = appender;
}
void Appender::_removeAppender(Appender* appender) {
threading::ScopedLock lock(_appenderMapStorageInstance._appenderMapMutex);
//private called from destructor only, but may be triggered by client code in several treads
_getAllAppenders().erase(appender->getName());
}
bool Appender::reopenAll() {
threading::ScopedLock lock(_appenderMapStorageInstance._appenderMapMutex);
bool result = true;
AppenderMap& allAppenders = _getAllAppenders();
for(AppenderMap::iterator i = allAppenders.begin(); i != allAppenders.end(); i++) {
result = result && ((*i).second)->reopen();
}
return result;
}
void Appender::closeAll() {
threading::ScopedLock lock(_appenderMapStorageInstance._appenderMapMutex);
AppenderMap& allAppenders = _getAllAppenders();
for(AppenderMap::iterator i = allAppenders.begin(); i != allAppenders.end(); i++) {
((*i).second)->close();
}
}
void Appender::_deleteAllAppenders() {
// deleting each appenders will cause a lock on Appender::_appenderMapMutex to be obtained again within destructor. to avoid nested locks:
std::vector<Appender*> appenders;
{
threading::ScopedLock lock(_appenderMapStorageInstance._appenderMapMutex);
AppenderMap& allAppenders = _getAllAppenders();
appenders.reserve(allAppenders.size());
for(AppenderMap::iterator i = allAppenders.begin(); i != allAppenders.end(); ) {
Appender* app = (*i).second;
++i;
appenders.push_back(app);
}
allAppenders.clear();
}
_deleteAllAppendersWOLock(appenders);
}
void Appender::_deleteAllAppendersWOLock(std::vector<Appender*> &appenders) {
/* assume Appender::_appenderMapMutex not locked */
AppenderMap& allAppenders = _getAllAppenders();
for(std::vector<Appender*>::iterator i = appenders.begin(); i != appenders.end(); ++i) {
Appender *app = (*i);
delete (app);
}
}
Appender::Appender(const std::string& name) :
_name(name) {
_addAppender(this);
}
Appender::~Appender() {
_removeAppender(this);
}
}
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.