Thanks Curt.  I'll give it a try.


Curt Arnold-3 wrote:
> 
> 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();
>           };
> 
> 
> 
> 
> 
> 
> 

-- 
View this message in context: 
http://www.nabble.com/apps-throwing-MutexException-at-termination-tf4590301.html#a13115535
Sent from the Log4cxx - Users mailing list archive at Nabble.com.

Reply via email to