Skip to content

Commit

Permalink
Merge pull request orocos-toolchain#12 into rdt-toolchain-2.9-cherry-…
Browse files Browse the repository at this point in the history
…pick

Merge with upstream version 2017-07-13 08:48
  • Loading branch information
meyerj committed Oct 26, 2017
2 parents 25c5abf + 4bff3f8 commit 30a577a
Show file tree
Hide file tree
Showing 29 changed files with 514 additions and 124 deletions.
10 changes: 10 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
2017-07-13 08:48 sanchouss_
* bug 146;
* bug 147 - Being prepared for Removing Deprecated Exception Specifications from C++17
2016-11-11 18:48 sanchouss_

* Numerous fixes;
* Added .target property for the ConsoleAppender to allow printing to STDERR
* Added method Category::shutdownForced(). It releases more memory than shutdown() by deleting all appenders.
Category::shutdownForced() may be invoked several times, not only at the end of program.

2015-03-28 18:48 sanchouss_

* Added DailyRollingFileAppender.cpp
Expand Down
27 changes: 20 additions & 7 deletions doc/html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ <h5>How to use</h5>
</ul>
<h5>Development</h5>
<ul>
<li><a title="CVS Repository" href="#cvs">CVS
<li><a title="Git Repository" href="#git">Git
Repository</a> </li>
<li><a title="Releases" href="#releases">Releases</a>
</li>
Expand Down Expand Up @@ -561,14 +561,18 @@ <h2><a id="propfile">Properties file example</a></h2>
</div>

<div class="chapter">
<h2><a id="cvs">CVS Repository</a></h2>
<p>Log4cpp is also available directly through CVS, see the <a href="http://sourceforge.net/cvs/?group_id=15190">SourceForge CVS page</a> for instructions.
CVS currently has two branches:
<h2><a id="git">Git Repository</a></h2>
<p>
log4cpp is moved to git <a href="https://sourceforge.net/p/log4cpp/codegit/">SourceForge Git page</a> since version 1.1.1, cvs is stale now.
</p>
<p></p><table>
<p>Log4cpp of older versions is also available through CVS, see the <a href="https://sourceforge.net/p/log4cpp/code/">SourceForge CVS page</a> for instructions.</p>
<small>
CVS had two branches:
<table>
<tbody><tr><td>MAIN</td><td>for log4cpp development</td></tr>
<tr><td>BRANCH_MAINT_0_2</td><td>for maintainance of log4cpp-stable (0.2.x)</td></tr>
</tbody></table><br>
</small>
Each release will receive a tag named REL_x_y_z.
<p></p>
<p>To start working with a freshly checked out log4cpp revision, run <b>./autogen.sh</b>
Expand All @@ -584,6 +588,14 @@ <h2><a id="releases">Releases</a></h2>
WARNING: releases from the development branch are a 'work in progress' and may fail to build, crash or redecorate your desktop.
</p>
<small>

<dl>
<dt>1.1.2 - master branch (18 April 2017)</dt>
<dd>Fixed memory leak after Category::shutdown() called: method Category::shutdownForced() releases memory allocated for appenders.</dd>
<dd>PropertyConfiguratorImpl: add target property to allow printing to STDERR.</dd>
<dd>Some fixes.</dd>
</dl>

<dl>
<dt>1.1.2rc1 - master branch (04 April 2015)</dt>
<dd>Small fixes, DailyRollingFile appender, tests, options to disable support for smtp and syslog</dd>
Expand Down Expand Up @@ -711,7 +723,7 @@ <h2><a id="releases">Releases</a></h2>

<div class="chapter">
<h2><a id="status">Status</a></h2>
<p>The latest stable release is 1.1.1</p>
<p>The latest stable release is 1.1.2</p>
<small>
<p>log4cpp is moved to git since version 1.1.1, cvs is stale since then</p>
<p>As of version 0.3.0 log4cpp has a separate 'stable' and 'development' branches.
Expand Down Expand Up @@ -783,4 +795,5 @@ <h2><a id="id">Chapter</a></h2>
</div>
</div>
</div>
</body></html>
</body></html>

27 changes: 23 additions & 4 deletions include/log4cpp/Appender.hh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <string>
#include <map>
#include <set>
#include <vector>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
Expand All @@ -31,6 +32,7 @@ namespace log4cpp {
* statements.
**/
class LOG4CPP_EXPORT Appender {
friend class Category;
public:

/**
Expand Down Expand Up @@ -130,21 +132,38 @@ namespace log4cpp {
**/
virtual Filter* getFilter() = 0;

private:
private:
typedef std::map<std::string, Appender*> AppenderMap;

static AppenderMap* _allAppenders;
static threading::Mutex _appenderMapMutex;

static AppenderMap& _getAllAppenders();
static void _deleteAllAppenders();
static void _deleteAllAppendersWOLock(std::vector<Appender*> &appenders);
static void _addAppender(Appender* appender);
static void _removeAppender(Appender* appender);

const std::string _name;

public:
class AppenderMapStorage {
public:
Appender::AppenderMap* _allAppenders; // single shared instance, nifty-counter defensed
threading::Mutex _appenderMapMutex; // mutex protecting map from multiple thread access

AppenderMapStorage();
~AppenderMapStorage();
};
class LOG4CPP_EXPORT AppenderMapStorageInitializer {
public:
AppenderMapStorageInitializer();
~AppenderMapStorageInitializer();
};
private:
static AppenderMapStorage &_appenderMapStorageInstance;
};

static Appender::AppenderMapStorageInitializer appenderMapStorageInitializer; // static initializer for every translation unit
typedef std::set<Appender *> AppenderSet;

}

#endif // _LOG4CPP_APPENDER_HH
12 changes: 8 additions & 4 deletions include/log4cpp/Category.hh
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ namespace log4cpp {
static void shutdown();

/**
* This method will remove all Appenders from Categories.XXX and delete all appenders.
* Releases more memory than shutdown() by deleting appenders.
**/
static void shutdownForced();

/**
* Destructor for Category.
**/
virtual ~Category();
Expand All @@ -112,8 +118,7 @@ namespace log4cpp {
* @exception std::invalid_argument if the caller tries to set
* Priority::NOTSET on the Root Category.
**/
virtual void setPriority(Priority::Value priority)
throw(std::invalid_argument);
virtual void setPriority(Priority::Value priority);

/**
* Returns the assigned Priority, if any, for this Category.
Expand Down Expand Up @@ -146,8 +151,7 @@ namespace log4cpp {
* @param appender The Appender to wich this category has to log.
* @exception std::invalid_argument if the appender is NULL.
**/
virtual void addAppender(Appender* appender)
throw(std::invalid_argument);
virtual void addAppender(Appender* appender);

/**
* Adds an Appender for this Category.
Expand Down
3 changes: 1 addition & 2 deletions include/log4cpp/PatternLayout.hh
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,7 @@ namespace log4cpp {
* @param conversionPattern the conversion pattern
* @exception ConfigureFailure if the pattern is invalid
**/
virtual void setConversionPattern(const std::string& conversionPattern)
throw(ConfigureFailure);
virtual void setConversionPattern(const std::string& conversionPattern);

virtual std::string getConversionPattern() const;

Expand Down
16 changes: 16 additions & 0 deletions include/log4cpp/Portability.hh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@
# else
# include <log4cpp/config-win32.h>
# endif

#ifdef MSVC_MEMORY_LEAK_CHECK
#define _CRTDBG_MAP_ALLOC

#include <stdlib.h>
#include <crtdbg.h>

#ifdef _DEBUG
#ifndef DBG_NEW
#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
#define new DBG_NEW
#endif
#endif // _DEBUG
#endif // MSVC_MEMORY_LEAK_CHECK

#else
#if defined(__OPENVMS__)
# include <log4cpp/config-openvms.h>
Expand Down Expand Up @@ -50,4 +65,5 @@
# endif // LOG4CPP_HAVE_SSTREAM
#endif // _APPLE_


#endif
3 changes: 1 addition & 2 deletions include/log4cpp/Priority.hh
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,7 @@ namespace log4cpp {
* @throw std::invalid_argument if the priorityName does not
* correspond with a known Priority name or a number
**/
static Value getPriorityValue(const std::string& priorityName)
throw(std::invalid_argument);
static Value getPriorityValue(const std::string& priorityName);
};
}

Expand Down
8 changes: 7 additions & 1 deletion include/log4cpp/PropertyConfigurator.hh
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,13 @@ namespace log4cpp {
**/
class LOG4CPP_EXPORT PropertyConfigurator {
public:
static void configure(const std::string& initFileName) throw (ConfigureFailure);
/**
*
* @param initFileName
* @exception ConfigureFailure if the method encountered a read or
* syntax error.
*/
static void configure(const std::string& initFileName);
};
}

Expand Down
5 changes: 3 additions & 2 deletions include/log4cpp/SimpleConfigurator.hh
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace log4cpp {
* @exception ConfigureFailure if the method encountered a read or
* syntax error.
**/
static void configure(const std::string& initFileName) throw (ConfigureFailure);
static void configure(const std::string& initFileName);

/**
* Configure log4cpp with the configuration in the given file.
Expand All @@ -45,7 +45,8 @@ namespace log4cpp {
* @exception ConfigureFailure if the method encountered a read or
* syntax error.
**/
static void configure(std::istream& initFile) throw (ConfigureFailure); };
static void configure(std::istream& initFile);
};
}

#endif
76 changes: 58 additions & 18 deletions src/Appender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,42 +9,66 @@

#include "PortabilityImpl.hh"
#include <log4cpp/Appender.hh>
#include <iostream>

namespace log4cpp {
Appender::AppenderMap* Appender::_allAppenders = 0;
threading::Mutex Appender::_appenderMapMutex;
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() {
if (!_allAppenders)
_allAppenders = new Appender::AppenderMap();

return *_allAppenders;
return *_appenderMapStorageInstance._allAppenders;
}

Appender* Appender::getAppender(const std::string& name) {
threading::ScopedLock lock(_appenderMapMutex);
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(_appenderMapMutex);
threading::ScopedLock lock(_appenderMapStorageInstance._appenderMapMutex);
_getAllAppenders()[appender->getName()] = appender;
}

void Appender::_removeAppender(Appender* appender) {
threading::ScopedLock lock(_appenderMapMutex);
threading::ScopedLock lock(_appenderMapStorageInstance._appenderMapMutex);
//private called from destructor only, but may be triggered by client code in several treads
_getAllAppenders().erase(appender->getName());
if(_getAllAppenders().size() == 0) {
delete _allAppenders; _allAppenders = 0; // fix for #2940452
}
}

bool Appender::reopenAll() {
threading::ScopedLock lock(_appenderMapMutex);
threading::ScopedLock lock(_appenderMapStorageInstance._appenderMapMutex);
bool result = true;
AppenderMap& allAppenders = _getAllAppenders();
for(AppenderMap::iterator i = allAppenders.begin(); i != allAppenders.end(); i++) {
Expand All @@ -55,19 +79,35 @@ namespace log4cpp {
}

void Appender::closeAll() {
threading::ScopedLock lock(_appenderMapMutex);
threading::ScopedLock lock(_appenderMapStorageInstance._appenderMapMutex);
AppenderMap& allAppenders = _getAllAppenders();
for(AppenderMap::iterator i = allAppenders.begin(); i != allAppenders.end(); i++) {
((*i).second)->close();
}
}

void Appender::_deleteAllAppenders() {
threading::ScopedLock lock(_appenderMapMutex);
// 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(AppenderMap::iterator i = allAppenders.begin(); i != allAppenders.end(); ) {
Appender *app = (*i).second;
i++; // increment iterator before delete or iterator will be invalid.
for(std::vector<Appender*>::iterator i = appenders.begin(); i != appenders.end(); ++i) {
Appender *app = (*i);
delete (app);
}
}
Expand Down
Loading

0 comments on commit 30a577a

Please sign in to comment.