Please try the following patch and see if it resolves your problem.
Reworking ObjectPtrBase::exchange for 64-bit builds was on my TO-DO
list, but I wanted to work through the rest of the backlog before
going to platform specific builds. On 32-bit builds,
ObjectPtrBase::exchange calls apr_atomic_xchg32 which on most
processors will end up being a single machine instruction. Until
recently APR did not have an equivalent call to exchange pointers (it
does now in the SVN, but hasn't appeared in a release yet), so there
were calls that used the Mutex abstraction from log4cxx. What I
believe that you are running into is exchange() was first called in
the object destructor which means that it could occur after APR has
been terminated. I've modified ObjectPtrBase so that the mutex is
accessed in the constructor which should guarantee that it is still
available in the matching destructor. I have not tested the code
and it is not what I expect the final fix will be, but it may be
enough to get you going.
Ultimately, I'd expect to use apr_atomic_xchg32 on 32-bit builds,
InterlockedExchangePtr on Win64-builds, update configure to test for
the presence of apr_atomic_xchgptr and use that if available and only
then attempt to use the log4cxx Mutex abstraction. log4cxx-0.9.7 did
not attempt to do any synchronization on object pointers. If the fix
doesn't work for you, let the list know but you should be able to get
away with just commenting out the synchronization constructor.
Index: src/main/cpp/objectptr.cpp
===================================================================
--- src/main/cpp/objectptr.cpp (revision 582963)
+++ src/main/cpp/objectptr.cpp (working copy)
@@ -26,6 +26,17 @@
using namespace log4cxx::helpers;
+ObjectPtrBase::ObjectPtrBase() {
+#if APR_SIZEOF_VOIDP != 4
+ getMutex();
+#endif
+}
+
+Mutex& ObjectPtrBase::getMutex() {
+ static Mutex mutex(APRInitializer::getRootPool());
+ return mutex;
+}
+
void ObjectPtrBase::checkNull(const int& null) {
if (null != 0) {
throw IllegalArgumentException("Attempt to set pointer to a
non-zero numeric value.");
@@ -37,8 +48,7 @@
return (void*) apr_atomic_xchg32((volatile apr_uint32_t*)
destination,
(apr_uint32_t) newValue);
#else
- static Mutex mutex(APRInitializer::getRootPool());
- synchronized sync(mutex);
+ synchronized sync(getMutex());
void* oldValue = *destination;
*destination = newValue;
return oldValue;
Index: src/main/include/log4cxx/helpers/objectptr.h
===================================================================
--- src/main/include/log4cxx/helpers/objectptr.h (revision 582963)
+++ src/main/include/log4cxx/helpers/objectptr.h (working copy)
@@ -37,11 +37,16 @@
{
namespace helpers
{
+ class Mutex;
class LOG4CXX_EXPORT ObjectPtrBase {
public:
+ ObjectPtrBase();
static void checkNull(const int& null);
static void* exchange(void** destination, void* newValue);
+
+ private:
+ static Mutex& getMutex();
};