diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2014-11-14 16:05:37 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2014-11-14 16:19:40 +0100 |
commit | b021fdfab3a0985ba1f5380f378bf8ab97383aed (patch) | |
tree | e9c69dd093e2cc7cb335261851e43eec4a7371f5 | |
parent | 9dacd849b6ba76bab36558ad9e5d5614cd9fa29e (diff) |
cid#983623 Don't throw DisposedException past uno_threadpool_putJob
This improves on b68640c44ecdb1df59d704cc6c2bae8bb412d7d0 "Prevent creation of
new ORequestThreads during shutdown," which added throwing the DisposedException
from ThreadAdmin::add. But ThreadAdmin::m_disposed can only become true via
uno_threadpool_destroy -> ThreadPool::joinWorkers -> ThreadAdmin::join, and
ThreadAdmin::add observing that can only happen via uno_threadpool_putJob ->
ThreadPool::addJob -> ThreadPool::createThread -> ORequestThread::launch ->
ThradAdmin::add, where the bridges should ensure that uno_threadpool_destroy
does not run in parallel with uno_threadpool_putJob. So demote this from a
DisposedException to a SAL_WARN.
Change-Id: I3912ea077b7fa35827c41e82dd0a8f962ba412b6
-rw-r--r-- | cppu/source/threadpool/thread.cxx | 20 | ||||
-rw-r--r-- | cppu/source/threadpool/thread.hxx | 2 | ||||
-rw-r--r-- | cppu/source/threadpool/threadpool.cxx | 29 | ||||
-rw-r--r-- | cppu/source/threadpool/threadpool.hxx | 6 |
4 files changed, 26 insertions, 31 deletions
diff --git a/cppu/source/threadpool/thread.cxx b/cppu/source/threadpool/thread.cxx index aed132243b5d..724da750708e 100644 --- a/cppu/source/threadpool/thread.cxx +++ b/cppu/source/threadpool/thread.cxx @@ -21,12 +21,6 @@ #include <osl/diagnose.h> #include <uno/threadpool.h> -#include <com/sun/star/lang/DisposedException.hpp> -#include <com/sun/star/uno/Reference.hxx> -#include <com/sun/star/uno/XInterface.hpp> -#include <rtl/ustring.h> -#include <rtl/ustring.hxx> - #include "thread.hxx" #include "jobqueue.hxx" #include "threadpool.hxx" @@ -49,16 +43,15 @@ namespace cppu_threadpool { #endif } - void ThreadAdmin::add( rtl::Reference< ORequestThread > const & p ) + bool ThreadAdmin::add( rtl::Reference< ORequestThread > const & p ) { MutexGuard aGuard( m_mutex ); if( m_disposed ) { - throw css::lang::DisposedException( - "cppu_threadpool::ORequestThread created after" - " cppu_threadpool::ThreadAdmin has been disposed"); + return false; } m_lst.push_back( p ); + return true; } void ThreadAdmin::remove_locked( rtl::Reference< ORequestThread > const & p ) @@ -120,14 +113,16 @@ namespace cppu_threadpool { m_bAsynchron = bAsynchron; } - void ORequestThread::launch() + bool ORequestThread::launch() { // Assumption is that osl::Thread::create returns normally with a true // return value iff it causes osl::Thread::run to start executing: acquire(); ThreadAdmin & rThreadAdmin = m_aThreadPool->getThreadAdmin(); osl::ClearableMutexGuard g(rThreadAdmin.m_mutex); - rThreadAdmin.add( this ); + if (!rThreadAdmin.add( this )) { + return false; + } try { if (!create()) { throw std::runtime_error("osl::Thread::create failed"); @@ -138,6 +133,7 @@ namespace cppu_threadpool { release(); throw; } + return true; } void ORequestThread::onTerminated() diff --git a/cppu/source/threadpool/thread.hxx b/cppu/source/threadpool/thread.hxx index cc669759cf7e..2b7aa966488c 100644 --- a/cppu/source/threadpool/thread.hxx +++ b/cppu/source/threadpool/thread.hxx @@ -45,7 +45,7 @@ namespace cppu_threadpool { void setTask( JobQueue * , const ::rtl::ByteSequence & aThreadId , bool bAsynchron ); - void launch(); + bool launch(); static inline void * operator new(std::size_t size) { return SimpleReferenceObject::operator new(size); } diff --git a/cppu/source/threadpool/threadpool.cxx b/cppu/source/threadpool/threadpool.cxx index c54b539877f4..f41213b0cacc 100644 --- a/cppu/source/threadpool/threadpool.cxx +++ b/cppu/source/threadpool/threadpool.cxx @@ -27,6 +27,7 @@ #include <osl/mutex.hxx> #include <osl/thread.h> #include <rtl/instance.hxx> +#include <sal/log.hxx> #include <uno/threadpool.h> @@ -190,11 +191,10 @@ namespace cppu_threadpool m_aThreadAdmin.join(); } - void ThreadPool::createThread( JobQueue *pQueue , + bool ThreadPool::createThread( JobQueue *pQueue , const ByteSequence &aThreadId, bool bAsynchron ) { - bool bCreate = true; { // Can a thread be reused ? MutexGuard guard( m_mutexWaitingThreadList ); @@ -210,16 +210,13 @@ namespace cppu_threadpool // let the thread go osl_setCondition( pWaitingThread->condition ); - bCreate = false; + return true; } } - if( bCreate ) - { - rtl::Reference< ORequestThread > pThread( - new ORequestThread( this, pQueue , aThreadId, bAsynchron) ); - pThread->launch(); - } + rtl::Reference< ORequestThread > pThread( + new ORequestThread( this, pQueue , aThreadId, bAsynchron) ); + return pThread->launch(); } bool ThreadPool::revokeQueue( const ByteSequence &aThreadId, bool bAsynchron ) @@ -264,7 +261,7 @@ namespace cppu_threadpool } - void ThreadPool::addJob( + bool ThreadPool::addJob( const ByteSequence &aThreadId , bool bAsynchron, void *pThreadSpecificData, @@ -310,10 +307,7 @@ namespace cppu_threadpool pQueue->add( pThreadSpecificData , doRequest ); } - if( bCreateThread ) - { - createThread( pQueue , aThreadId , bAsynchron); - } + return !bCreateThread || createThread( pQueue , aThreadId , bAsynchron); } void ThreadPool::prepare( const ByteSequence &aThreadId ) @@ -470,7 +464,12 @@ uno_threadpool_putJob( void ( SAL_CALL * doRequest ) ( void *pThreadSpecificData ), sal_Bool bIsOneway ) SAL_THROW_EXTERN_C() { - getThreadPool(hPool)->addJob( pThreadId, bIsOneway, pJob ,doRequest ); + if (!getThreadPool(hPool)->addJob( pThreadId, bIsOneway, pJob ,doRequest )) + { + SAL_WARN( + "cppu", + "uno_threadpool_putJob in parallel with uno_threadpool_destroy"); + } } extern "C" void SAL_CALL diff --git a/cppu/source/threadpool/threadpool.hxx b/cppu/source/threadpool/threadpool.hxx index 83f219e0960b..b1db7b368cc2 100644 --- a/cppu/source/threadpool/threadpool.hxx +++ b/cppu/source/threadpool/threadpool.hxx @@ -102,7 +102,7 @@ namespace cppu_threadpool { ThreadAdmin(); ~ThreadAdmin (); - void add( rtl::Reference< ORequestThread > const & ); + bool add( rtl::Reference< ORequestThread > const & ); void remove( rtl::Reference< ORequestThread > const & ); void join(); @@ -126,7 +126,7 @@ namespace cppu_threadpool { void dispose( sal_Int64 nDisposeId ); void destroy( sal_Int64 nDisposeId ); - void addJob( const ::rtl::ByteSequence &aThreadId, + bool addJob( const ::rtl::ByteSequence &aThreadId, bool bAsynchron, void *pThreadSpecificData, RequestFun * doRequest ); @@ -146,7 +146,7 @@ namespace cppu_threadpool { ThreadAdmin & getThreadAdmin() { return m_aThreadAdmin; } private: - void createThread( JobQueue *pQueue, const ::rtl::ByteSequence &aThreadId, bool bAsynchron); + bool createThread( JobQueue *pQueue, const ::rtl::ByteSequence &aThreadId, bool bAsynchron); ThreadIdHashMap m_mapQueue; |