You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rm...@apache.org on 2022/10/18 02:11:33 UTC

[logging-log4cxx] 03/03: Broke out the multiprocess part of the rollingfileappender into a separate class

This is an automated email from the ASF dual-hosted git repository.

rmiddleton pushed a commit to branch LOGCXX-518
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git

commit f4efd85deeafed466f8cbecdcc913e37facde146
Author: Robert Middleton <ro...@rm5248.com>
AuthorDate: Sun Oct 16 12:29:35 2022 -0400

    Broke out the multiprocess part of the rollingfileappender into a separate class
---
 src/main/cpp/CMakeLists.txt                        |   1 +
 src/main/cpp/fileoutputstream.cpp                  |   4 +
 ...der.cpp => multiprocessrollingfileappender.cpp} | 120 ++++++------
 src/main/cpp/outputstream.cpp                      |  12 --
 src/main/cpp/outputstreamwriter.cpp                |   3 +-
 src/main/cpp/rollingfileappender.cpp               | 201 --------------------
 src/main/cpp/rollingpolicybase.cpp                 |   5 +-
 src/main/cpp/timebasedrollingpolicy.cpp            | 206 +++++++++++----------
 src/main/cpp/writer.cpp                            |   8 +-
 src/main/cpp/writerappender.cpp                    |   4 +
 .../include/log4cxx/helpers/fileoutputstream.h     |   8 +-
 src/main/include/log4cxx/helpers/outputstream.h    |   7 -
 .../include/log4cxx/helpers/outputstreamwriter.h   |   2 +-
 src/main/include/log4cxx/helpers/writer.h          |   3 -
 ...keleton.h => multiprocessrollingfileappender.h} |  68 +++----
 .../include/log4cxx/rolling/rollingfileappender.h  |  22 ---
 .../include/log4cxx/rolling/rollingpolicybase.h    |  10 +-
 .../log4cxx/rolling/timebasedrollingpolicy.h       |  67 +++----
 src/main/include/log4cxx/writerappender.h          |   8 +-
 19 files changed, 242 insertions(+), 517 deletions(-)

diff --git a/src/main/cpp/CMakeLists.txt b/src/main/cpp/CMakeLists.txt
index 62080106..8837f1da 100644
--- a/src/main/cpp/CMakeLists.txt
+++ b/src/main/cpp/CMakeLists.txt
@@ -128,6 +128,7 @@ target_sources(log4cxx
   messagebuffer.cpp
   messagepatternconverter.cpp
   methodlocationpatternconverter.cpp
+  multiprocessrollingfileappender.cpp
   nameabbreviator.cpp
   namepatternconverter.cpp
   ndc.cpp
diff --git a/src/main/cpp/fileoutputstream.cpp b/src/main/cpp/fileoutputstream.cpp
index a55e6adc..dcfe8384 100644
--- a/src/main/cpp/fileoutputstream.cpp
+++ b/src/main/cpp/fileoutputstream.cpp
@@ -133,3 +133,7 @@ void FileOutputStream::write(ByteBuffer& buf, Pool& /* p */ )
 	}
 }
 
+apr_file_t* FileOutputStream::getFilePtr() const{
+	return m_priv->fileptr;
+}
+
diff --git a/src/main/cpp/rollingfileappender.cpp b/src/main/cpp/multiprocessrollingfileappender.cpp
similarity index 83%
copy from src/main/cpp/rollingfileappender.cpp
copy to src/main/cpp/multiprocessrollingfileappender.cpp
index 03205071..5185ab67 100644
--- a/src/main/cpp/rollingfileappender.cpp
+++ b/src/main/cpp/multiprocessrollingfileappender.cpp
@@ -19,20 +19,19 @@
 	#pragma warning ( disable: 4231 4251 4275 4786 )
 #endif
 
-#ifdef LOG4CXX_MULTI_PROCESS
-	#include <apr_portable.h>
-	#include <libgen.h>
-	#include <apr_file_io.h>
-	#include <apr_atomic.h>
-	#include <apr_mmap.h>
-	#ifndef MAX_FILE_LEN
-		#define MAX_FILE_LEN 2048
-	#endif
-	#include <log4cxx/pattern/filedatepatternconverter.h>
-	#include <log4cxx/helpers/date.h>
+
+#include <apr_portable.h>
+#include <libgen.h>
+#include <apr_file_io.h>
+#include <apr_atomic.h>
+#include <apr_mmap.h>
+#ifndef MAX_FILE_LEN
+	#define MAX_FILE_LEN 2048
 #endif
+#include <log4cxx/pattern/filedatepatternconverter.h>
+#include <log4cxx/helpers/date.h>
 
-#include <log4cxx/rolling/rollingfileappender.h>
+#include <log4cxx/rolling/multiprocessrollingfileappender.h>
 #include <log4cxx/helpers/loglog.h>
 #include <log4cxx/rolling/rolloverdescription.h>
 #include <log4cxx/helpers/fileoutputstream.h>
@@ -48,9 +47,9 @@ using namespace log4cxx::rolling;
 using namespace log4cxx::helpers;
 using namespace log4cxx::spi;
 
-struct RollingFileAppender::RollingFileAppenderPriv : public FileAppenderPriv
+struct MultiprocessRollingFileAppender::MultiprocessRollingFileAppenderPriv : public FileAppenderPriv
 {
-	RollingFileAppenderPriv() :
+	MultiprocessRollingFileAppenderPriv() :
 		FileAppenderPriv(),
 		fileLength(0) {}
 
@@ -75,23 +74,23 @@ struct RollingFileAppender::RollingFileAppenderPriv : public FileAppenderPriv
 	spi::LoggingEventPtr _event;
 };
 
-#define _priv static_cast<RollingFileAppenderPriv*>(m_priv.get())
+#define _priv static_cast<MultiprocessRollingFileAppenderPriv*>(m_priv.get())
 
-IMPLEMENT_LOG4CXX_OBJECT(RollingFileAppender)
+IMPLEMENT_LOG4CXX_OBJECT(MultiprocessRollingFileAppender)
 
 
 /**
  * Construct a new instance.
  */
-RollingFileAppender::RollingFileAppender() :
-	FileAppender (std::make_unique<RollingFileAppenderPriv>())
+MultiprocessRollingFileAppender::MultiprocessRollingFileAppender() :
+	FileAppender (std::make_unique<MultiprocessRollingFileAppenderPriv>())
 {
 }
 
 /**
  * Prepare instance of use.
  */
-void RollingFileAppender::activateOptions(Pool& p)
+void MultiprocessRollingFileAppender::activateOptions(Pool& p)
 {
 	if (_priv->rollingPolicy == NULL)
 	{
@@ -174,8 +173,7 @@ void RollingFileAppender::activateOptions(Pool& p)
 	}
 }
 
-#ifdef LOG4CXX_MULTI_PROCESS
-void RollingFileAppenderSkeleton::releaseFileLock(apr_file_t* lock_file)
+void MultiprocessRollingFileAppender::releaseFileLock(apr_file_t* lock_file)
 {
 	if (lock_file)
 	{
@@ -190,7 +188,7 @@ void RollingFileAppenderSkeleton::releaseFileLock(apr_file_t* lock_file)
 		lock_file = NULL;
 	}
 }
-#endif
+
 /**
    Implements the usual roll over behaviour.
 
@@ -206,13 +204,13 @@ void RollingFileAppenderSkeleton::releaseFileLock(apr_file_t* lock_file)
 
  * @return true if rollover performed.
  */
-bool RollingFileAppender::rollover(Pool& p)
+bool MultiprocessRollingFileAppender::rollover(Pool& p)
 {
 	std::lock_guard<std::recursive_mutex> lock(_priv->mutex);
 	return rolloverInternal(p);
 }
 
-bool RollingFileAppender::rolloverInternal(Pool& p)
+bool MultiprocessRollingFileAppender::rolloverInternal(Pool& p)
 {
 	//
 	//   can't roll without a policy
@@ -221,10 +219,8 @@ bool RollingFileAppender::rolloverInternal(Pool& p)
 	{
 
 		{
-
-#ifdef LOG4CXX_MULTI_PROCESS
 			std::string fileName(getFile());
-			RollingPolicyBase* basePolicy = dynamic_cast<RollingPolicyBase* >(&(*rollingPolicy));
+			RollingPolicyBasePtr basePolicy = log4cxx::cast<RollingPolicyBase>(_priv->rollingPolicy);
 			apr_time_t n = apr_time_now();
 			ObjectPtr obj = std::make_shared<Date>(n);
 			LogString fileNamePattern;
@@ -246,7 +242,7 @@ bool RollingFileAppender::rolloverInternal(Pool& p)
 			memcpy(szBaseName, fileName.c_str(), fileName.size() > MAX_FILE_LEN ? MAX_FILE_LEN : fileName.size());
 			apr_uid_t uid;
 			apr_gid_t groupid;
-			apr_status_t stat = apr_uid_current(&uid, &groupid, pool.getAPRPool());
+			apr_status_t stat = apr_uid_current(&uid, &groupid, p.getAPRPool());
 
 			if (stat == APR_SUCCESS)
 			{
@@ -278,9 +274,9 @@ bool RollingFileAppender::rolloverInternal(Pool& p)
 				}
 				else
 				{
-					if (_event)
+					if (_priv->_event)
 					{
-						triggeringPolicy->isTriggeringEvent(this, *_event, getFile(), getFileLength());
+						_priv->triggeringPolicy->isTriggeringEvent(this, _priv->_event, getFile(), getFileLength());
 					}
 				}
 			}
@@ -289,7 +285,13 @@ bool RollingFileAppender::rolloverInternal(Pool& p)
 			{
 				apr_finfo_t finfo1, finfo2;
 				apr_status_t st1, st2;
-				apr_file_t* _fd = getWriter()->getOutPutStreamPtr()->getFileOutPutStreamPtr().getFilePtr();
+				const WriterPtr writer = getWriter();
+				const FileOutputStreamPtr fos = log4cxx::cast<FileOutputStream>( writer );
+				if( !fos ){
+					LogLog::error( "Can't cast writer to FileOutputStream" );
+					return false;
+				}
+				apr_file_t* _fd = fos->getFilePtr();
 				st1 = apr_file_info_get(&finfo1, APR_FINFO_IDENT, _fd);
 
 				if (st1 != APR_SUCCESS)
@@ -310,7 +312,6 @@ bool RollingFileAppender::rolloverInternal(Pool& p)
 
 			if (!bAlreadyRolled)
 			{
-#endif
 
 				try
 				{
@@ -427,9 +428,7 @@ bool RollingFileAppender::rolloverInternal(Pool& p)
 							writeHeader(p);
 						}
 
-#ifdef LOG4CXX_MULTI_PROCESS
 						releaseFileLock(lock_file);
-#endif
 						return true;
 					}
 				}
@@ -441,7 +440,6 @@ bool RollingFileAppender::rolloverInternal(Pool& p)
 					_priv->errorHandler->error(exmsg, ex, 0);
 				}
 
-#ifdef LOG4CXX_MULTI_PROCESS
 			}
 			else
 			{
@@ -449,34 +447,31 @@ bool RollingFileAppender::rolloverInternal(Pool& p)
 			}
 
 			releaseFileLock(lock_file);
-#endif
 		}
 	}
 
 	return false;
 }
 
-#ifdef LOG4CXX_MULTI_PROCESS
 /**
  * re-open current file when its own handler has been renamed
  */
-void RollingFileAppenderSkeleton::reopenLatestFile(Pool& p)
+void MultiprocessRollingFileAppender::reopenLatestFile(Pool& p)
 {
 	closeWriter();
-	OutputStreamPtr os = std::make_shared<FileOutputStream(getFile>(), true);
+	OutputStreamPtr os = std::make_shared<FileOutputStream>(getFile(), true);
 	WriterPtr newWriter(createWriter(os));
 	setFile(getFile());
 	setWriter(newWriter);
-	fileLength = File().setPath(getFile()).length(p);
+	_priv->fileLength = File().setPath(getFile()).length(p);
 	writeHeader(p);
 }
 
-#endif
 
 /**
  * {@inheritDoc}
 */
-void RollingFileAppender::subAppend(const LoggingEventPtr& event, Pool& p)
+void MultiprocessRollingFileAppender::subAppend(const LoggingEventPtr& event, Pool& p)
 {
 	// The rollover check must precede actual writing. This is the
 	// only correct behavior for time driven triggers.
@@ -503,12 +498,17 @@ void RollingFileAppender::subAppend(const LoggingEventPtr& event, Pool& p)
 		}
 	}
 
-#ifdef LOG4CXX_MULTI_PROCESS
 	//do re-check before every write
 	//
 	apr_finfo_t finfo1, finfo2;
 	apr_status_t st1, st2;
-	apr_file_t* _fd = getWriter()->getOutPutStreamPtr()->getFileOutPutStreamPtr().getFilePtr();
+	const WriterPtr writer = getWriter();
+	const FileOutputStreamPtr fos = log4cxx::cast<FileOutputStream>( writer );
+	if( !fos ){
+		LogLog::error( "Can't cast writer to FileOutputStream" );
+		return;
+	}
+	apr_file_t* _fd = fos->getFilePtr();
 	st1 = apr_file_info_get(&finfo1, APR_FINFO_IDENT, _fd);
 
 	if (st1 != APR_SUCCESS)
@@ -532,8 +532,6 @@ void RollingFileAppender::subAppend(const LoggingEventPtr& event, Pool& p)
 		reopenLatestFile(p);
 	}
 
-#endif
-
 	FileAppender::subAppend(event, p);
 }
 
@@ -541,7 +539,7 @@ void RollingFileAppender::subAppend(const LoggingEventPtr& event, Pool& p)
  * Get rolling policy.
  * @return rolling policy.
  */
-RollingPolicyPtr RollingFileAppender::getRollingPolicy() const
+RollingPolicyPtr MultiprocessRollingFileAppender::getRollingPolicy() const
 {
 	return _priv->rollingPolicy;
 }
@@ -550,7 +548,7 @@ RollingPolicyPtr RollingFileAppender::getRollingPolicy() const
  * Get triggering policy.
  * @return triggering policy.
  */
-TriggeringPolicyPtr RollingFileAppender::getTriggeringPolicy() const
+TriggeringPolicyPtr MultiprocessRollingFileAppender::getTriggeringPolicy() const
 {
 	return _priv->triggeringPolicy;
 }
@@ -559,7 +557,7 @@ TriggeringPolicyPtr RollingFileAppender::getTriggeringPolicy() const
  * Sets the rolling policy.
  * @param policy rolling policy.
  */
-void RollingFileAppender::setRollingPolicy(const RollingPolicyPtr& policy)
+void MultiprocessRollingFileAppender::setRollingPolicy(const RollingPolicyPtr& policy)
 {
 	_priv->rollingPolicy = policy;
 }
@@ -568,7 +566,7 @@ void RollingFileAppender::setRollingPolicy(const RollingPolicyPtr& policy)
  * Set triggering policy.
  * @param policy triggering policy.
  */
-void RollingFileAppender::setTriggeringPolicy(const TriggeringPolicyPtr& policy)
+void MultiprocessRollingFileAppender::setTriggeringPolicy(const TriggeringPolicyPtr& policy)
 {
 	_priv->triggeringPolicy = policy;
 }
@@ -576,7 +574,7 @@ void RollingFileAppender::setTriggeringPolicy(const TriggeringPolicyPtr& policy)
 /**
  * Close appender.  Waits for any asynchronous file compression actions to be completed.
  */
-void RollingFileAppender::close()
+void MultiprocessRollingFileAppender::close()
 {
 	FileAppender::close();
 }
@@ -600,7 +598,7 @@ class CountingOutputStream : public OutputStream
 		/**
 		 * Rolling file appender to inform of stream writes.
 		 */
-		RollingFileAppender* rfa;
+		MultiprocessRollingFileAppender* rfa;
 
 	public:
 		/**
@@ -609,7 +607,7 @@ class CountingOutputStream : public OutputStream
 		 * @param rfa rolling file appender to inform.
 		 */
 		CountingOutputStream(
-			OutputStreamPtr& os1, RollingFileAppender* rfa1) :
+			OutputStreamPtr& os1, MultiprocessRollingFileAppender* rfa1) :
 			os(os1), rfa(rfa1)
 		{
 		}
@@ -640,20 +638,14 @@ class CountingOutputStream : public OutputStream
 
 			if (rfa != 0)
 			{
-#ifndef LOG4CXX_MULTI_PROCESS
-				rfa->incrementFileLength(buf.limit());
-#else
 				rfa->setFileLength(File().setPath(rfa->getFile()).length(p));
-#endif
 			}
 		}
 
-#ifdef LOG4CXX_MULTI_PROCESS
 		OutputStream& getFileOutPutStreamPtr()
 		{
 			return *os;
 		}
-#endif
 };
 }
 }
@@ -667,7 +659,7 @@ class CountingOutputStream : public OutputStream
  @param os output stream, may not be null.
  @return new writer.
  */
-WriterPtr RollingFileAppender::createWriter(OutputStreamPtr& os)
+WriterPtr MultiprocessRollingFileAppender::createWriter(OutputStreamPtr& os)
 {
 	OutputStreamPtr cos = std::make_shared<CountingOutputStream>(os, this);
 	return FileAppender::createWriter(cos);
@@ -677,23 +669,21 @@ WriterPtr RollingFileAppender::createWriter(OutputStreamPtr& os)
  * Get byte length of current active log file.
  * @return byte length of current active log file.
  */
-size_t RollingFileAppender::getFileLength() const
+size_t MultiprocessRollingFileAppender::getFileLength() const
 {
 	return _priv->fileLength;
 }
 
-#ifdef LOG4CXX_MULTI_PROCESS
-void RollingFileAppender::setFileLength(size_t length)
+void MultiprocessRollingFileAppender::setFileLength(size_t length)
 {
 	_priv->fileLength = length;
 }
-#endif
 
 /**
  * Increments estimated byte length of current active log file.
  * @param increment additional bytes written to log file.
  */
-void RollingFileAppender::incrementFileLength(size_t increment)
+void MultiprocessRollingFileAppender::incrementFileLength(size_t increment)
 {
 	_priv->fileLength += increment;
 }
diff --git a/src/main/cpp/outputstream.cpp b/src/main/cpp/outputstream.cpp
index 2175744d..169823cf 100644
--- a/src/main/cpp/outputstream.cpp
+++ b/src/main/cpp/outputstream.cpp
@@ -31,15 +31,3 @@ OutputStream::OutputStream()
 OutputStream::~OutputStream()
 {
 }
-
-#ifdef LOG4CXX_MULTI_PROCESS
-apr_file_t* OutputStream::getFilePtr()
-{
-	throw std::logic_error("getFilePtr must be implemented in the derived class that you are using");
-}
-
-OutputStream& OutputStream::getFileOutPutStreamPtr()
-{
-	throw std::logic_error("getFileOutPutStreamPtr must be implemented in the derived class that you are using");
-}
-#endif
diff --git a/src/main/cpp/outputstreamwriter.cpp b/src/main/cpp/outputstreamwriter.cpp
index 703f31f8..90d19931 100644
--- a/src/main/cpp/outputstreamwriter.cpp
+++ b/src/main/cpp/outputstreamwriter.cpp
@@ -81,6 +81,7 @@ void OutputStreamWriter::write(const LogString& str, Pool& p)
 	if (str.length() > 0)
 	{
 #ifdef LOG4CXX_MULTI_PROCESS
+		// Why does this need to happen for multiproces??  why??
 		size_t bufSize = str.length() * 2;
 		char* rawbuf = new char[bufSize];
 		ByteBuffer buf(rawbuf, (size_t) bufSize);
@@ -110,7 +111,7 @@ void OutputStreamWriter::write(const LogString& str, Pool& p)
 	}
 }
 
-OutputStreamPtr OutputStreamWriter::getOutPutStreamPtr() const
+OutputStreamPtr OutputStreamWriter::getOutputStreamPtr() const
 {
 	return m_priv->out;
 }
diff --git a/src/main/cpp/rollingfileappender.cpp b/src/main/cpp/rollingfileappender.cpp
index 03205071..a24a8e49 100644
--- a/src/main/cpp/rollingfileappender.cpp
+++ b/src/main/cpp/rollingfileappender.cpp
@@ -19,19 +19,6 @@
 	#pragma warning ( disable: 4231 4251 4275 4786 )
 #endif
 
-#ifdef LOG4CXX_MULTI_PROCESS
-	#include <apr_portable.h>
-	#include <libgen.h>
-	#include <apr_file_io.h>
-	#include <apr_atomic.h>
-	#include <apr_mmap.h>
-	#ifndef MAX_FILE_LEN
-		#define MAX_FILE_LEN 2048
-	#endif
-	#include <log4cxx/pattern/filedatepatternconverter.h>
-	#include <log4cxx/helpers/date.h>
-#endif
-
 #include <log4cxx/rolling/rollingfileappender.h>
 #include <log4cxx/helpers/loglog.h>
 #include <log4cxx/rolling/rolloverdescription.h>
@@ -174,23 +161,6 @@ void RollingFileAppender::activateOptions(Pool& p)
 	}
 }
 
-#ifdef LOG4CXX_MULTI_PROCESS
-void RollingFileAppenderSkeleton::releaseFileLock(apr_file_t* lock_file)
-{
-	if (lock_file)
-	{
-		apr_status_t stat = apr_file_unlock(lock_file);
-
-		if (stat != APR_SUCCESS)
-		{
-			LogLog::warn(LOG4CXX_STR("flock: unlock failed"));
-		}
-
-		apr_file_close(lock_file);
-		lock_file = NULL;
-	}
-}
-#endif
 /**
    Implements the usual roll over behaviour.
 
@@ -221,97 +191,6 @@ bool RollingFileAppender::rolloverInternal(Pool& p)
 	{
 
 		{
-
-#ifdef LOG4CXX_MULTI_PROCESS
-			std::string fileName(getFile());
-			RollingPolicyBase* basePolicy = dynamic_cast<RollingPolicyBase* >(&(*rollingPolicy));
-			apr_time_t n = apr_time_now();
-			ObjectPtr obj = std::make_shared<Date>(n);
-			LogString fileNamePattern;
-
-			if (basePolicy)
-			{
-				if (basePolicy->getPatternConverterList().size())
-				{
-					(*(basePolicy->getPatternConverterList().begin()))->format(obj, fileNamePattern, p);
-					fileName = std::string(fileNamePattern);
-				}
-			}
-
-			bool bAlreadyRolled = true;
-			char szDirName[MAX_FILE_LEN] = {'\0'};
-			char szBaseName[MAX_FILE_LEN] = {'\0'};
-			char szUid[MAX_FILE_LEN] = {'\0'};
-			memcpy(szDirName, fileName.c_str(), fileName.size() > MAX_FILE_LEN ? MAX_FILE_LEN : fileName.size());
-			memcpy(szBaseName, fileName.c_str(), fileName.size() > MAX_FILE_LEN ? MAX_FILE_LEN : fileName.size());
-			apr_uid_t uid;
-			apr_gid_t groupid;
-			apr_status_t stat = apr_uid_current(&uid, &groupid, pool.getAPRPool());
-
-			if (stat == APR_SUCCESS)
-			{
-				snprintf(szUid, MAX_FILE_LEN, "%u", uid);
-			}
-
-			const std::string lockname = std::string(::dirname(szDirName)) + "/." + ::basename(szBaseName) + szUid + ".lock";
-			apr_file_t* lock_file;
-			stat = apr_file_open(&lock_file, lockname.c_str(), APR_CREATE | APR_READ | APR_WRITE, APR_OS_DEFAULT, p.getAPRPool());
-
-			if (stat != APR_SUCCESS)
-			{
-				std::string err = "lockfile return error: open lockfile failed. ";
-				err += (strerror(errno));
-				LogLog::warn(LOG4CXX_STR(err.c_str()));
-				bAlreadyRolled = false;
-				lock_file = NULL;
-			}
-			else
-			{
-				stat = apr_file_lock(lock_file, APR_FLOCK_EXCLUSIVE);
-
-				if (stat != APR_SUCCESS)
-				{
-					std::string err = "apr_file_lock: lock failed. ";
-					err += (strerror(errno));
-					LogLog::warn(LOG4CXX_STR(err.c_str()));
-					bAlreadyRolled = false;
-				}
-				else
-				{
-					if (_event)
-					{
-						triggeringPolicy->isTriggeringEvent(this, *_event, getFile(), getFileLength());
-					}
-				}
-			}
-
-			if (bAlreadyRolled)
-			{
-				apr_finfo_t finfo1, finfo2;
-				apr_status_t st1, st2;
-				apr_file_t* _fd = getWriter()->getOutPutStreamPtr()->getFileOutPutStreamPtr().getFilePtr();
-				st1 = apr_file_info_get(&finfo1, APR_FINFO_IDENT, _fd);
-
-				if (st1 != APR_SUCCESS)
-				{
-					LogLog::warn(LOG4CXX_STR("apr_file_info_get failed"));
-				}
-
-				st2 = apr_stat(&finfo2, std::string(getFile()).c_str(), APR_FINFO_IDENT, p.getAPRPool());
-
-				if (st2 != APR_SUCCESS)
-				{
-					LogLog::warn(LOG4CXX_STR("apr_stat failed."));
-				}
-
-				bAlreadyRolled = ((st1 == APR_SUCCESS) && (st2 == APR_SUCCESS)
-						&& ((finfo1.device != finfo2.device) || (finfo1.inode != finfo2.inode)));
-			}
-
-			if (!bAlreadyRolled)
-			{
-#endif
-
 				try
 				{
 					RolloverDescriptionPtr rollover1(_priv->rollingPolicy->rollover(this->getFile(), this->getAppend(), p));
@@ -426,10 +305,6 @@ bool RollingFileAppender::rolloverInternal(Pool& p)
 
 							writeHeader(p);
 						}
-
-#ifdef LOG4CXX_MULTI_PROCESS
-						releaseFileLock(lock_file);
-#endif
 						return true;
 					}
 				}
@@ -440,39 +315,12 @@ bool RollingFileAppender::rolloverInternal(Pool& p)
 					log4cxx::helpers::Transcoder::decode(ex.what(), exmsg);
 					_priv->errorHandler->error(exmsg, ex, 0);
 				}
-
-#ifdef LOG4CXX_MULTI_PROCESS
-			}
-			else
-			{
-				reopenLatestFile(p);
-			}
-
-			releaseFileLock(lock_file);
-#endif
 		}
 	}
 
 	return false;
 }
 
-#ifdef LOG4CXX_MULTI_PROCESS
-/**
- * re-open current file when its own handler has been renamed
- */
-void RollingFileAppenderSkeleton::reopenLatestFile(Pool& p)
-{
-	closeWriter();
-	OutputStreamPtr os = std::make_shared<FileOutputStream(getFile>(), true);
-	WriterPtr newWriter(createWriter(os));
-	setFile(getFile());
-	setWriter(newWriter);
-	fileLength = File().setPath(getFile()).length(p);
-	writeHeader(p);
-}
-
-#endif
-
 /**
  * {@inheritDoc}
 */
@@ -503,37 +351,6 @@ void RollingFileAppender::subAppend(const LoggingEventPtr& event, Pool& p)
 		}
 	}
 
-#ifdef LOG4CXX_MULTI_PROCESS
-	//do re-check before every write
-	//
-	apr_finfo_t finfo1, finfo2;
-	apr_status_t st1, st2;
-	apr_file_t* _fd = getWriter()->getOutPutStreamPtr()->getFileOutPutStreamPtr().getFilePtr();
-	st1 = apr_file_info_get(&finfo1, APR_FINFO_IDENT, _fd);
-
-	if (st1 != APR_SUCCESS)
-	{
-		LogLog::warn(LOG4CXX_STR("apr_file_info_get failed"));
-	}
-
-	st2 = apr_stat(&finfo2, std::string(getFile()).c_str(), APR_FINFO_IDENT, p.getAPRPool());
-
-	if (st2 != APR_SUCCESS)
-	{
-		std::string err = "apr_stat failed. file:" + std::string(getFile());
-		LogLog::warn(LOG4CXX_STR(err.c_str()));
-	}
-
-	bool bAlreadyRolled = ((st1 == APR_SUCCESS) && (st2 == APR_SUCCESS)
-			&& ((finfo1.device != finfo2.device) || (finfo1.inode != finfo2.inode)));
-
-	if (bAlreadyRolled)
-	{
-		reopenLatestFile(p);
-	}
-
-#endif
-
 	FileAppender::subAppend(event, p);
 }
 
@@ -640,20 +457,9 @@ class CountingOutputStream : public OutputStream
 
 			if (rfa != 0)
 			{
-#ifndef LOG4CXX_MULTI_PROCESS
 				rfa->incrementFileLength(buf.limit());
-#else
-				rfa->setFileLength(File().setPath(rfa->getFile()).length(p));
-#endif
 			}
 		}
-
-#ifdef LOG4CXX_MULTI_PROCESS
-		OutputStream& getFileOutPutStreamPtr()
-		{
-			return *os;
-		}
-#endif
 };
 }
 }
@@ -682,13 +488,6 @@ size_t RollingFileAppender::getFileLength() const
 	return _priv->fileLength;
 }
 
-#ifdef LOG4CXX_MULTI_PROCESS
-void RollingFileAppender::setFileLength(size_t length)
-{
-	_priv->fileLength = length;
-}
-#endif
-
 /**
  * Increments estimated byte length of current active log file.
  * @param increment additional bytes written to log file.
diff --git a/src/main/cpp/rollingpolicybase.cpp b/src/main/cpp/rollingpolicybase.cpp
index 3e409dfd..c22a36a4 100644
--- a/src/main/cpp/rollingpolicybase.cpp
+++ b/src/main/cpp/rollingpolicybase.cpp
@@ -183,4 +183,7 @@ void RollingPolicyBase::setCreateIntermediateDirectories(bool createIntermediate
 	m_priv->createIntermediateDirectories = createIntermediate;
 }
 
-
+PatternConverterList RollingPolicyBase::getPatternConverterList() const
+{
+	return m_priv->patternConverters;
+}
diff --git a/src/main/cpp/timebasedrollingpolicy.cpp b/src/main/cpp/timebasedrollingpolicy.cpp
index eadf2b0c..cf32329d 100644
--- a/src/main/cpp/timebasedrollingpolicy.cpp
+++ b/src/main/cpp/timebasedrollingpolicy.cpp
@@ -18,10 +18,6 @@
 	#pragma warning ( disable: 4231 4251 4275 4786 )
 #endif
 
-#ifdef LOG4CXX_MULTI_PROCESS
-	#include <libgen.h>
-#endif
-
 #include <log4cxx/logstring.h>
 #include <log4cxx/rolling/timebasedrollingpolicy.h>
 #include <log4cxx/pattern/filedatepatternconverter.h>
@@ -31,7 +27,11 @@
 #include <log4cxx/helpers/exception.h>
 #include <log4cxx/rolling/gzcompressaction.h>
 #include <log4cxx/rolling/zipcompressaction.h>
-#include<iostream>
+#include <log4cxx/helpers/stringhelper.h>
+#include <log4cxx/helpers/optionconverter.h>
+#include <log4cxx/fileappender.h>
+#include <iostream>
+#include <libgen.h>
 
 using namespace log4cxx;
 using namespace log4cxx::rolling;
@@ -41,6 +41,13 @@ using namespace log4cxx::pattern;
 IMPLEMENT_LOG4CXX_OBJECT(TimeBasedRollingPolicy)
 
 struct TimeBasedRollingPolicy::TimeBasedRollingPolicyPrivate{
+	TimeBasedRollingPolicyPrivate() :
+		_mmap(nullptr),
+		_file_map(nullptr),
+		_lock_file(nullptr),
+		bAlreadyInitialized(false),
+		bRefreshCurFile(false){}
+
 		/**
 		 * Time for next determination if time for rollover.
 		 */
@@ -59,7 +66,7 @@ struct TimeBasedRollingPolicy::TimeBasedRollingPolicyPrivate{
 		/*
 		 * pool for mmap handler
 		 * */
-		log4cxx::helpers::Pool* _mmapPool;
+		log4cxx::helpers::Pool _mmapPool;
 
 		/**
 		 * mmap file descriptor
@@ -100,9 +107,11 @@ struct TimeBasedRollingPolicy::TimeBasedRollingPolicyPrivate{
 		 * Length of any file type suffix (.gz, .zip).
 		 */
 		int suffixLength;
+
+		bool multiprocess = false;
 };
 
-#ifdef LOG4CXX_MULTI_PROCESS
+
 #define MMAP_FILE_SUFFIX ".map"
 #define LOCK_FILE_SUFFIX ".maplck"
 #define MAX_FILE_LEN 2048
@@ -110,7 +119,7 @@ struct TimeBasedRollingPolicy::TimeBasedRollingPolicyPrivate{
 bool TimeBasedRollingPolicy::isMapFileEmpty(log4cxx::helpers::Pool& pool)
 {
 	apr_finfo_t finfo;
-	apr_status_t st = apr_stat(&finfo, _mapFileName.c_str(), APR_FINFO_SIZE, pool.getAPRPool());
+	apr_status_t st = apr_stat(&finfo, m_priv->_mapFileName.c_str(), APR_FINFO_SIZE, pool.getAPRPool());
 
 	if (st != APR_SUCCESS)
 	{
@@ -129,16 +138,16 @@ void TimeBasedRollingPolicy::initMMapFile(const LogString& lastFileName, log4cxx
 {
 	int iRet = 0;
 
-	if (!_mmap)
+	if (!m_priv->_mmap)
 	{
-		iRet = createMMapFile(std::string(_fileNamePattern), pool);
+		iRet = createMMapFile(std::string(m_priv->_fileNamePattern), pool);
 	}
 
 	if (!iRet && isMapFileEmpty(pool))
 	{
 		lockMMapFile(APR_FLOCK_EXCLUSIVE);
-		memset(_mmap->mm, 0, MAX_FILE_LEN);
-		memcpy(_mmap->mm, std::string(lastFileName).c_str(), std::string(lastFileName).size());
+		memset(m_priv->_mmap->mm, 0, MAX_FILE_LEN);
+		memcpy(m_priv->_mmap->mm, std::string(lastFileName).c_str(), std::string(lastFileName).size());
 		unLockMMapFile();
 	}
 }
@@ -160,40 +169,41 @@ const std::string TimeBasedRollingPolicy::createFile(const std::string& fileName
 		snprintf(szUid, MAX_FILE_LEN, "%u", uid);
 	}
 
+	// TODO this should probably be using boost::filesystem or std::filesystem
 	return std::string(::dirname(szDirName)) + "/." + ::basename(szBaseName) + szUid + suffix;
 }
 
 int TimeBasedRollingPolicy::createMMapFile(const std::string& fileName, log4cxx::helpers::Pool& pool)
 {
-	_mapFileName = createFile(fileName, MMAP_FILE_SUFFIX, pool);
+	m_priv->_mapFileName = createFile(fileName, MMAP_FILE_SUFFIX, pool);
 
-	apr_status_t stat = apr_file_open(&_file_map, _mapFileName.c_str(), APR_CREATE | APR_READ | APR_WRITE, APR_OS_DEFAULT, _mmapPool->getAPRPool());
+	apr_status_t stat = apr_file_open(&m_priv->_file_map, m_priv->_mapFileName.c_str(), APR_CREATE | APR_READ | APR_WRITE, APR_OS_DEFAULT, m_priv->_mmapPool.getAPRPool());
 
 	if (stat != APR_SUCCESS)
 	{
-		std::string err(std::string("open mmap file failed. ") + std::string(strerror(errno)) + ". Check the privilege or try to remove " + _mapFileName + " if exist.");
+		std::string err(std::string("open mmap file failed. ") + std::string(strerror(errno)) + ". Check the privilege or try to remove " + m_priv->_mapFileName + " if exist.");
 		LogLog::warn(LOG4CXX_STR(err.c_str()));
 		return -1;
 	}
 
 	if (isMapFileEmpty(pool))
 	{
-		stat = apr_file_trunc(_file_map, MAX_FILE_LEN + 1);
+		stat = apr_file_trunc(m_priv->_file_map, MAX_FILE_LEN + 1);
 
 		if (stat != APR_SUCCESS)
 		{
 			LogLog::warn(LOG4CXX_STR("apr_file_trunc failed."));
-			apr_file_close(_file_map);
+			apr_file_close(m_priv->_file_map);
 			return -1;
 		}
 	}
 
-	stat = apr_mmap_create(&_mmap, _file_map, 0, MAX_FILE_LEN, APR_MMAP_WRITE | APR_MMAP_READ, _mmapPool->getAPRPool());
+	stat = apr_mmap_create(&m_priv->_mmap, m_priv->_file_map, 0, MAX_FILE_LEN, APR_MMAP_WRITE | APR_MMAP_READ, m_priv->_mmapPool.getAPRPool());
 
 	if (stat != APR_SUCCESS)
 	{
 		LogLog::warn(LOG4CXX_STR("mmap failed."));
-		apr_file_close(_file_map);
+		apr_file_close(m_priv->_file_map);
 		return -1;
 	}
 
@@ -202,7 +212,7 @@ int TimeBasedRollingPolicy::createMMapFile(const std::string& fileName, log4cxx:
 
 int TimeBasedRollingPolicy::lockMMapFile(int type)
 {
-	apr_status_t stat = apr_file_lock(_lock_file, type);
+	apr_status_t stat = apr_file_lock(m_priv->_lock_file, type);
 
 	if (stat != APR_SUCCESS)
 	{
@@ -211,7 +221,7 @@ int TimeBasedRollingPolicy::lockMMapFile(int type)
 }
 int TimeBasedRollingPolicy::unLockMMapFile()
 {
-	apr_status_t stat = apr_file_unlock(_lock_file);
+	apr_status_t stat = apr_file_unlock(m_priv->_lock_file);
 
 	if (stat != APR_SUCCESS)
 	{
@@ -219,26 +229,13 @@ int TimeBasedRollingPolicy::unLockMMapFile()
 	}
 }
 
-#endif
-
 TimeBasedRollingPolicy::TimeBasedRollingPolicy() :
 	m_priv(std::make_unique<TimeBasedRollingPolicyPrivate>())
-#ifdef LOG4CXX_MULTI_PROCESS
-	: _mmap(NULL), _file_map(NULL), bAlreadyInitialized(false), _mmapPool(new Pool()), _lock_file(NULL), bRefreshCurFile(false)
-#endif
 {
 }
 
 TimeBasedRollingPolicy::~TimeBasedRollingPolicy(){}
 
-#ifdef LOG4CXX_MULTI_PROCESS
-TimeBasedRollingPolicy::~TimeBasedRollingPolicy()
-{
-	//no-need to delete mmap
-	delete _mmapPool;
-}
-#endif
-
 void TimeBasedRollingPolicy::activateOptions(log4cxx::helpers::Pool& pool)
 {
 	// find out period from the filename pattern
@@ -265,30 +262,29 @@ void TimeBasedRollingPolicy::activateOptions(log4cxx::helpers::Pool& pool)
 	formatFileName(obj, buf, pool);
 	m_priv->lastFileName = buf;
 
-#ifdef LOG4CXX_MULTI_PROCESS
-
-	if (getPatternConverterList().size())
-	{
-		(*(getPatternConverterList().begin()))->format(obj, _fileNamePattern, pool);
-	}
-	else
-	{
-		_fileNamePattern = lastFileName;
-	}
-
-	if (!_lock_file)
-	{
-		const std::string lockname = createFile(std::string(_fileNamePattern), LOCK_FILE_SUFFIX, *_mmapPool);
-		apr_status_t stat = apr_file_open(&_lock_file, lockname.c_str(), APR_CREATE | APR_READ | APR_WRITE, APR_OS_DEFAULT, (*_mmapPool).getAPRPool());
+	if( m_priv->multiprocess ){
+		if (getPatternConverterList().size())
+		{
+			(*(getPatternConverterList().begin()))->format(obj, m_priv->_fileNamePattern, pool);
+		}
+		else
+		{
+			m_priv->_fileNamePattern = m_priv->lastFileName;
+		}
 
-		if (stat != APR_SUCCESS)
+		if (!m_priv->_lock_file)
 		{
-			LogLog::warn(LOG4CXX_STR("open lock file failed."));
+			const std::string lockname = createFile(std::string(m_priv->_fileNamePattern), LOCK_FILE_SUFFIX, m_priv->_mmapPool);
+			apr_status_t stat = apr_file_open(&m_priv->_lock_file, lockname.c_str(), APR_CREATE | APR_READ | APR_WRITE, APR_OS_DEFAULT, m_priv->_mmapPool.getAPRPool());
+
+			if (stat != APR_SUCCESS)
+			{
+				LogLog::warn(LOG4CXX_STR("open lock file failed."));
+			}
 		}
-	}
 
-	initMMapFile(lastFileName, *_mmapPool);
-#endif
+		initMMapFile(m_priv->lastFileName, m_priv->_mmapPool);
+	}
 
 	m_priv->suffixLength = 0;
 
@@ -367,24 +363,23 @@ RolloverDescriptionPtr TimeBasedRollingPolicy::rollover(
 
 	LogString newFileName(buf);
 
-#ifdef LOG4CXX_MULTI_PROCESS
-	bAlreadyInitialized = true;
+	if( m_priv->multiprocess ){
+		m_priv->bAlreadyInitialized = true;
 
-	if (_mmap && !isMapFileEmpty(*_mmapPool))
-	{
-		lockMMapFile(APR_FLOCK_SHARED);
-		LogString mapLastFile((char*)_mmap->mm);
-		lastFileName = mapLastFile;
-		unLockMMapFile();
-	}
-	else
-	{
-		_mmap = NULL;
-		initMMapFile(lastFileName, *_mmapPool);
+		if (m_priv->_mmap && !isMapFileEmpty(m_priv->_mmapPool))
+		{
+			lockMMapFile(APR_FLOCK_SHARED);
+			LogString mapLastFile((char*)m_priv->_mmap->mm);
+			m_priv->lastFileName = mapLastFile;
+			unLockMMapFile();
+		}
+		else
+		{
+			m_priv->_mmap = NULL;
+			initMMapFile(m_priv->lastFileName, m_priv->_mmapPool);
+		}
 	}
 
-#endif
-
 	//
 	//  if file names haven't changed, no rollover
 	//
@@ -430,25 +425,23 @@ RolloverDescriptionPtr TimeBasedRollingPolicy::rollover(
 					File().setPath(lastBaseName), File().setPath(m_priv->lastFileName), true);
 	}
 
-#ifdef LOG4CXX_MULTI_PROCESS
-
-	if (_mmap && !isMapFileEmpty(*_mmapPool))
-	{
-		lockMMapFile(APR_FLOCK_EXCLUSIVE);
-		memset(_mmap->mm, 0, MAX_FILE_LEN);
-		memcpy(_mmap->mm, std::string(newFileName).c_str(), std::string(newFileName).size());
-		unLockMMapFile();
-	}
-	else
-	{
-		_mmap = NULL;
-		initMMapFile(newFileName, *_mmapPool);
+	if( m_priv->multiprocess ){
+		if (m_priv->_mmap && !isMapFileEmpty(m_priv->_mmapPool))
+		{
+			lockMMapFile(APR_FLOCK_EXCLUSIVE);
+			memset(m_priv->_mmap->mm, 0, MAX_FILE_LEN);
+			memcpy(m_priv->_mmap->mm, std::string(newFileName).c_str(), std::string(newFileName).size());
+			unLockMMapFile();
+		}
+		else
+		{
+			m_priv->_mmap = NULL;
+			initMMapFile(newFileName, m_priv->_mmapPool);
+		}
+	}else{
+		m_priv->lastFileName = newFileName;
 	}
 
-#else
-	m_priv->lastFileName = newFileName;
-#endif
-
 	return std::make_shared<RolloverDescription>(nextActiveFile, append, renameAction, compressAction);
 }
 
@@ -458,23 +451,38 @@ bool TimeBasedRollingPolicy::isTriggeringEvent(
 	const LogString&  filename,
 	size_t /* fileLength */)
 {
-#ifdef LOG4CXX_MULTI_PROCESS
-
-	if (bRefreshCurFile && _mmap && !isMapFileEmpty(*_mmapPool))
-	{
-		lockMMapFile(APR_FLOCK_SHARED);
-		LogString mapCurrent((char*)_mmap->mm);
-		unLockMMapFile();
-		LogString mapCurrentBase(mapCurrent.substr(0, mapCurrent.length() - suffixLength));
+	if( m_priv->multiprocess ){
 
-		if (!mapCurrentBase.empty() && mapCurrentBase != filename)
+		if (m_priv->bRefreshCurFile && m_priv->_mmap && !isMapFileEmpty(m_priv->_mmapPool))
 		{
-			dynamic_cast<FileAppender*>(appender)->setFile(mapCurrentBase);
+			lockMMapFile(APR_FLOCK_SHARED);
+			LogString mapCurrent((char*)m_priv->_mmap->mm);
+			unLockMMapFile();
+			LogString mapCurrentBase(mapCurrent.substr(0, mapCurrent.length() - m_priv->suffixLength));
+
+			if (!mapCurrentBase.empty() && mapCurrentBase != filename)
+			{
+				const FileAppender* fappend = reinterpret_cast<const FileAppender*>(appender->cast(FileAppender::getStaticClass()));
+				if( fappend ){
+					const_cast<FileAppender*>(fappend)->setFile(mapCurrentBase);
+				}
+			}
 		}
+
+		return ( Date::currentTime() > m_priv->nextCheck) || (!m_priv->bAlreadyInitialized);
 	}
 
-	return ((apr_time_now()) > nextCheck) || (!bAlreadyInitialized);
-#else
 	return Date::currentTime() > m_priv->nextCheck;
-#endif
+}
+
+void TimeBasedRollingPolicy::setOption(const LogString& option,
+									   const LogString& value){
+	if (StringHelper::equalsIgnoreCase(option,
+			LOG4CXX_STR("MULTIPROCESS"),
+			LOG4CXX_STR("multiprocess")))
+	{
+		m_priv->multiprocess = OptionConverter::toBoolean(value, false);
+	}
+
+	RollingPolicyBase::setOption(option, value);
 }
diff --git a/src/main/cpp/writer.cpp b/src/main/cpp/writer.cpp
index 312aa527..42f197be 100644
--- a/src/main/cpp/writer.cpp
+++ b/src/main/cpp/writer.cpp
@@ -17,6 +17,7 @@
 
 #include <log4cxx/logstring.h>
 #include <log4cxx/helpers/writer.h>
+#include <log4cxx/helpers/loglog.h>
 #include <stdexcept>
 
 using namespace log4cxx::helpers;
@@ -30,10 +31,3 @@ Writer::Writer()
 Writer::~Writer()
 {
 }
-
-#ifdef LOG4CXX_MULTI_PROCESS
-OutputStreamPtr Writer::getOutPutStreamPtr()
-{
-	throw std::logic_error("getOutPutStreamPtr must be implemented in the derived class that you are using");
-}
-#endif
diff --git a/src/main/cpp/writerappender.cpp b/src/main/cpp/writerappender.cpp
index 02fe154a..ada3bd89 100644
--- a/src/main/cpp/writerappender.cpp
+++ b/src/main/cpp/writerappender.cpp
@@ -321,3 +321,7 @@ bool WriterAppender::getImmediateFlush() const
 {
 	return _priv->immediateFlush;
 }
+
+const log4cxx::helpers::WriterPtr WriterAppender::getWriter() const{
+	return _priv->writer;
+}
diff --git a/src/main/include/log4cxx/helpers/fileoutputstream.h b/src/main/include/log4cxx/helpers/fileoutputstream.h
index 322d8a77..baacb2ba 100644
--- a/src/main/include/log4cxx/helpers/fileoutputstream.h
+++ b/src/main/include/log4cxx/helpers/fileoutputstream.h
@@ -52,12 +52,8 @@ class LOG4CXX_EXPORT FileOutputStream : public OutputStream
 		virtual void flush(Pool& p);
 		virtual void write(ByteBuffer& buf, Pool& p);
 
-#ifdef LOG4CXX_MULTI_PROCESS
-		apr_file_t* getFilePtr()
-		{
-			return fileptr;
-		}
-#endif
+		apr_file_t* getFilePtr() const;
+
 	private:
 		FileOutputStream(const FileOutputStream&);
 		FileOutputStream& operator=(const FileOutputStream&);
diff --git a/src/main/include/log4cxx/helpers/outputstream.h b/src/main/include/log4cxx/helpers/outputstream.h
index a72e45f4..d1ec12c6 100644
--- a/src/main/include/log4cxx/helpers/outputstream.h
+++ b/src/main/include/log4cxx/helpers/outputstream.h
@@ -19,9 +19,6 @@
 #define _LOG4CXX_HELPERS_OUTPUTSTREAM_H
 
 #include <log4cxx/helpers/object.h>
-#ifdef LOG4CXX_MULTI_PROCESS
-	#include <apr_file_io.h>
-#endif
 
 namespace log4cxx
 {
@@ -49,10 +46,6 @@ class LOG4CXX_EXPORT OutputStream : public Object
 		virtual void close(Pool& p) = 0;
 		virtual void flush(Pool& p) = 0;
 		virtual void write(ByteBuffer& buf, Pool& p) = 0;
-#ifdef LOG4CXX_MULTI_PROCESS
-		virtual apr_file_t* getFilePtr();
-		virtual OutputStream& getFileOutPutStreamPtr();
-#endif
 
 	private:
 		OutputStream(const OutputStream&);
diff --git a/src/main/include/log4cxx/helpers/outputstreamwriter.h b/src/main/include/log4cxx/helpers/outputstreamwriter.h
index b3086f5f..7f2a196b 100644
--- a/src/main/include/log4cxx/helpers/outputstreamwriter.h
+++ b/src/main/include/log4cxx/helpers/outputstreamwriter.h
@@ -52,7 +52,7 @@ class LOG4CXX_EXPORT OutputStreamWriter : public Writer
 		virtual void write(const LogString& str, Pool& p);
 		LogString getEncoding() const;
 
-		OutputStreamPtr getOutPutStreamPtr() const;
+		OutputStreamPtr getOutputStreamPtr() const;
 
 	private:
 		OutputStreamWriter(const OutputStreamWriter&);
diff --git a/src/main/include/log4cxx/helpers/writer.h b/src/main/include/log4cxx/helpers/writer.h
index a7c054d2..8c95d5d5 100644
--- a/src/main/include/log4cxx/helpers/writer.h
+++ b/src/main/include/log4cxx/helpers/writer.h
@@ -46,9 +46,6 @@ class LOG4CXX_EXPORT Writer : public Object
 		virtual void close(Pool& p) = 0;
 		virtual void flush(Pool& p) = 0;
 		virtual void write(const LogString& str, Pool& p) = 0;
-#ifdef LOG4CXX_MULTI_PROCESS
-		virtual OutputStreamPtr getOutPutStreamPtr();
-#endif
 
 	private:
 		Writer(const Writer&);
diff --git a/src/main/include/log4cxx/rolling/rollingfileappenderskeleton.h b/src/main/include/log4cxx/rolling/multiprocessrollingfileappender.h
similarity index 78%
rename from src/main/include/log4cxx/rolling/rollingfileappenderskeleton.h
rename to src/main/include/log4cxx/rolling/multiprocessrollingfileappender.h
index 3dfa3951..717b2d5b 100644
--- a/src/main/include/log4cxx/rolling/rollingfileappenderskeleton.h
+++ b/src/main/include/log4cxx/rolling/multiprocessrollingfileappender.h
@@ -15,9 +15,10 @@
  * limitations under the License.
  */
 
-#if !defined(_LOG4CXX_ROLLING_ROLLING_FILE_APPENDER_SKELETON_H)
-#define _LOG4CXX_ROLLING_ROLLING_FILE_APPENDER_SKELETON_H
+#if !defined(LOG4CXX_ROLLING_MULTIPROCESS_ROLLING_FILE_APPENDER_H)
+#define LOG4CXX_ROLLING_MULTIPROCESS_ROLLING_FILE_APPENDER_H
 
+#include <log4cxx/fileappender.h>
 #include <log4cxx/spi/optionhandler.h>
 #include <log4cxx/fileappender.h>
 #include <log4cxx/rolling/triggeringpolicy.h>
@@ -31,44 +32,20 @@ namespace rolling
 
 
 /**
- *  Base class for log4cxx::rolling::RollingFileAppender and log4cxx::RollingFileAppender
- * (analogues of org.apache.log4j.rolling.RFA from extras companion and
- *  org.apache.log4j.RFA from log4j 1.2, respectively).
- *
- * */
-class LOG4CXX_EXPORT RollingFileAppenderSkeleton : public FileAppender
+ * A special version of the RollingFileAppender that acts properly with multiple processes
+ */
+class LOG4CXX_EXPORT MultiprocessRollingFileAppender : public FileAppender
 {
-		DECLARE_LOG4CXX_OBJECT(RollingFileAppenderSkeleton)
+		DECLARE_LOG4CXX_OBJECT(MultiprocessRollingFileAppender)
 		BEGIN_LOG4CXX_CAST_MAP()
-		LOG4CXX_CAST_ENTRY(RollingFileAppenderSkeleton)
+		LOG4CXX_CAST_ENTRY(MultiprocessRollingFileAppender)
 		LOG4CXX_CAST_ENTRY_CHAIN(FileAppender)
 		END_LOG4CXX_CAST_MAP()
+	protected:
+		struct MultiprocessRollingFileAppenderPriv;
 
-		/**
-		 * Triggering policy.
-		 */
-		TriggeringPolicyPtr triggeringPolicy;
-
-		/**
-		 * Rolling policy.
-		 */
-		RollingPolicyPtr rollingPolicy;
-
-		/**
-		 * Length of current active log file.
-		 */
-		size_t fileLength;
-
-		/**
-		 *  save the loggingevent
-		 */
-		spi::LoggingEventPtr* _event;
 	public:
-		/**
-		 * The default constructor simply calls its {@link
-		 * FileAppender#FileAppender parents constructor}.
-		 * */
-		RollingFileAppenderSkeleton();
+		MultiprocessRollingFileAppender();
 
 		void activateOptions(log4cxx::helpers::Pool&);
 
@@ -98,7 +75,7 @@ class LOG4CXX_EXPORT RollingFileAppenderSkeleton : public FileAppender
 
 		bool rolloverInternal(log4cxx::helpers::Pool& p);
 
-	protected:
+	public:
 
 		RollingPolicyPtr getRollingPolicy() const;
 
@@ -133,16 +110,19 @@ class LOG4CXX_EXPORT RollingFileAppenderSkeleton : public FileAppender
 		log4cxx::helpers::WriterPtr createWriter(log4cxx::helpers::OutputStreamPtr& os);
 
 	public:
-
-
-
 		/**
 		 * Get byte length of current active log file.
 		 * @return byte length of current active log file.
 		 */
 		size_t getFileLength() const;
 
-#ifdef LOG4CXX_MULTI_PROCESS
+		/**
+		 * Increments estimated byte length of current active log file.
+		 * @param increment additional bytes written to log file.
+		 */
+		void incrementFileLength(size_t increment);
+
+	private:
 		/**
 		 * Set byte length of current active log file.
 		 * @return void
@@ -159,18 +139,12 @@ class LOG4CXX_EXPORT RollingFileAppenderSkeleton : public FileAppender
 		 * @return void
 		 */
 		void reopenLatestFile(log4cxx::helpers::Pool& p);
-#endif
 
-		/**
-		 * Increments estimated byte length of current active log file.
-		 * @param increment additional bytes written to log file.
-		 */
-		void incrementFileLength(size_t increment);
+		friend class CountingOutputStream;
 
 };
 
-
-LOG4CXX_PTR_DEF(RollingFileAppenderSkeleton);
+LOG4CXX_PTR_DEF(MultiprocessRollingFileAppender);
 
 }
 }
diff --git a/src/main/include/log4cxx/rolling/rollingfileappender.h b/src/main/include/log4cxx/rolling/rollingfileappender.h
index 840d03a4..603dffe4 100644
--- a/src/main/include/log4cxx/rolling/rollingfileappender.h
+++ b/src/main/include/log4cxx/rolling/rollingfileappender.h
@@ -152,34 +152,12 @@ class LOG4CXX_EXPORT RollingFileAppender : public FileAppender
 		log4cxx::helpers::WriterPtr createWriter(log4cxx::helpers::OutputStreamPtr& os);
 
 	public:
-
-
-
 		/**
 		 * Get byte length of current active log file.
 		 * @return byte length of current active log file.
 		 */
 		size_t getFileLength() const;
 
-#ifdef LOG4CXX_MULTI_PROCESS
-		/**
-		 * Set byte length of current active log file.
-		 * @return void
-		 */
-		void setFileLength(size_t length);
-
-		/**
-		 *  Release the file lock
-		 * @return void
-		 */
-		void releaseFileLock(apr_file_t* lock_file);
-		/**
-		 * re-open the latest file when its own handler has been renamed
-		 * @return void
-		 */
-		void reopenLatestFile(log4cxx::helpers::Pool& p);
-#endif
-
 		/**
 		 * Increments estimated byte length of current active log file.
 		 * @param increment additional bytes written to log file.
diff --git a/src/main/include/log4cxx/rolling/rollingpolicybase.h b/src/main/include/log4cxx/rolling/rollingpolicybase.h
index c9fdae21..0f7a4bb5 100644
--- a/src/main/include/log4cxx/rolling/rollingpolicybase.h
+++ b/src/main/include/log4cxx/rolling/rollingpolicybase.h
@@ -77,13 +77,8 @@ class LOG4CXX_EXPORT RollingPolicyBase :
 		bool getCreateIntermediateDirectories() const;
 		void setCreateIntermediateDirectories(bool createIntermediate);
 
+		PatternConverterList getPatternConverterList() const;
 
-#ifdef LOG4CXX_MULTI_PROCESS
-		PatternConverterList getPatternConverterList()
-		{
-			return patternConverters;
-		}
-#endif
 	protected:
 		RollingPolicyBase(LOG4CXX_PRIVATE_PTR(RollingPolicyBasePrivate) priv);
 		/**
@@ -104,6 +99,9 @@ class LOG4CXX_EXPORT RollingPolicyBase :
 		log4cxx::pattern::PatternConverterPtr getIntegerPatternConverter() const;
 		log4cxx::pattern::PatternConverterPtr getDatePatternConverter() const;
 };
+
+LOG4CXX_PTR_DEF(RollingPolicyBase);
+
 }
 }
 
diff --git a/src/main/include/log4cxx/rolling/timebasedrollingpolicy.h b/src/main/include/log4cxx/rolling/timebasedrollingpolicy.h
index 60b1e200..8aaf60a7 100755
--- a/src/main/include/log4cxx/rolling/timebasedrollingpolicy.h
+++ b/src/main/include/log4cxx/rolling/timebasedrollingpolicy.h
@@ -161,39 +161,8 @@ class LOG4CXX_EXPORT TimeBasedRollingPolicy : public RollingPolicyBase,
 		virtual ~TimeBasedRollingPolicy();
 		void activateOptions(log4cxx::helpers::Pool& );
 
-#ifdef LOG4CXX_MULTI_PROCESS
-		virtual ~TimeBasedRollingPolicy();
-
-		/**
-		 * Generate mmap file
-		 */
-		int createMMapFile(const std::string& lastfilename, log4cxx::helpers::Pool& pool);
-
-		/**
-		 *  Detect if the mmap file is empty
-		 */
-		bool isMapFileEmpty(log4cxx::helpers::Pool& pool);
-
-		/**
-		 *   init MMapFile
-		 */
-		void initMMapFile(const LogString& lastFileName, log4cxx::helpers::Pool& pool);
-
-		/**
-		 *   lock MMapFile
-		 */
-		int lockMMapFile(int type);
-
-		/**
-		 *   unlock MMapFile
-		 */
-		int unLockMMapFile();
-
-		/**
-		 *   create MMapFile/lockFile
-		 */
-		const std::string createFile(const std::string& filename, const std::string& suffix, log4cxx::helpers::Pool& pool);
-#endif
+		void setOption(const LogString& option,
+					const LogString& value);
 
 		/**
 		 * {@inheritDoc}
@@ -231,6 +200,38 @@ class LOG4CXX_EXPORT TimeBasedRollingPolicy : public RollingPolicyBase,
 	protected:
 		log4cxx::pattern::PatternMap getFormatSpecifiers() const;
 
+	private:
+
+		/**
+		 * Generate mmap file
+		 */
+		int createMMapFile(const std::string& lastfilename, log4cxx::helpers::Pool& pool);
+
+		/**
+		 *  Detect if the mmap file is empty
+		 */
+		bool isMapFileEmpty(log4cxx::helpers::Pool& pool);
+
+		/**
+		 *   init MMapFile
+		 */
+		void initMMapFile(const LogString& lastFileName, log4cxx::helpers::Pool& pool);
+
+		/**
+		 *   lock MMapFile
+		 */
+		int lockMMapFile(int type);
+
+		/**
+		 *   unlock MMapFile
+		 */
+		int unLockMMapFile();
+
+		/**
+		 *   create MMapFile/lockFile
+		 */
+		const std::string createFile(const std::string& filename, const std::string& suffix, log4cxx::helpers::Pool& pool);
+
 };
 
 LOG4CXX_PTR_DEF(TimeBasedRollingPolicy);
diff --git a/src/main/include/log4cxx/writerappender.h b/src/main/include/log4cxx/writerappender.h
index e77d75ad..8b276918 100644
--- a/src/main/include/log4cxx/writerappender.h
+++ b/src/main/include/log4cxx/writerappender.h
@@ -156,12 +156,8 @@ class LOG4CXX_EXPORT WriterAppender : public AppenderSkeleton
 		  <p>
 		  @param writer An already opened Writer.  */
 		void setWriter(const log4cxx::helpers::WriterPtr& writer);
-#ifdef LOG4CXX_MULTI_PROCESS
-		const log4cxx::helpers::WriterPtr getWriter()
-		{
-			return writer;
-		};
-#endif
+
+		const log4cxx::helpers::WriterPtr getWriter() const;
 
 		virtual bool requiresLayout() const;