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();
         };





Reply via email to