-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathAppender.cpp
More file actions
123 lines (108 loc) · 4.5 KB
/
Appender.cpp
File metadata and controls
123 lines (108 loc) · 4.5 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);
}
}