Author: carnold Date: Thu Apr 27 12:33:41 2006 New Revision: 397620 URL: http://svn.apache.org/viewcvs?rev=397620&view=rev Log: Bug LOGCXX-132: various segmentation faults
Added: logging/log4cxx/trunk/tests/src/threadtest.cpp Modified: logging/log4cxx/trunk/include/log4cxx/helpers/objectptr.h logging/log4cxx/trunk/include/log4cxx/helpers/thread.h logging/log4cxx/trunk/include/log4cxx/logger.h logging/log4cxx/trunk/include/log4cxx/spi/loggingevent.h logging/log4cxx/trunk/src/asyncappender.cpp logging/log4cxx/trunk/src/filewatchdog.cpp logging/log4cxx/trunk/src/hierarchy.cpp logging/log4cxx/trunk/src/loggingevent.cpp logging/log4cxx/trunk/src/objectptr.cpp logging/log4cxx/trunk/src/socketappenderskeleton.cpp logging/log4cxx/trunk/src/sockethubappender.cpp logging/log4cxx/trunk/src/telnetappender.cpp logging/log4cxx/trunk/src/thread.cpp logging/log4cxx/trunk/tests/src/Makefile.am Modified: logging/log4cxx/trunk/include/log4cxx/helpers/objectptr.h URL: http://svn.apache.org/viewcvs/logging/log4cxx/trunk/include/log4cxx/helpers/objectptr.h?rev=397620&r1=397619&r2=397620&view=diff ============================================================================== --- logging/log4cxx/trunk/include/log4cxx/helpers/objectptr.h (original) +++ logging/log4cxx/trunk/include/log4cxx/helpers/objectptr.h Thu Apr 27 12:33:41 2006 @@ -27,6 +27,7 @@ class LOG4CXX_EXPORT ObjectPtrBase { public: static void checkNull(const int& null); + static void* exchange(volatile void** destination, void* newValue); }; @@ -37,23 +38,9 @@ template<typename InterfacePtr> ObjectPtrT(const InterfacePtr& p) : p(0) { - cast(p); + cast(p); } - // Disable conversion using ObjectPtrT* specialization of - // template<typename InterfacePtr> ObjectPtrT(const InterfacePtr& p) -/* template<> explicit ObjectPtrT(ObjectPtrT* const & p) throw(IllegalArgumentException) - { - if (p == 0) - { - throw IllegalArgumentException(String()); - } - else - { - this->p = p->p; - this->p->addRef(); - } - }*/ ObjectPtrT(const int& null) //throw(IllegalArgumentException) : p(0) @@ -87,35 +74,27 @@ { this->p->releaseRef(); } - this->p = 0; + this->p = 0; } // Operators template<typename InterfacePtr> ObjectPtrT& operator=(const InterfacePtr& p) { - cast(p); - return *this; + cast(p); + return *this; } - ObjectPtrT& operator=(const ObjectPtrT& p) - { - if (this->p != p.p) - { - if (this->p != 0) - { - this->p->releaseRef(); - } - - this->p = p.p; - - if (this->p != 0) - { - this->p->addRef(); - } - } - + ObjectPtrT& operator=(const ObjectPtrT& p) { + T* newPtr = (T*) p.p; + if (newPtr != 0) { + newPtr->addRef(); + } + void* oldPtr = ObjectPtrBase::exchange((volatile void**) &this->p, newPtr); + if (oldPtr != 0) { + ((T*) oldPtr)->releaseRef(); + } return *this; - } + } ObjectPtrT& operator=(const int& null) //throw(IllegalArgumentException) { @@ -123,65 +102,45 @@ // throws IllegalArgumentException if null != 0 // ObjectPtrBase::checkNull(null); - - if (this->p != 0) - { - this->p->releaseRef(); - this->p = 0; - } - - return *this; - } - - ObjectPtrT& operator=(T* p) - { - if (this->p != p) - { - if (this->p != 0) - { - this->p->releaseRef(); - } - - this->p = p; - - if (this->p != 0) - { - this->p->addRef(); - } - } - - return *this; + void* oldPtr = ObjectPtrBase::exchange((volatile void**) &this->p, 0); + if (oldPtr != 0) { + ((T*) oldPtr)->releaseRef(); + } + return *this; + } + + ObjectPtrT& operator=(T* p) { + if (p != 0) { + p->addRef(); + } + void* oldPtr = ObjectPtrBase::exchange((volatile void**) &this->p, p); + if (oldPtr != 0) { + ((T*)oldPtr)->releaseRef(); + } + return *this; } bool operator==(const ObjectPtrT& p) const { return (this->p == p.p); } bool operator!=(const ObjectPtrT& p) const { return (this->p != p.p); } bool operator==(const T* p) const { return (this->p == p); } bool operator!=(const T* p) const { return (this->p != p); } - T* operator->() {return p; } - const T* operator->() const {return p; } - T& operator*() const {return *p; } - operator T*() const {return p; } - - template<typename InterfacePtr> void cast(const InterfacePtr& p) - { - if (this->p != 0) - { - this->p->releaseRef(); - this->p = 0; - } + T* operator->() {return (T*) p; } + const T* operator->() const {return (const T*) p; } + T& operator*() const {return (T&) *p; } + operator T*() const {return (T*) p; } - if (p != 0) + template<typename InterfacePtr> void cast(const InterfacePtr& p) { - this->p = (T*)p->cast(T::getStaticClass()); - if (this->p != 0) + T* newPtr = 0; + if (p != 0) { - this->p->addRef(); + newPtr = (T*)p->cast(T::getStaticClass()); } + operator=(newPtr); } - } - public: + private: T * p; }; } Modified: logging/log4cxx/trunk/include/log4cxx/helpers/thread.h URL: http://svn.apache.org/viewcvs/logging/log4cxx/trunk/include/log4cxx/helpers/thread.h?rev=397620&r1=397619&r2=397620&view=diff ============================================================================== --- logging/log4cxx/trunk/include/log4cxx/helpers/thread.h (original) +++ logging/log4cxx/trunk/include/log4cxx/helpers/thread.h Thu Apr 27 12:33:41 2006 @@ -18,6 +18,7 @@ #define _LOG4CXX_HELPERS_THREAD_H #include <log4cxx/log4cxx.h> +#include <log4cxx/helpers/pool.h> #if !defined(LOG4CXX_THREAD_FUNC) #if defined(_WIN32) @@ -41,8 +42,7 @@ Thread(); ~Thread(); - void run(log4cxx::helpers::Pool& pool, - void* (LOG4CXX_THREAD_FUNC *start)(log4cxx_thread_t* thread, void* data), + void run(void* (LOG4CXX_THREAD_FUNC *start)(log4cxx_thread_t* thread, void* data), void* data); void stop(); void join(); @@ -56,8 +56,9 @@ static void sleep(log4cxx_time_t duration); private: + Pool p; log4cxx_thread_t* thread; - volatile bool finished; + volatile bool alive; Thread(const Thread&); Thread& operator=(const Thread&); }; Modified: logging/log4cxx/trunk/include/log4cxx/logger.h URL: http://svn.apache.org/viewcvs/logging/log4cxx/trunk/include/log4cxx/logger.h?rev=397620&r1=397619&r2=397620&view=diff ============================================================================== --- logging/log4cxx/trunk/include/log4cxx/logger.h (original) +++ logging/log4cxx/trunk/include/log4cxx/logger.h Thu Apr 27 12:33:41 2006 @@ -258,8 +258,7 @@ /** Return the logger name. */ - inline const LogString& getName() const - { return name; } + const LogString getName() const { return name; } void getName(std::string& name) const; #if LOG4CXX_HAS_WCHAR_T void getName(std::wstring& name) const; Modified: logging/log4cxx/trunk/include/log4cxx/spi/loggingevent.h URL: http://svn.apache.org/viewcvs/logging/log4cxx/trunk/include/log4cxx/spi/loggingevent.h?rev=397620&r1=397619&r2=397620&view=diff ============================================================================== --- logging/log4cxx/trunk/include/log4cxx/spi/loggingevent.h (original) +++ logging/log4cxx/trunk/include/log4cxx/spi/loggingevent.h Thu Apr 27 12:33:41 2006 @@ -92,7 +92,7 @@ { return level; } /** Return the name of the #logger. */ - const LogString& getLoggerName() const; + const LogString getLoggerName() const; /** Return the #message for this logging event. */ inline const LogString& getMessage() const Modified: logging/log4cxx/trunk/src/asyncappender.cpp URL: http://svn.apache.org/viewcvs/logging/log4cxx/trunk/src/asyncappender.cpp?rev=397620&r1=397619&r2=397620&view=diff ============================================================================== --- logging/log4cxx/trunk/src/asyncappender.cpp (original) +++ logging/log4cxx/trunk/src/asyncappender.cpp Thu Apr 27 12:33:41 2006 @@ -45,7 +45,7 @@ thread(), locationInfo(true), aai(new AppenderAttachableImpl()) { - thread.run(pool, dispatch, this); + thread.run(dispatch, this); } AsyncAppender::~AsyncAppender() Modified: logging/log4cxx/trunk/src/filewatchdog.cpp URL: http://svn.apache.org/viewcvs/logging/log4cxx/trunk/src/filewatchdog.cpp?rev=397620&r1=397619&r2=397620&view=diff ============================================================================== --- logging/log4cxx/trunk/src/filewatchdog.cpp (original) +++ logging/log4cxx/trunk/src/filewatchdog.cpp Thu Apr 27 12:33:41 2006 @@ -84,7 +84,7 @@ { checkAndConfigure(); - thread.run(pool, run, this); + thread.run(run, this); } #endif Modified: logging/log4cxx/trunk/src/hierarchy.cpp URL: http://svn.apache.org/viewcvs/logging/log4cxx/trunk/src/hierarchy.cpp?rev=397620&r1=397619&r2=397620&view=diff ============================================================================== --- logging/log4cxx/trunk/src/hierarchy.cpp (original) +++ logging/log4cxx/trunk/src/hierarchy.cpp Thu Apr 27 12:33:41 2006 @@ -37,7 +37,7 @@ IMPLEMENT_LOG4CXX_OBJECT(Hierarchy) -Hierarchy::Hierarchy(const LoggerPtr& root) : root(root), +Hierarchy::Hierarchy(const LoggerPtr& root) : root(root), emittedNoAppenderWarning(false), emittedNoResourceBundleWarning(false), mutex(), configured(false), thresholdInt(Level::ALL_INT), threshold(Level::getAll()) { @@ -256,6 +256,8 @@ void Hierarchy::shutdown() { + synchronized sync(mutex); + setConfigured(false); LoggerPtr root = getRootLogger(); @@ -284,15 +286,16 @@ void Hierarchy::updateParents(LoggerPtr& logger) { - const LogString& name = logger->getName(); + const LogString name(logger->getName()); int length = name.size(); bool parentFound = false; //tcout << _T("UpdateParents called for ") << name << std::endl; // if name = "w.x.y.z", loop thourgh "w.x.y", "w.x" and "w", but not "w.x.y.z" - for(size_t i = name.find_last_of(L'.', length-1); i != LogString::npos; - i = name.find_last_of(L'.', i-1)) + for(size_t i = name.find_last_of(LOG4CXX_STR('.'), length-1); + i != LogString::npos; + i = name.find_last_of(LOG4CXX_STR('.'), i-1)) { LogString substr = name.substr(0, i); //tcout << _T("UpdateParents processing ") << substr << std::endl; Modified: logging/log4cxx/trunk/src/loggingevent.cpp URL: http://svn.apache.org/viewcvs/logging/log4cxx/trunk/src/loggingevent.cpp?rev=397620&r1=397619&r2=397620&view=diff ============================================================================== --- logging/log4cxx/trunk/src/loggingevent.cpp (original) +++ logging/log4cxx/trunk/src/loggingevent.cpp Thu Apr 27 12:33:41 2006 @@ -79,7 +79,7 @@ } } -const LogString& LoggingEvent::getLoggerName() const +const LogString LoggingEvent::getLoggerName() const { return logger->getName(); } Modified: logging/log4cxx/trunk/src/objectptr.cpp URL: http://svn.apache.org/viewcvs/logging/log4cxx/trunk/src/objectptr.cpp?rev=397620&r1=397619&r2=397620&view=diff ============================================================================== --- logging/log4cxx/trunk/src/objectptr.cpp (original) +++ logging/log4cxx/trunk/src/objectptr.cpp Thu Apr 27 12:33:41 2006 @@ -16,6 +16,7 @@ #include <log4cxx/helpers/objectptr.h> #include <log4cxx/helpers/exception.h> +#include <apr_atomic.h> using namespace log4cxx::helpers; @@ -25,5 +26,9 @@ throw IllegalArgumentException("Attempt to set pointer to a non-zero numeric value."); } +} + +void* ObjectPtrBase::exchange(volatile void** destination, void* newValue) { + return apr_atomic_casptr(destination, newValue, (const void*) *destination); } Modified: logging/log4cxx/trunk/src/socketappenderskeleton.cpp URL: http://svn.apache.org/viewcvs/logging/log4cxx/trunk/src/socketappenderskeleton.cpp?rev=397620&r1=397619&r2=397620&view=diff ============================================================================== --- logging/log4cxx/trunk/src/socketappenderskeleton.cpp (original) +++ logging/log4cxx/trunk/src/socketappenderskeleton.cpp Thu Apr 27 12:33:41 2006 @@ -200,7 +200,7 @@ { synchronized sync(mutex); if (thread.isActive()) { - thread.run(pool, monitor, this); + thread.run(monitor, this); } } Modified: logging/log4cxx/trunk/src/sockethubappender.cpp URL: http://svn.apache.org/viewcvs/logging/log4cxx/trunk/src/sockethubappender.cpp?rev=397620&r1=397619&r2=397620&view=diff ============================================================================== --- logging/log4cxx/trunk/src/sockethubappender.cpp (original) +++ logging/log4cxx/trunk/src/sockethubappender.cpp Thu Apr 27 12:33:41 2006 @@ -148,7 +148,7 @@ void SocketHubAppender::startServer() { - thread.run(pool, monitor, this); + thread.run(monitor, this); } void* APR_THREAD_FUNC SocketHubAppender::monitor(log4cxx_thread_t* thread, void* data) { Modified: logging/log4cxx/trunk/src/telnetappender.cpp URL: http://svn.apache.org/viewcvs/logging/log4cxx/trunk/src/telnetappender.cpp?rev=397620&r1=397619&r2=397620&view=diff ============================================================================== --- logging/log4cxx/trunk/src/telnetappender.cpp (original) +++ logging/log4cxx/trunk/src/telnetappender.cpp Thu Apr 27 12:33:41 2006 @@ -55,7 +55,7 @@ if (serverSocket == NULL) { serverSocket = new ServerSocket(port); } - sh.run(pool, acceptConnections, this); + sh.run(acceptConnections, this); } void TelnetAppender::setOption(const LogString& option, Modified: logging/log4cxx/trunk/src/thread.cpp URL: http://svn.apache.org/viewcvs/logging/log4cxx/trunk/src/thread.cpp?rev=397620&r1=397619&r2=397620&view=diff ============================================================================== --- logging/log4cxx/trunk/src/thread.cpp (original) +++ logging/log4cxx/trunk/src/thread.cpp Thu Apr 27 12:33:41 2006 @@ -22,20 +22,19 @@ using namespace log4cxx::helpers; using namespace log4cxx; -Thread::Thread() : thread(NULL), finished(false) { +Thread::Thread() : thread(NULL), alive(false) { } Thread::~Thread() { -#if APR_HAS_THREADS +#if APR_HAS_THREADS join(); #endif } #if APR_HAS_THREADS -void Thread::run(log4cxx::helpers::Pool& p, - void* (LOG4CXX_THREAD_FUNC *start)(log4cxx_thread_t* thread, void* data), +void Thread::run(void* (LOG4CXX_THREAD_FUNC *start)(log4cxx_thread_t* thread, void* data), void* data) { - if (thread != NULL && !finished) { + if (thread != NULL && alive) { throw ThreadException(0); } apr_threadattr_t* attrs; @@ -43,7 +42,8 @@ if (stat != APR_SUCCESS) { throw ThreadException(stat); } - stat = apr_thread_create((apr_thread_t**) &thread, attrs, + alive = true; + stat = apr_thread_create((apr_thread_t**) &thread, attrs, (apr_thread_start_t) start, data, (apr_pool_t*) p.getAPRPool()); if (stat != APR_SUCCESS) { throw ThreadException(stat); @@ -51,9 +51,9 @@ } void Thread::stop() { - if (thread != NULL && !finished) { + if (thread != NULL && alive) { apr_status_t stat = apr_thread_exit((apr_thread_t*) thread, 0); - finished = true; + alive = false; thread = NULL; if (stat != APR_SUCCESS) { throw ThreadException(stat); @@ -62,10 +62,10 @@ } void Thread::join() { - if (thread != NULL && !finished) { + if (thread != NULL && alive) { apr_status_t startStat; apr_status_t stat = apr_thread_join(&startStat, (apr_thread_t*) thread); - finished = true; + alive = false; thread = NULL; if (stat != APR_SUCCESS) { throw ThreadException(stat); @@ -75,7 +75,7 @@ #endif void Thread::ending() { - finished = true; + alive = false; } Modified: logging/log4cxx/trunk/tests/src/Makefile.am URL: http://svn.apache.org/viewcvs/logging/log4cxx/trunk/tests/src/Makefile.am?rev=397620&r1=397619&r2=397620&view=diff ============================================================================== --- logging/log4cxx/trunk/tests/src/Makefile.am (original) +++ logging/log4cxx/trunk/tests/src/Makefile.am Thu Apr 27 12:33:41 2006 @@ -39,7 +39,7 @@ helpers/stringhelpertestcase.cpp \ helpers/timezonetestcase.cpp \ helpers/transcodertestcase.cpp \ - helpers/unicodehelpertestcase.cpp + helpers/unicodehelpertestcase.cpp net_tests = \ net/smtpappendertestcase.cpp \ @@ -128,7 +128,8 @@ rollingfileappendertestcase.cpp\ streamtestcase.cpp\ writerappendertestcase.cpp \ - ndctestcase.cpp + ndctestcase.cpp \ + threadtest.cpp testsuite_LDADD = \ $(top_builddir)/src/liblog4cxx.la