Fixed ThreadPool (and dependent ORequestThread) life cycle

At least with sw_complex test under load, it happened that an ORequestThread
could still process a remote release request while the main thread was already
in exit(3).  This was because (a) ThreadPool never joined with the spawned
worker threads (which has been rectified by calling uno_threadpool_dispose(0)
from the final uno_threadpool_destroy), and (b) binaryurp::Bridge called
uno_threadpool_destroy only from its destructor (which could go as late as
exit(3)) instead of from terminate.

Additional clean up:
* Access to Bridge's threadPool_ is now cleanly controlled by mutex_ (even
  though that might not be necessary in every case).
* ThreadPool's stopDisposing got renamed to destroy, to make meaning clearer.

Change-Id: I45fa76e80e790a11065e7bf8ac9d92af2e62f262
This commit is contained in:
Stephan Bergmann
2012-05-16 22:09:21 +02:00
parent 9aad89df87
commit d015384e1d
4 changed files with 52 additions and 32 deletions

View File

@@ -26,7 +26,10 @@
*
************************************************************************/
#include "sal/config.h"
#include <boost/unordered_map.hpp>
#include <cassert>
#include <stdio.h>
#include <osl/diagnose.h>
@@ -73,7 +76,7 @@ namespace cppu_threadpool
m_lst.push_back( nDisposeId );
}
void DisposedCallerAdmin::stopDisposing( sal_Int64 nDisposeId )
void DisposedCallerAdmin::destroy( sal_Int64 nDisposeId )
{
MutexGuard guard( m_mutex );
for( DisposedCallerList::iterator ii = m_lst.begin() ;
@@ -172,9 +175,9 @@ namespace cppu_threadpool
}
}
void ThreadPool::stopDisposing( sal_Int64 nDisposeId )
void ThreadPool::destroy( sal_Int64 nDisposeId )
{
m_DisposedCallerAdmin->stopDisposing( nDisposeId );
m_DisposedCallerAdmin->destroy( nDisposeId );
}
/******************
@@ -480,13 +483,14 @@ uno_threadpool_dispose( uno_ThreadPool hPool ) SAL_THROW_EXTERN_C()
extern "C" void SAL_CALL
uno_threadpool_destroy( uno_ThreadPool hPool ) SAL_THROW_EXTERN_C()
{
ThreadPool::getInstance()->stopDisposing(
assert(hPool != 0);
ThreadPool::getInstance()->destroy(
sal::static_int_cast< sal_Int64 >(
reinterpret_cast< sal_IntPtr >(hPool)) );
if( hPool )
bool empty;
{
// special treatment for 0 !
OSL_ASSERT( g_pThreadpoolHashSet );
MutexGuard guard( Mutex::getGlobalMutex() );
@@ -496,12 +500,18 @@ uno_threadpool_destroy( uno_ThreadPool hPool ) SAL_THROW_EXTERN_C()
g_pThreadpoolHashSet->erase( ii );
delete hPool;
if( g_pThreadpoolHashSet->empty() )
empty = g_pThreadpoolHashSet->empty();
if( empty )
{
delete g_pThreadpoolHashSet;
g_pThreadpoolHashSet = 0;
}
}
if( empty )
{
uno_threadpool_dispose( 0 );
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@@ -90,7 +90,7 @@ namespace cppu_threadpool {
static DisposedCallerAdminHolder getInstance();
void dispose( sal_Int64 nDisposeId );
void stopDisposing( sal_Int64 nDisposeId );
void destroy( sal_Int64 nDisposeId );
sal_Bool isDisposed( sal_Int64 nDisposeId );
private:
@@ -109,7 +109,7 @@ namespace cppu_threadpool {
static ThreadPoolHolder getInstance();
void dispose( sal_Int64 nDisposeId );
void stopDisposing( sal_Int64 nDisposeId );
void destroy( sal_Int64 nDisposeId );
void addJob( const ByteSequence &aThreadId,
sal_Bool bAsynchron,