Made all changes related to non-blocking behaviour configurable with --enable-non-blocking=yes option
diff --git a/configure.ac b/configure.ac
index d8ad3d4..561928c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -64,8 +64,6 @@
;;
esac
-CXXFLAGS="$CXXFLAGS -std=c++11"
-
# Doxygen
AC_ARG_ENABLE(doxygen,
@@ -445,6 +443,17 @@
esac
+AC_ARG_ENABLE(non-blocking,
+ AC_HELP_STRING(--enable-non-blocking,
+ [non-blocking mode (no)]))
+if test "x$enable_non_blocking" = xyes; then
+ CXXFLAGS="$CXXFLAGS -std=c++11"
+ AC_DEFINE(NON_BLOCKING)
+ AC_DEFINE(RW_MUTEX)
+ AC_DEFINE(STATIC_STRINGSTREAM)
+fi
+
+AM_CONDITIONAL([NON_BLOCKING], [test "x$enable_non_blocking" = xyes])
# Create files
# ----------------------------------------------------------------------------
diff --git a/src/main/cpp/Makefile.am b/src/main/cpp/Makefile.am
index 8c1e007..6da89cb 100644
--- a/src/main/cpp/Makefile.am
+++ b/src/main/cpp/Makefile.am
@@ -23,7 +23,6 @@
appenderattachableimpl.cpp \
appenderskeleton.cpp \
aprinitializer.cpp \
- asyncappender.cpp \
basicconfigurator.cpp \
bufferedwriter.cpp \
bytearrayinputstream.cpp \
@@ -169,5 +168,11 @@
xmlsocketappender.cpp \
zipcompressaction.cpp
+if NON_BLOCKING
+liblog4cxx_la_SOURCES += asyncappender_nonblocking.cpp
+else
+liblog4cxx_la_SOURCES += asyncappender.cpp
+endif
+
AM_CPPFLAGS += @CPPFLAGS_ODBC@
liblog4cxx_la_LDFLAGS = -version-info @LT_VERSION@ @LIBS_ODBC@ -@APR_LIBS@
diff --git a/src/main/cpp/asyncappender.cpp b/src/main/cpp/asyncappender.cpp
index 0484136..336d609 100644
--- a/src/main/cpp/asyncappender.cpp
+++ b/src/main/cpp/asyncappender.cpp
@@ -44,8 +44,8 @@
AsyncAppender::AsyncAppender()
: AppenderSkeleton(),
- buffer(DEFAULT_BUFFER_SIZE),
- SHARED_MUTEX_INIT(bufferMutex, pool),
+ buffer(),
+ bufferMutex(pool),
bufferNotFull(pool),
bufferNotEmpty(pool),
discardMap(new DiscardMap()),
@@ -125,19 +125,16 @@
{
- LOCK_R sync(bufferMutex);
+ synchronized sync(bufferMutex);
while(true) {
-
- event->addRef();
- if (buffer.bounded_push(event))
- {
- bufferNotEmpty.signalAll();
- break;
- }
- else
- {
- event->releaseRef();
- }
+ int previousSize = buffer.size();
+ if (previousSize < bufferSize) {
+ buffer.push_back(event);
+ if (previousSize == 0) {
+ bufferNotEmpty.signalAll();
+ }
+ break;
+ }
//
// Following code is only reachable if buffer is full
@@ -151,7 +148,7 @@
&& !Thread::interrupted()
&& !dispatcher.isCurrentThread()) {
try {
- bufferNotFull.await();
+ bufferNotFull.await(bufferMutex);
discard = false;
} catch (InterruptedException& e) {
//
@@ -167,7 +164,14 @@
// add event to discard map.
//
if (discard) {
- discardedCount++;
+ LogString loggerName = event->getLoggerName();
+ DiscardMap::iterator iter = discardMap->find(loggerName);
+ if (iter == discardMap->end()) {
+ DiscardSummary summary(event);
+ discardMap->insert(DiscardMap::value_type(loggerName, summary));
+ } else {
+ (*iter).second.add(event);
+ }
break;
}
}
@@ -181,13 +185,12 @@
void AsyncAppender::close() {
{
- LOCK_W sync(bufferMutex);
+ synchronized sync(bufferMutex);
closed = true;
+ bufferNotEmpty.signalAll();
+ bufferNotFull.signalAll();
}
- bufferNotEmpty.signalAll();
- bufferNotFull.signalAll();
-
#if APR_HAS_THREADS
try {
dispatcher.join();
@@ -262,12 +265,8 @@
if (size < 0) {
throw IllegalArgumentException(LOG4CXX_STR("size argument must be non-negative"));
}
-
- {
- LOCK_W sync(bufferMutex);
- bufferSize = (size < 1) ? 1 : size;
- buffer.reserve_unsafe(bufferSize);
- }
+ synchronized sync(bufferMutex);
+ bufferSize = (size < 1) ? 1 : size;
bufferNotFull.signalAll();
}
@@ -277,10 +276,8 @@
}
void AsyncAppender::setBlocking(bool value) {
- {
- LOCK_W sync(bufferMutex);
- blocking = value;
- }
+ synchronized sync(bufferMutex);
+ blocking = value;
bufferNotFull.signalAll();
}
@@ -323,7 +320,7 @@
::log4cxx::spi::LoggingEventPtr
AsyncAppender::DiscardSummary::createEvent(::log4cxx::helpers::Pool& p,
- unsigned discardedCount)
+ size_t discardedCount)
{
LogString msg(LOG4CXX_STR("Discarded "));
StringHelper::toString(discardedCount, p, msg);
@@ -339,39 +336,37 @@
#if APR_HAS_THREADS
void* LOG4CXX_THREAD_FUNC AsyncAppender::dispatch(apr_thread_t* /*thread*/, void* data) {
AsyncAppender* pThis = (AsyncAppender*) data;
+ bool isActive = true;
try {
- while (!pThis->closed) {
-
- pThis->bufferNotEmpty.await();
-
+ while (isActive) {
//
// process events after lock on buffer is released.
//
Pool p;
LoggingEventList events;
{
- LOCK_R sync(pThis->bufferMutex);
+ synchronized sync(pThis->bufferMutex);
+ size_t bufferSize = pThis->buffer.size();
+ isActive = !pThis->closed;
- unsigned count = 0;
- log4cxx::spi::LoggingEvent * logPtr = nullptr;
- while (pThis->buffer.pop(logPtr))
- {
- log4cxx::spi::LoggingEventPtr ptr(logPtr);
- events.push_back(ptr);
- logPtr->releaseRef();
- count++;
+ while((bufferSize == 0) && isActive) {
+ pThis->bufferNotEmpty.await(pThis->bufferMutex);
+ bufferSize = pThis->buffer.size();
+ isActive = !pThis->closed;
}
-
- if (pThis->blocking) {
- pThis->bufferNotFull.signalAll();
+ for(LoggingEventList::iterator eventIter = pThis->buffer.begin();
+ eventIter != pThis->buffer.end();
+ eventIter++) {
+ events.push_back(*eventIter);
}
-
- unsigned discarded = pThis->discardedCount.exchange(0);
-
- if (discarded != 0)
- {
- events.push_back(AsyncAppender::DiscardSummary::createEvent(p, discarded));
+ for(DiscardMap::iterator discardIter = pThis->discardMap->begin();
+ discardIter != pThis->discardMap->end();
+ discardIter++) {
+ events.push_back(discardIter->second.createEvent(p));
}
+ pThis->buffer.clear();
+ pThis->discardMap->clear();
+ pThis->bufferNotFull.signalAll();
}
for (LoggingEventList::iterator iter = events.begin();
diff --git a/src/main/cpp/asyncappender_nonblocking.cpp b/src/main/cpp/asyncappender_nonblocking.cpp
new file mode 100644
index 0000000..b6cedfa
--- /dev/null
+++ b/src/main/cpp/asyncappender_nonblocking.cpp
@@ -0,0 +1,390 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if defined(_MSC_VER)
+#pragma warning ( disable: 4231 4251 4275 4786 )
+#endif
+
+#include <log4cxx/asyncappender.h>
+
+
+#include <log4cxx/helpers/loglog.h>
+#include <log4cxx/spi/loggingevent.h>
+#include <apr_thread_proc.h>
+#include <apr_thread_mutex.h>
+#include <apr_thread_cond.h>
+#include <log4cxx/helpers/condition.h>
+#include <log4cxx/helpers/synchronized.h>
+#include <log4cxx/helpers/stringhelper.h>
+#include <apr_atomic.h>
+#include <log4cxx/helpers/optionconverter.h>
+
+
+using namespace log4cxx;
+using namespace log4cxx::helpers;
+using namespace log4cxx::spi;
+
+
+IMPLEMENT_LOG4CXX_OBJECT(AsyncAppender)
+
+
+AsyncAppender::AsyncAppender()
+: AppenderSkeleton(),
+ buffer(DEFAULT_BUFFER_SIZE),
+ SHARED_MUTEX_INIT(bufferMutex, pool),
+ bufferNotFull(pool),
+ bufferNotEmpty(pool),
+ discardMap(new DiscardMap()),
+ bufferSize(DEFAULT_BUFFER_SIZE),
+ appenders(new AppenderAttachableImpl(pool)),
+ dispatcher(),
+ locationInfo(false),
+ blocking(true) {
+#if APR_HAS_THREADS
+ dispatcher.run(dispatch, this);
+#endif
+}
+
+AsyncAppender::~AsyncAppender()
+{
+ finalize();
+ delete discardMap;
+}
+
+void AsyncAppender::addRef() const {
+ ObjectImpl::addRef();
+}
+
+void AsyncAppender::releaseRef() const {
+ ObjectImpl::releaseRef();
+}
+
+void AsyncAppender::addAppender(const AppenderPtr& newAppender)
+{
+ synchronized sync(appenders->getMutex());
+ appenders->addAppender(newAppender);
+}
+
+
+void AsyncAppender::setOption(const LogString& option,
+ const LogString& value) {
+ if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("LOCATIONINFO"), LOG4CXX_STR("locationinfo"))) {
+ setLocationInfo(OptionConverter::toBoolean(value, false));
+ }
+ if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("BUFFERSIZE"), LOG4CXX_STR("buffersize"))) {
+ setBufferSize(OptionConverter::toInt(value, DEFAULT_BUFFER_SIZE));
+ }
+ if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("BLOCKING"), LOG4CXX_STR("blocking"))) {
+ setBlocking(OptionConverter::toBoolean(value, true));
+ } else {
+ AppenderSkeleton::setOption(option, value);
+ }
+}
+
+
+void AsyncAppender::doAppend(const spi::LoggingEventPtr& event, Pool& pool1)
+{
+ LOCK_R sync(mutex);
+
+ doAppendImpl(event, pool1);
+}
+
+void AsyncAppender::append(const spi::LoggingEventPtr& event, Pool& p) {
+#if APR_HAS_THREADS
+ //
+ // if dispatcher has died then
+ // append subsequent events synchronously
+ //
+ if (!dispatcher.isAlive() || bufferSize <= 0) {
+ synchronized sync(appenders->getMutex());
+ appenders->appendLoopOnAppenders(event, p);
+ return;
+ }
+
+ // Set the NDC and thread name for the calling thread as these
+ // LoggingEvent fields were not set at event creation time.
+ LogString ndcVal;
+ event->getNDC(ndcVal);
+ event->getThreadName();
+ // Get a copy of this thread's MDC.
+ event->getMDCCopy();
+
+
+ {
+ LOCK_R sync(bufferMutex);
+ while(true) {
+
+ event->addRef();
+ if (buffer.bounded_push(event))
+ {
+ bufferNotEmpty.signalAll();
+ break;
+ }
+ else
+ {
+ event->releaseRef();
+ }
+
+ //
+ // Following code is only reachable if buffer is full
+ //
+ //
+ // if blocking and thread is not already interrupted
+ // and not the dispatcher then
+ // wait for a buffer notification
+ bool discard = true;
+ if (blocking
+ && !Thread::interrupted()
+ && !dispatcher.isCurrentThread()) {
+ try {
+ bufferNotFull.await();
+ discard = false;
+ } catch (InterruptedException& e) {
+ //
+ // reset interrupt status so
+ // calling code can see interrupt on
+ // their next wait or sleep.
+ Thread::currentThreadInterrupt();
+ }
+ }
+
+ //
+ // if blocking is false or thread has been interrupted
+ // add event to discard map.
+ //
+ if (discard) {
+ discardedCount++;
+ break;
+ }
+ }
+ }
+#else
+ synchronized sync(appenders->getMutex());
+ appenders->appendLoopOnAppenders(event, p);
+#endif
+ }
+
+
+void AsyncAppender::close() {
+ {
+ LOCK_W sync(bufferMutex);
+ closed = true;
+ }
+
+ bufferNotEmpty.signalAll();
+ bufferNotFull.signalAll();
+
+#if APR_HAS_THREADS
+ try {
+ dispatcher.join();
+ } catch(InterruptedException& e) {
+ Thread::currentThreadInterrupt();
+ LogLog::error(LOG4CXX_STR("Got an InterruptedException while waiting for the dispatcher to finish,"), e);
+ }
+#endif
+
+ {
+ synchronized sync(appenders->getMutex());
+ AppenderList appenderList = appenders->getAllAppenders();
+ for (AppenderList::iterator iter = appenderList.begin();
+ iter != appenderList.end();
+ iter++) {
+ (*iter)->close();
+ }
+ }
+}
+
+AppenderList AsyncAppender::getAllAppenders() const
+{
+ synchronized sync(appenders->getMutex());
+ return appenders->getAllAppenders();
+}
+
+AppenderPtr AsyncAppender::getAppender(const LogString& n) const
+{
+ synchronized sync(appenders->getMutex());
+ return appenders->getAppender(n);
+}
+
+bool AsyncAppender::isAttached(const AppenderPtr& appender) const
+{
+ synchronized sync(appenders->getMutex());
+ return appenders->isAttached(appender);
+}
+
+bool AsyncAppender::requiresLayout() const {
+ return false;
+}
+
+void AsyncAppender::removeAllAppenders()
+{
+ synchronized sync(appenders->getMutex());
+ appenders->removeAllAppenders();
+}
+
+void AsyncAppender::removeAppender(const AppenderPtr& appender)
+{
+ synchronized sync(appenders->getMutex());
+ appenders->removeAppender(appender);
+}
+
+void AsyncAppender::removeAppender(const LogString& n)
+{
+ synchronized sync(appenders->getMutex());
+ appenders->removeAppender(n);
+}
+
+bool AsyncAppender::getLocationInfo() const {
+ return locationInfo;
+}
+
+void AsyncAppender::setLocationInfo(bool flag) {
+ locationInfo = flag;
+}
+
+
+void AsyncAppender::setBufferSize(int size)
+{
+ if (size < 0) {
+ throw IllegalArgumentException(LOG4CXX_STR("size argument must be non-negative"));
+ }
+
+ {
+ LOCK_W sync(bufferMutex);
+ bufferSize = (size < 1) ? 1 : size;
+ buffer.reserve_unsafe(bufferSize);
+ }
+ bufferNotFull.signalAll();
+}
+
+int AsyncAppender::getBufferSize() const
+{
+ return bufferSize;
+}
+
+void AsyncAppender::setBlocking(bool value) {
+ {
+ LOCK_W sync(bufferMutex);
+ blocking = value;
+ }
+ bufferNotFull.signalAll();
+}
+
+bool AsyncAppender::getBlocking() const {
+ return blocking;
+}
+
+AsyncAppender::DiscardSummary::DiscardSummary(const LoggingEventPtr& event) :
+ maxEvent(event), count(1) {
+}
+
+AsyncAppender::DiscardSummary::DiscardSummary(const DiscardSummary& src) :
+ maxEvent(src.maxEvent), count(src.count) {
+}
+
+AsyncAppender::DiscardSummary& AsyncAppender::DiscardSummary::operator=(const DiscardSummary& src) {
+ maxEvent = src.maxEvent;
+ count = src.count;
+ return *this;
+}
+
+void AsyncAppender::DiscardSummary::add(const LoggingEventPtr& event) {
+ if (event->getLevel()->toInt() > maxEvent->getLevel()->toInt()) {
+ maxEvent = event;
+ }
+ count++;
+}
+
+LoggingEventPtr AsyncAppender::DiscardSummary::createEvent(Pool& p) {
+ LogString msg(LOG4CXX_STR("Discarded "));
+ StringHelper::toString(count, p, msg);
+ msg.append(LOG4CXX_STR(" messages due to a full event buffer including: "));
+ msg.append(maxEvent->getMessage());
+ return new LoggingEvent(
+ maxEvent->getLoggerName(),
+ maxEvent->getLevel(),
+ msg,
+ LocationInfo::getLocationUnavailable());
+}
+
+::log4cxx::spi::LoggingEventPtr
+AsyncAppender::DiscardSummary::createEvent(::log4cxx::helpers::Pool& p,
+ size_t discardedCount)
+{
+ LogString msg(LOG4CXX_STR("Discarded "));
+ StringHelper::toString(discardedCount, p, msg);
+ msg.append(LOG4CXX_STR(" messages due to a full event buffer"));
+
+ return new LoggingEvent(
+ LOG4CXX_STR(""),
+ log4cxx::Level::getError(),
+ msg,
+ LocationInfo::getLocationUnavailable());
+}
+
+#if APR_HAS_THREADS
+void* LOG4CXX_THREAD_FUNC AsyncAppender::dispatch(apr_thread_t* /*thread*/, void* data) {
+ AsyncAppender* pThis = (AsyncAppender*) data;
+ try {
+ while (!pThis->closed) {
+
+ pThis->bufferNotEmpty.await();
+
+ //
+ // process events after lock on buffer is released.
+ //
+ Pool p;
+ LoggingEventList events;
+ {
+ LOCK_R sync(pThis->bufferMutex);
+
+ unsigned count = 0;
+ log4cxx::spi::LoggingEvent * logPtr = nullptr;
+ while (pThis->buffer.pop(logPtr))
+ {
+ log4cxx::spi::LoggingEventPtr ptr(logPtr);
+ events.push_back(ptr);
+ logPtr->releaseRef();
+ count++;
+ }
+
+ if (pThis->blocking) {
+ pThis->bufferNotFull.signalAll();
+ }
+
+ size_t discarded = pThis->discardedCount.exchange(0);
+
+ if (discarded != 0)
+ {
+ events.push_back(AsyncAppender::DiscardSummary::createEvent(p, discarded));
+ }
+ }
+
+ for (LoggingEventList::iterator iter = events.begin();
+ iter != events.end();
+ iter++) {
+ synchronized sync(pThis->appenders->getMutex());
+ pThis->appenders->appendLoopOnAppenders(*iter, p);
+ }
+ }
+ } catch(InterruptedException& ex) {
+ Thread::currentThreadInterrupt();
+ } catch(...) {
+ }
+ return 0;
+}
+#endif
diff --git a/src/main/cpp/messagebuffer.cpp b/src/main/cpp/messagebuffer.cpp
index 39a5f2a..e13d312 100644
--- a/src/main/cpp/messagebuffer.cpp
+++ b/src/main/cpp/messagebuffer.cpp
@@ -40,7 +40,9 @@
}
CharMessageBuffer::CharMessageBuffer() : stream(0) {
- if (gMessageBufferUseStaticStream)
+
+#if defined(STATIC_STRINGSTREAM)
+if (gMessageBufferUseStaticStream)
{
thread_local static char ossBuf[8192];
thread_local static std::basic_ostringstream<char> sStream;
@@ -54,6 +56,7 @@
}
stream = &sStream;
}
+#endif
}
CharMessageBuffer::~CharMessageBuffer() {
@@ -143,6 +146,8 @@
#if LOG4CXX_WCHAR_T_API
WideMessageBuffer::WideMessageBuffer() : stream(0) {
+
+#if defined(STATIC_STRINGSTREAM)
if (gMessageBufferUseStaticStream)
{
thread_local static wchar_t ossBuf[8192];
@@ -157,6 +162,7 @@
}
stream = &sStream;
}
+#endif
}
WideMessageBuffer::~WideMessageBuffer() {
@@ -372,6 +378,8 @@
UniCharMessageBuffer::UniCharMessageBuffer() : stream(0) {
+
+#if defined(STATIC_STRINGSTREAM)
if (gMessageBufferUseStaticStream)
{
thread_local static log4cxx::UniChar ossBuf[8192];
@@ -386,6 +394,7 @@
}
stream = &sStream;
}
+#endif
}
UniCharMessageBuffer::~UniCharMessageBuffer() {
diff --git a/src/main/cpp/mutex.cpp b/src/main/cpp/mutex.cpp
index b57595d..d76afca 100755
--- a/src/main/cpp/mutex.cpp
+++ b/src/main/cpp/mutex.cpp
@@ -27,6 +27,8 @@
#endif
#include <log4cxx/helpers/aprinitializer.h>
+#if defined(NON_BLOCKING)
+
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#else
@@ -34,6 +36,8 @@
#include <semaphore.h>
#endif
+#endif // NON_BLOCKING
+
using namespace log4cxx::helpers;
using namespace log4cxx;
@@ -75,6 +79,8 @@
return mutex;
}
+#if defined(RW_MUTEX)
+
RWMutex::RWMutex(Pool& p)
: id((apr_os_thread_t)-1)
, count(0)
@@ -152,6 +158,9 @@
#endif
}
+#endif // RW_MUTEX
+
+#if defined(NON_BLOCKING)
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64)
@@ -164,7 +173,7 @@
}
}
-static const LONG cMax = 10;
+static const LONG cMax = 10000; // arbitrary high value
Semaphore::Semaphore(log4cxx::helpers::Pool& p)
: impl(nullptr)
@@ -275,4 +284,6 @@
#endif
}
-#endif
+#endif // POSIX
+
+#endif // NON_BLOCKING
diff --git a/src/main/cpp/synchronized.cpp b/src/main/cpp/synchronized.cpp
index e561f54..a732c7f 100644
--- a/src/main/cpp/synchronized.cpp
+++ b/src/main/cpp/synchronized.cpp
@@ -60,6 +60,7 @@
#endif
}
+#if defined(RW_MUTEX)
synchronized_read::synchronized_read(const RWMutex& mutex1)
: mutex(mutex1)
@@ -83,3 +84,4 @@
mutex.wrUnlock();
}
+#endif // RW_MUTEX
diff --git a/src/main/include/log4cxx/asyncappender.h b/src/main/include/log4cxx/asyncappender.h
index 7d43d81..499b435 100644
--- a/src/main/include/log4cxx/asyncappender.h
+++ b/src/main/include/log4cxx/asyncappender.h
@@ -32,7 +32,9 @@
#include <log4cxx/helpers/mutex.h>
#include <log4cxx/helpers/condition.h>
+#if defined(NON_BLOCKING)
#include <boost/lockfree/queue.hpp>
+#endif
namespace log4cxx
{
@@ -199,16 +201,25 @@
/**
* Event buffer.
*/
+#if defined(NON_BLOCKING)
boost::lockfree::queue<log4cxx::spi::LoggingEvent* > buffer;
- std::atomic<unsigned> discardedCount;
+ std::atomic<size_t> discardedCount;
+#else
+ LoggingEventList buffer;
+#endif
/**
* Mutex used to guard access to buffer and discardMap.
*/
SHARED_MUTEX bufferMutex;
- SEMAPHORE bufferNotFull;
- SEMAPHORE bufferNotEmpty;
-
+
+#if defined(NON_BLOCKING)
+ ::log4cxx::helpers::Semaphore bufferNotFull;
+ ::log4cxx::helpers::Semaphore bufferNotEmpty;
+#else
+ ::log4cxx::helpers::Condition bufferNotFull;
+ ::log4cxx::helpers::Condition bufferNotEmpty;
+#endif
class DiscardSummary {
private:
/**
@@ -249,7 +260,7 @@
static
::log4cxx::spi::LoggingEventPtr createEvent(::log4cxx::helpers::Pool& p,
- unsigned discardedCount);
+ size_t discardedCount);
};
/**
diff --git a/src/main/include/log4cxx/helpers/mutex.h b/src/main/include/log4cxx/helpers/mutex.h
index ea8b18e..aecc6bd 100644
--- a/src/main/include/log4cxx/helpers/mutex.h
+++ b/src/main/include/log4cxx/helpers/mutex.h
@@ -54,6 +54,8 @@
} // namespace log4cxx
+#if defined(RW_MUTEX)
+
namespace log4cxx
{
namespace helpers
@@ -84,8 +86,17 @@
} // namespace log4cxx
#define SHARED_MUTEX log4cxx::helpers::RWMutex
+
+#else // no RW_MUTEX
+
+#define SHARED_MUTEX log4cxx::helpers::Mutex
+
+#endif // RW_MUTEX
+
#define SHARED_MUTEX_INIT(mutex, p) mutex(p)
+#if defined(NON_BLOCKING)
+
namespace log4cxx
{
namespace helpers
@@ -110,6 +121,6 @@
} // namespace helpers
} // namespace log4cxx
-#define SEMAPHORE log4cxx::helpers::Semaphore
+#endif // NON_BLOCKING
#endif //_LOG4CXX_HELPERS_MUTEX_H
diff --git a/src/main/include/log4cxx/helpers/synchronized.h b/src/main/include/log4cxx/helpers/synchronized.h
index e4df183..741b24e 100644
--- a/src/main/include/log4cxx/helpers/synchronized.h
+++ b/src/main/include/log4cxx/helpers/synchronized.h
@@ -46,6 +46,8 @@
}
}
+#if defined(RW_MUTEX)
+
namespace log4cxx
{
namespace helpers {
@@ -93,4 +95,11 @@
#define LOCK_R synchronized_read
#define LOCK_W synchronized_write
+#else
+
+#define LOCK_R synchronized
+#define LOCK_W synchronized
+
+#endif // RW_MUTEX
+
#endif //_LOG4CXX_HELPERS_SYNCHRONIZED_H