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