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