You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4cxx-dev@logging.apache.org by cd...@apache.org on 2004/08/18 23:04:57 UTC

cvs commit: logging-log4cxx/src criticalsection.cpp ndc.cpp thread.cpp threadspecificdata.cpp

cdevienne    2004/08/18 14:04:57

  Modified:    .        ChangeLog
               include/log4cxx ndc.h
               include/log4cxx/helpers criticalsection.h thread.h
                        threadspecificdata.h
               src      criticalsection.cpp ndc.cpp thread.cpp
                        threadspecificdata.cpp
  Log:
  * Hidden thread related classes members (Christophe de Vienne)
  * Added TreadSpecificData_ptr (Christophe de Vienne)
  * Added CriticalSection::Type so one can use fast mutexes, not only recursive (Christophe de Vienne).
  
  Revision  Changes    Path
  1.36      +4 -1      logging-log4cxx/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/ChangeLog,v
  retrieving revision 1.35
  retrieving revision 1.36
  diff -u -r1.35 -r1.36
  --- ChangeLog	13 Aug 2004 12:27:45 -0000	1.35
  +++ ChangeLog	18 Aug 2004 21:04:56 -0000	1.36
  @@ -7,8 +7,11 @@
   * Renamed config.h to portability.h (fixes an automake problem).
   * Fixed a memory leak in the "trivial" example.
   * Fixed errors in documentation
  -* simplesocketserver is now in a separate directory.
  +* simplesocketserver is now in a separate directory. (Christophe de Vienne)
   * Fixed global namespace pollution (config_auto.h) (Cesar Eduardo Barros).
  +* Hidden thread related classes members (Christophe de Vienne)
  +* Added TreadSpecificData_ptr (Christophe de Vienne)
  +* Added CriticalSection::Type so one can use fast mutexes, not only recursive (Christophe de Vienne).
   
   Version 0.9.7 (2004-05-10)
   ==========================
  
  
  
  1.7       +1 -1      logging-log4cxx/include/log4cxx/ndc.h
  
  Index: ndc.h
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/include/log4cxx/ndc.h,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ndc.h	24 Apr 2004 06:55:01 -0000	1.6
  +++ ndc.h	18 Aug 2004 21:04:56 -0000	1.7
  @@ -111,7 +111,7 @@
   		static Stack * getCurrentThreadStack();
   		static void setCurrentThreadStack(Stack * stack);
   
  -		static helpers::ThreadSpecificData threadSpecificData;
  +		static helpers::ThreadSpecificData_ptr<Stack> threadSpecificData;
   
   	public:
   		NDC(const String& message);
  
  
  
  1.10      +13 -13    logging-log4cxx/include/log4cxx/helpers/criticalsection.h
  
  Index: criticalsection.h
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/include/log4cxx/helpers/criticalsection.h,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- criticalsection.h	13 Aug 2004 12:27:46 -0000	1.9
  +++ criticalsection.h	18 Aug 2004 21:04:56 -0000	1.10
  @@ -18,12 +18,7 @@
   #define _LOG4CXX_HELPERS_CRITICAL_SECTION_H
   
   #include <log4cxx/portability.h>
  -
  -#ifdef LOG4CXX_HAVE_PTHREAD
  -#include <pthread.h>
  -#elif defined(LOG4CXX_HAVE_MS_THREAD)
  -#include <windows.h>
  -#endif
  +#include <memory>
   
   namespace log4cxx
   {
  @@ -32,18 +27,23 @@
   		class LOG4CXX_EXPORT CriticalSection
   		{
   		public:
  -			CriticalSection();
  +			enum Type {
  +				Simple,
  +				Recursive
  +			};
  +
  +			
  +		public:
  +			CriticalSection(Type type = Recursive);
   			~CriticalSection();
   			void lock();
  +			bool try_lock();
   			void unlock();
   			unsigned long getOwningThread();
   
  -#ifdef LOG4CXX_HAVE_PTHREAD
  -			pthread_mutex_t mutex;
  -#elif defined(LOG4CXX_HAVE_MS_THREAD)
  -			CRITICAL_SECTION mutex;
  -#endif						
  -			unsigned long owningThread;
  +		private:
  +			struct Impl;
  +			std::auto_ptr<Impl> impl;
   		};
   
   		/** CriticalSection helper class to be used on call stack
  
  
  
  1.15      +4 -6      logging-log4cxx/include/log4cxx/helpers/thread.h
  
  Index: thread.h
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/include/log4cxx/helpers/thread.h,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- thread.h	13 Aug 2004 12:27:46 -0000	1.14
  +++ thread.h	18 Aug 2004 21:04:56 -0000	1.15
  @@ -130,14 +130,12 @@
   			static long InterlockedDecrement(volatile long * val);
   		
   		protected:
  -			/** Thread descriptor */
  -#ifdef LOG4CXX_HAVE_PTHREAD
  -			pthread_t thread;
  -#elif defined(LOG4CXX_HAVE_MS_THREAD)
  -			void * thread;
  -#endif
   			RunnablePtr runnable;
   			MDC::Map parentMDCMap;
  +
  +		private:
  +			struct Impl;
  +			std::auto_ptr<Impl> impl;
   		};
   		
   		typedef ObjectPtrT<Thread> ThreadPtr;
  
  
  
  1.10      +56 -9     logging-log4cxx/include/log4cxx/helpers/threadspecificdata.h
  
  Index: threadspecificdata.h
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/include/log4cxx/helpers/threadspecificdata.h,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- threadspecificdata.h	13 Aug 2004 12:27:46 -0000	1.9
  +++ threadspecificdata.h	18 Aug 2004 21:04:56 -0000	1.10
  @@ -18,10 +18,7 @@
   #define _LOG4CXX_HELPERS_THREAD_SPECIFIC_DATA_H
   
   #include <log4cxx/portability.h>
  -
  -#ifdef LOG4CXX_HAVE_PTHREAD
  -#include <pthread.h>
  -#endif
  +#include <memory>
   
   namespace log4cxx
   {
  @@ -31,17 +28,67 @@
   		{
   		public:
   			ThreadSpecificData();
  +			ThreadSpecificData(void (*cleanup)(void*));
   			~ThreadSpecificData();
   			void * GetData() const;
   			void SetData(void * data);
   
   		protected:
  -#ifdef LOG4CXX_HAVE_PTHREAD
  -			pthread_key_t key;
  -#elif defined(LOG4CXX_HAVE_MS_THREAD)
  -			void * key;
  -#endif
  +			struct Impl;
  +			std::auto_ptr<Impl> impl;
   		};
  +
  +		template < typename T >
  +			class ThreadSpecificData_ptr
  +			{
  +			public:
  +				ThreadSpecificData_ptr(T * p = 0): impl(&cleanup)
  +				{
  +					reset(p);
  +				}
  +
  +				T * get() const
  +				{
  +					return static_cast<T*>( impl.GetData() );
  +				}
  +
  +				void reset(T * p)
  +				{
  +					T * tmp = get();
  +					if(tmp)
  +						delete tmp;
  +					impl.SetData(p);
  +				}
  +
  +				operator T * () const
  +				{
  +					return get();
  +				}
  +
  +				T * operator->() const
  +				{
  +					return get();
  +				}
  +
  +				T & operator*() const
  +				{
  +					return *get();
  +				}
  +
  +				T * release()
  +				{
  +					T * tmp = get();
  +					impl.SetData(0);
  +					return tmp;
  +				}
  +				
  +			private:
  +				ThreadSpecificData impl;
  +				static void cleanup(void * p)
  +				{
  +					delete static_cast<T*>(p);
  +				}
  +			};
   	}  // namespace helpers
   }; // namespace log4cxx
   
  
  
  
  1.8       +52 -13    logging-log4cxx/src/criticalsection.cpp
  
  Index: criticalsection.cpp
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/src/criticalsection.cpp,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- criticalsection.cpp	13 Aug 2004 12:27:47 -0000	1.7
  +++ criticalsection.cpp	18 Aug 2004 21:04:56 -0000	1.8
  @@ -17,52 +17,91 @@
   #include <log4cxx/helpers/criticalsection.h>
   #include <log4cxx/helpers/thread.h>
   
  +#ifdef LOG4CXX_HAVE_PTHREAD
  +#include <pthread.h>
  +#elif defined(LOG4CXX_HAVE_MS_THREAD)
  +#include <windows.h>
  +#endif
  +
  +
   using namespace log4cxx::helpers;
   
  -CriticalSection::CriticalSection() : owningThread(0)
  +struct CriticalSection::Impl
  +{
  +	Impl(CriticalSection::Type type): owningThread(0), type(type) {}
  +#ifdef LOG4CXX_HAVE_PTHREAD
  +	pthread_mutex_t mutex;
  +#elif defined(LOG4CXX_HAVE_MS_THREAD)
  +	CRITICAL_SECTION mutex;
  +#endif						
  +	unsigned long owningThread;
  +	CriticalSection::Type type;
  +};
  +
  +CriticalSection::CriticalSection(Type type) : impl(new Impl(type))
   {
   #ifdef LOG4CXX_HAVE_PTHREAD
   	pthread_mutexattr_t attr;
   	pthread_mutexattr_init(&attr);
  -	pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
  -	pthread_mutex_init(&mutex, &attr);
  +	switch(type)
  +	{
  +		case Simple:
  +			// to nothing, leave the default type
  +			break;
  +		case Recursive:
  +			pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
  +			break;
  +	};
  +	pthread_mutex_init(&impl->mutex, &attr);
   	pthread_mutexattr_destroy(&attr);
   #elif defined(LOG4CXX_HAVE_MS_THREAD)
  -	InitializeCriticalSection(&mutex);
  +	InitializeCriticalSection(&impl->mutex);
   #endif						
   }
   
   CriticalSection::~CriticalSection()
   {
   #ifdef LOG4CXX_HAVE_PTHREAD
  -	pthread_mutex_destroy(&mutex);
  +	pthread_mutex_destroy(&impl->mutex);
   #elif defined(LOG4CXX_HAVE_MS_THREAD)
  -	DeleteCriticalSection(&mutex);
  +	DeleteCriticalSection(&impl->mutex);
   #endif
   }
   
   void CriticalSection::lock()
   {
   #ifdef LOG4CXX_HAVE_PTHREAD
  -	pthread_mutex_lock(&mutex);
  +	pthread_mutex_lock(&impl->mutex);
  +#elif defined(LOG4CXX_HAVE_MS_THREAD)
  +	EnterCriticalSection(&impl->mutex);
  +#endif
  +	impl->owningThread = Thread::getCurrentThreadId();
  +}
  +
  +bool CriticalSection::try_lock()
  +{
  +#ifdef LOG4CXX_HAVE_PTHREAD
  +	if(pthread_mutex_trylock(&impl->mutex) == EBUSY)
  +		return false;
  +	else
  +		return true;
   #elif defined(LOG4CXX_HAVE_MS_THREAD)
  -	EnterCriticalSection(&mutex);
  +#error "try_lock is not implemented for msthread"
   #endif
  -	owningThread = Thread::getCurrentThreadId();
   }
   
   void CriticalSection::unlock()
   {
  -	owningThread = 0;
  +	impl->owningThread = 0;
   
   #ifdef LOG4CXX_HAVE_PTHREAD
  -	pthread_mutex_unlock(&mutex);
  +	pthread_mutex_unlock(&impl->mutex);
   #elif defined(LOG4CXX_HAVE_MS_THREAD)
  -	LeaveCriticalSection(&mutex);
  +	LeaveCriticalSection(&impl->mutex);
   #endif
   }
   
   unsigned long CriticalSection::getOwningThread()
   {
  -	return owningThread;
  +	return impl->owningThread;
   }
  
  
  
  1.5       +8 -8      logging-log4cxx/src/ndc.cpp
  
  Index: ndc.cpp
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/src/ndc.cpp,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ndc.cpp	22 Apr 2004 21:21:33 -0000	1.4
  +++ ndc.cpp	18 Aug 2004 21:04:56 -0000	1.5
  @@ -34,7 +34,7 @@
   }
   
   // static member instanciation
  -ThreadSpecificData NDC::threadSpecificData;
  +ThreadSpecificData_ptr<NDC::Stack> NDC::threadSpecificData;
   
   NDC::NDC(const String& message)
   {
  @@ -48,22 +48,22 @@
   
   NDC::Stack * NDC::getCurrentThreadStack()
   {
  -	return (Stack *)threadSpecificData.GetData();
  +	return threadSpecificData;
   }
   
   void NDC::setCurrentThreadStack(NDC::Stack * stack)
   {
  -	threadSpecificData.SetData((void *)stack); 
  +	threadSpecificData.reset(stack); 
   }
   
   void NDC::clear()
   {
  -	Stack * stack = getCurrentThreadStack();    
  +/*	Stack * stack = getCurrentThreadStack();    
   	if(stack != 0)
   	{
  -		delete stack;
  +		delete stack; */
   		setCurrentThreadStack(0);
  -	} 
  +	//} 
   }
   
   NDC::Stack * NDC::cloneStack()
  @@ -83,12 +83,12 @@
   {
   	if(stack != 0)
   	{
  -		Stack * oldStack = getCurrentThreadStack();
  +/*		Stack * oldStack = getCurrentThreadStack();
   		if(oldStack != 0)
   		{
   			delete oldStack;
   		}
  -	
  +*/	
   		setCurrentThreadStack(stack);
   	}
   }
  
  
  
  1.15      +26 -12    logging-log4cxx/src/thread.cpp
  
  Index: thread.cpp
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/src/thread.cpp,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- thread.cpp	13 Aug 2004 12:27:48 -0000	1.14
  +++ thread.cpp	18 Aug 2004 21:04:56 -0000	1.15
  @@ -28,6 +28,19 @@
   IMPLEMENT_LOG4CXX_OBJECT(Runnable)
   IMPLEMENT_LOG4CXX_OBJECT(Thread)
   
  +struct Thread::Impl
  +{
  +	Impl(): thread(0) {};
  +
  +	/** Thread descriptor */
  +#ifdef LOG4CXX_HAVE_PTHREAD
  +	pthread_t thread;
  +#elif defined(LOG4CXX_HAVE_MS_THREAD)
  +	void * thread;
  +#endif
  +
  +};
  +
   #ifdef LOG4CXX_HAVE_PTHREAD
   #include <pthread.h>
   #include <unistd.h> // usleep
  @@ -54,24 +67,25 @@
   #endif
   
   
  -Thread::Thread() : thread(0)
  +Thread::Thread(): impl( new Impl )
   {
   	addRef();
   }
   
  -Thread::Thread(RunnablePtr runnable) : runnable(runnable), thread(0)
  +Thread::Thread(RunnablePtr runnable) : runnable(runnable), impl( new Impl )
   {
   	addRef();
   }
   
   Thread::~Thread()
   {
  -	if (thread != 0)
  +	// TODO: why don't we use Thread::join ?
  +	if (impl->thread != 0)
   	{
   #ifdef LOG4CXX_HAVE_PTHREAD
  -		::pthread_join(thread, 0);
  +		::pthread_join(impl->thread, 0);
   #elif defined(LOG4CXX_HAVE_MS_THREAD)
  -		::CloseHandle((HANDLE)thread);
  +		::CloseHandle((HANDLE)impl->thread);
   #endif
   		LOGLOG_DEBUG(_T("Thread destroyed."));
   	}
  @@ -91,15 +105,15 @@
   	parentMDCMap = MDC::getContext();
   #ifdef LOG4CXX_HAVE_PTHREAD
   //	LogLog::debug(_T("Thread::start"));
  -	if (::pthread_create(&thread, NULL, threadProc, this) != 0)
  +	if (::pthread_create(&impl->thread, NULL, threadProc, this) != 0)
   	{
   		throw ThreadException();
   	}
   #elif defined(LOG4CXX_HAVE_MS_THREAD)
   	unsigned long threadId = 0;
  -	thread =
  +	impl->thread =
   		(void *)::CreateThread(NULL, 0, threadProc, this, 0, &threadId);
  -	if (thread == 0)
  +	if (impl->thread == 0)
   	{
   		throw ThreadException();
   	}
  @@ -119,17 +133,17 @@
   {
   	bool bSuccess = true;
   #ifdef LOG4CXX_HAVE_PTHREAD
  -	::pthread_join(thread, 0);
  +	::pthread_join(impl->thread, 0);
   #elif defined(LOG4CXX_HAVE_MS_THREAD)
  -	if (::WaitForSingleObject((HANDLE)thread, INFINITE) != WAIT_OBJECT_0)
  +	if (::WaitForSingleObject((HANDLE)impl->thread, INFINITE) != WAIT_OBJECT_0)
   	{
   		bSuccess = false;
   	}
   
  -	::CloseHandle((HANDLE)thread);
  +	::CloseHandle((HANDLE)impl->thread);
   #endif
   
  -	thread = 0;
  +	impl->thread = 0;
   
   	if (!bSuccess)
   	{
  
  
  
  1.8       +35 -11    logging-log4cxx/src/threadspecificdata.cpp
  
  Index: threadspecificdata.cpp
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/src/threadspecificdata.cpp,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- threadspecificdata.cpp	13 Aug 2004 12:27:48 -0000	1.7
  +++ threadspecificdata.cpp	18 Aug 2004 21:04:56 -0000	1.8
  @@ -26,42 +26,66 @@
   
   using namespace log4cxx::helpers;
   
  -ThreadSpecificData::ThreadSpecificData() : key(0)
  +struct ThreadSpecificData::Impl
   {
  +	Impl(): key(0) {}
   #ifdef LOG4CXX_HAVE_PTHREAD
  -	pthread_key_create(&key, NULL);
  +	pthread_key_t key;
  +//#elif defined(LOG4CXX_HAVE_MS_THREAD)
  +#else
  +	void * key;
  +#endif
  +};
  +
  +ThreadSpecificData::ThreadSpecificData() : impl(new Impl)
  +{
  +#ifdef LOG4CXX_HAVE_PTHREAD
  +	pthread_key_create(&impl->key, NULL);
   #elif defined(LOG4CXX_HAVE_MS_THREAD)
  -	key = (void *)TlsAlloc();
  +	impl->key = (void *)TlsAlloc();
  +#endif
  +}
  +
  +ThreadSpecificData::ThreadSpecificData(void (*cleanup)(void*)): impl(new Impl)
  +{
  +#ifdef LOG4CXX_HAVE_PTHREAD
  +	pthread_key_create(&impl->key, cleanup);
  +#elif defined(LOG4CXX_HAVE_MS_THREAD)
  +//	impl->key = (void *)TlsAlloc();
  +#error "Not implemented"
   #endif
   }
   
   ThreadSpecificData::~ThreadSpecificData()
   {
   #ifdef LOG4CXX_HAVE_PTHREAD
  -	pthread_key_delete(key);
  +	pthread_key_delete(impl->key);
   #elif defined(LOG4CXX_HAVE_MS_THREAD)
  -	TlsFree((DWORD)key);
  +	TlsFree((DWORD)impl->key);
   #endif
   }
   
   void * ThreadSpecificData::GetData() const
   {
   #ifdef LOG4CXX_HAVE_PTHREAD
  -	return pthread_getspecific((pthread_key_t)key);
  +	return pthread_getspecific((pthread_key_t)impl->key);
   #elif defined(LOG4CXX_HAVE_MS_THREAD)
  -	return TlsGetValue((DWORD)key);
  +	return TlsGetValue((DWORD)impl->key);
   #else
  -	return key;
  +	return impl->key;
   #endif
   }
   
   void ThreadSpecificData::SetData(void * data)
   {
   #ifdef LOG4CXX_HAVE_PTHREAD
  -	pthread_setspecific((pthread_key_t)key, data);
  +	pthread_setspecific((pthread_key_t)impl->key, data);
   #elif defined(LOG4CXX_HAVE_MS_THREAD)
  -	TlsSetValue((DWORD)key, data);
  +	TlsSetValue((DWORD)impl->key, data);
   #else
  -	key = data;
  +	impl->key = data;
   #endif
   }
  +
  +
  +ThreadSpecificData_ptr<int> test;
  
  
  

Re: cvs commit: logging-log4cxx/src criticalsection.cpp ndc.cpp thread.cpp threadspecificdata.cpp

Posted by Christophe de Vienne <cd...@alphacent.com>.
cdevienne@apache.org wrote:

>cdevienne    2004/08/18 14:04:57
>
>  Modified:    .        ChangeLog
>               include/log4cxx ndc.h
>               src      ndc.cpp
>

I forgot to specify : I changed NDC::threadSpecificData from 
ThreadSpecificData to ThreadSpecificData_ptr<Stack>. This will fix the 
memory leak reported a few days ago.

Regards,

Christophe

Re: cvs commit: logging-log4cxx/src criticalsection.cpp ndc.cpp thread.cpp threadspecificdata.cpp

Posted by Christophe de Vienne <cd...@alphacent.com>.
cdevienne@apache.org wrote:

>  * Hidden thread related classes members (Christophe de Vienne)
>  * Added TreadSpecificData_ptr (Christophe de Vienne)
>  * Added CriticalSection::Type so one can use fast mutexes, not only recursive (Christophe de Vienne).  
>

I tested this on linux. Tests on other platforms are welcome :-)

Christophe