#i107490# cppu lifecycle cleanup

This commit is contained in:
Caolán McNamara
2010-10-11 10:41:50 +01:00
parent 2f68ee59b2
commit 521a9f6f76
11 changed files with 96 additions and 110 deletions

View File

@@ -106,11 +106,9 @@ static typelib_InterfaceTypeDescription * get_type_XCurrentContext()
1, aParameters, 1, pExceptions );
typelib_typedescription_register( (typelib_TypeDescription**)&pMethod );
typelib_typedescription_release( (typelib_TypeDescription*)pMethod );
#if ! defined CPPU_LEAK_STATIC_DATA
// another static ref
// another static ref:
++reinterpret_cast< typelib_TypeDescription * >( pTD )->
nStaticRefCount;
#endif
s_type_XCurrentContext = pTD;
}
}

View File

@@ -42,6 +42,7 @@ namespace cppu_threadpool {
m_cndWait( osl_createCondition() )
{
osl_resetCondition( m_cndWait );
m_DisposedCallerAdmin = DisposedCallerAdmin::getInstance();
}
JobQueue::~JobQueue()
@@ -68,7 +69,7 @@ namespace cppu_threadpool {
{
// synchronize with the dispose calls
MutexGuard guard( m_mutex );
if( DisposedCallerAdmin::getInstance()->isDisposed( nDisposeId ) )
if( m_DisposedCallerAdmin->isDisposed( nDisposeId ) )
{
return 0;
}

View File

@@ -34,6 +34,8 @@
#include <osl/conditn.h>
#include <osl/mutex.hxx>
#include <boost/shared_ptr.hpp>
namespace cppu_threadpool
{
extern "C" typedef void (SAL_CALL RequestFun)(void *);
@@ -48,6 +50,9 @@ namespace cppu_threadpool
typedef ::std::list < sal_Int64 > CallStackList;
class DisposedCallerAdmin;
typedef boost::shared_ptr<DisposedCallerAdmin> DisposedCallerAdminHolder;
class JobQueue
{
public:
@@ -73,6 +78,7 @@ namespace cppu_threadpool
sal_Int32 m_nToDo;
sal_Bool m_bSuspended;
oslCondition m_cndWait;
DisposedCallerAdminHolder m_DisposedCallerAdmin;
};
}

View File

@@ -31,6 +31,8 @@
#include <osl/diagnose.h>
#include <uno/threadpool.h>
#include <rtl/instance.hxx>
#include "thread.hxx"
#include "jobqueue.hxx"
#include "threadpool.hxx"
@@ -98,20 +100,17 @@ namespace cppu_threadpool {
} while( pCurrent );
}
ThreadAdmin* ThreadAdmin::getInstance()
struct theThreadAdmin : public rtl::StaticWithInit< ThreadAdminHolder, theThreadAdmin >
{
static ThreadAdmin *pThreadAdmin = 0;
if( ! pThreadAdmin )
{
MutexGuard guard( Mutex::getGlobalMutex() );
if( ! pThreadAdmin )
{
static ThreadAdmin admin;
pThreadAdmin = &admin;
}
ThreadAdminHolder operator () () {
ThreadAdminHolder aRet(new ThreadAdmin());
return aRet;
}
return pThreadAdmin;
};
ThreadAdminHolder& ThreadAdmin::getInstance()
{
return theThreadAdmin::get();
}
// ----------------------------------------------------------------------------------
@@ -119,12 +118,13 @@ namespace cppu_threadpool {
const ByteSequence &aThreadId,
sal_Bool bAsynchron )
: m_thread( 0 )
, m_aThreadAdmin( ThreadAdmin::getInstance() )
, m_pQueue( pQueue )
, m_aThreadId( aThreadId )
, m_bAsynchron( bAsynchron )
, m_bDeleteSelf( sal_True )
{
ThreadAdmin::getInstance()->add( this );
m_aThreadAdmin->add( this );
}
@@ -166,7 +166,7 @@ namespace cppu_threadpool {
void ORequestThread::onTerminated()
{
ThreadAdmin::getInstance()->remove( this );
m_aThreadAdmin->remove( this );
if( m_bDeleteSelf )
{
delete this;
@@ -175,6 +175,8 @@ namespace cppu_threadpool {
void ORequestThread::run()
{
ThreadPoolHolder theThreadPool = cppu_threadpool::ThreadPool::getInstance();
while ( m_pQueue )
{
if( ! m_bAsynchron )
@@ -197,7 +199,7 @@ namespace cppu_threadpool {
if( m_pQueue->isEmpty() )
{
ThreadPool::getInstance()->revokeQueue( m_aThreadId , m_bAsynchron );
theThreadPool->revokeQueue( m_aThreadId , m_bAsynchron );
// Note : revokeQueue might have failed because m_pQueue.isEmpty()
// may be false (race).
}
@@ -211,7 +213,7 @@ namespace cppu_threadpool {
uno_releaseIdFromCurrentThread();
}
cppu_threadpool::ThreadPool::getInstance()->waitInPool( this );
theThreadPool->waitInPool( this );
}
}
}

View File

@@ -37,6 +37,8 @@
namespace cppu_threadpool {
class JobQueue;
class ThreadAdmin;
typedef boost::shared_ptr<ThreadAdmin> ThreadAdminHolder;
//-----------------------------------------
// private thread class for the threadpool
@@ -61,6 +63,7 @@ namespace cppu_threadpool {
private:
oslThread m_thread;
ThreadAdminHolder m_aThreadAdmin;
JobQueue *m_pQueue;
::rtl::ByteSequence m_aThreadId;
sal_Bool m_bAsynchron;
@@ -71,7 +74,7 @@ namespace cppu_threadpool {
{
public:
~ThreadAdmin ();
static ThreadAdmin *getInstance();
static ThreadAdminHolder &getInstance();
void add( ORequestThread * );
void remove( ORequestThread * );
void join();

View File

@@ -33,6 +33,7 @@
#include <osl/diagnose.h>
#include <osl/mutex.hxx>
#include <osl/thread.h>
#include <rtl/instance.hxx>
#include <uno/threadpool.h>
@@ -44,19 +45,17 @@ using namespace ::osl;
namespace cppu_threadpool
{
DisposedCallerAdmin *DisposedCallerAdmin::getInstance()
struct theDisposedCallerAdmin :
public rtl::StaticWithInit< DisposedCallerAdminHolder, theDisposedCallerAdmin >
{
static DisposedCallerAdmin *pDisposedCallerAdmin = 0;
if( ! pDisposedCallerAdmin )
{
MutexGuard guard( Mutex::getGlobalMutex() );
if( ! pDisposedCallerAdmin )
{
static DisposedCallerAdmin admin;
pDisposedCallerAdmin = &admin;
}
DisposedCallerAdminHolder operator () () {
return DisposedCallerAdminHolder(new DisposedCallerAdmin());
}
return pDisposedCallerAdmin;
};
DisposedCallerAdminHolder DisposedCallerAdmin::getInstance()
{
return theDisposedCallerAdmin::get();
}
DisposedCallerAdmin::~DisposedCallerAdmin()
@@ -107,6 +106,21 @@ namespace cppu_threadpool
//-------------------------------------------------------------------------------
struct theThreadPool :
public rtl::StaticWithInit< ThreadPoolHolder, theThreadPool >
{
ThreadPoolHolder operator () () {
ThreadPoolHolder aRet(new ThreadPool());
return aRet;
}
};
ThreadPool::ThreadPool()
{
m_DisposedCallerAdmin = DisposedCallerAdmin::getInstance();
}
ThreadPool::~ThreadPool()
{
#if OSL_DEBUG_LEVEL > 1
@@ -116,19 +130,9 @@ namespace cppu_threadpool
}
#endif
}
ThreadPool *ThreadPool::getInstance()
ThreadPoolHolder ThreadPool::getInstance()
{
static ThreadPool *pThreadPool = 0;
if( ! pThreadPool )
{
MutexGuard guard( Mutex::getGlobalMutex() );
if( ! pThreadPool )
{
static ThreadPool pool;
pThreadPool = &pool;
}
}
return pThreadPool;
return theThreadPool::get();
}
@@ -136,7 +140,7 @@ namespace cppu_threadpool
{
if( nDisposeId )
{
DisposedCallerAdmin::getInstance()->dispose( nDisposeId );
m_DisposedCallerAdmin->dispose( nDisposeId );
MutexGuard guard( m_mutex );
for( ThreadIdHashMap::iterator ii = m_mapQueue.begin() ;
@@ -171,7 +175,7 @@ namespace cppu_threadpool
void ThreadPool::stopDisposing( sal_Int64 nDisposeId )
{
DisposedCallerAdmin::getInstance()->stopDisposing( nDisposeId );
m_DisposedCallerAdmin->stopDisposing( nDisposeId );
}
/******************
@@ -400,7 +404,7 @@ struct uno_ThreadPool_Hash
typedef ::std::hash_set< uno_ThreadPool, uno_ThreadPool_Hash, uno_ThreadPool_Equal > ThreadpoolHashSet;
typedef ::std::hash_map< uno_ThreadPool, ThreadPoolHolder, uno_ThreadPool_Hash, uno_ThreadPool_Equal > ThreadpoolHashSet;
static ThreadpoolHashSet *g_pThreadpoolHashSet;
@@ -420,7 +424,7 @@ uno_threadpool_create() SAL_THROW_EXTERN_C()
// Just ensure that the handle is unique in the process (via heap)
uno_ThreadPool h = new struct _uno_ThreadPool;
g_pThreadpoolHashSet->insert( h );
g_pThreadpoolHashSet->insert( ThreadpoolHashSet::value_type(h, ThreadPool::getInstance()) );
return h;
}

View File

@@ -30,6 +30,8 @@
#include <rtl/byteseq.hxx>
#include <boost/shared_ptr.hpp>
#include "jobqueue.hxx"
@@ -76,12 +78,15 @@ namespace cppu_threadpool {
typedef ::std::list < struct ::cppu_threadpool::WaitingThread * > WaitingThreadList;
class DisposedCallerAdmin;
typedef boost::shared_ptr<DisposedCallerAdmin> DisposedCallerAdminHolder;
class DisposedCallerAdmin
{
public:
~DisposedCallerAdmin();
static DisposedCallerAdmin *getInstance();
static DisposedCallerAdminHolder getInstance();
void dispose( sal_Int64 nDisposeId );
void stopDisposing( sal_Int64 nDisposeId );
@@ -92,11 +97,15 @@ namespace cppu_threadpool {
DisposedCallerList m_lst;
};
class ThreadPool;
typedef boost::shared_ptr<ThreadPool> ThreadPoolHolder;
class ThreadPool
{
public:
ThreadPool();
~ThreadPool();
static ThreadPool *getInstance();
static ThreadPoolHolder getInstance();
void dispose( sal_Int64 nDisposeId );
void stopDisposing( sal_Int64 nDisposeId );
@@ -124,6 +133,8 @@ namespace cppu_threadpool {
::osl::Mutex m_mutexWaitingThreadList;
WaitingThreadList m_lstThreads;
DisposedCallerAdminHolder m_DisposedCallerAdmin;
};
} // end namespace cppu_threadpool

View File

@@ -168,10 +168,8 @@ typelib_TypeDescriptionReference ** SAL_CALL typelib_static_type_getByTypeClass(
OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM("type") );
::typelib_typedescriptionreference_new(
&s_aTypes[typelib_TypeClass_TYPE], typelib_TypeClass_TYPE, sTypeName.pData );
#ifndef CPPU_LEAK_STATIC_DATA
// another static ref
// another static ref:
++s_aTypes[typelib_TypeClass_TYPE]->nStaticRefCount;
#endif
}
// any
if (! s_aTypes[typelib_TypeClass_ANY])
@@ -179,10 +177,8 @@ typelib_TypeDescriptionReference ** SAL_CALL typelib_static_type_getByTypeClass(
OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM("any") );
::typelib_typedescriptionreference_new(
&s_aTypes[typelib_TypeClass_ANY], typelib_TypeClass_ANY, sTypeName.pData );
#ifndef CPPU_LEAK_STATIC_DATA
// another static ref
// another static ref:
++s_aTypes[typelib_TypeClass_ANY]->nStaticRefCount;
#endif
}
// string
if (! s_aTypes[typelib_TypeClass_STRING])
@@ -190,10 +186,8 @@ typelib_TypeDescriptionReference ** SAL_CALL typelib_static_type_getByTypeClass(
OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM("string") );
::typelib_typedescriptionreference_new(
&s_aTypes[typelib_TypeClass_STRING], typelib_TypeClass_STRING, sTypeName.pData );
#ifndef CPPU_LEAK_STATIC_DATA
// another static ref
// another static ref:
++s_aTypes[typelib_TypeClass_STRING]->nStaticRefCount;
#endif
}
// XInterface
if (! s_aTypes[typelib_TypeClass_INTERFACE])
@@ -220,10 +214,8 @@ typelib_TypeDescriptionReference ** SAL_CALL typelib_static_type_getByTypeClass(
::typelib_typedescription_register( (typelib_TypeDescription **)&pTD );
::typelib_typedescriptionreference_acquire(
s_aTypes[typelib_TypeClass_INTERFACE] = ((typelib_TypeDescription *)pTD)->pWeakRef );
#ifndef CPPU_LEAK_STATIC_DATA
// another static ref
// another static ref:
++s_aTypes[typelib_TypeClass_INTERFACE]->nStaticRefCount;
#endif
::typelib_typedescription_release( (typelib_TypeDescription*)pTD );
::typelib_typedescriptionreference_release( pMembers[0] );
@@ -252,10 +244,8 @@ typelib_TypeDescriptionReference ** SAL_CALL typelib_static_type_getByTypeClass(
typelib_typedescription_register( &pTD1 );
typelib_typedescriptionreference_acquire(
s_aTypes[typelib_TypeClass_EXCEPTION] = pTD1->pWeakRef );
#ifndef CPPU_LEAK_STATIC_DATA
// another static ref
// another static ref:
++s_aTypes[typelib_TypeClass_EXCEPTION]->nStaticRefCount;
#endif
// RuntimeException
OUString sTypeName2( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.RuntimeException") );
::typelib_typedescription_new(
@@ -302,10 +292,8 @@ typelib_TypeDescriptionReference ** SAL_CALL typelib_static_type_getByTypeClass(
{
OUString aTypeName( OUString::createFromAscii( s_aTypeNames[eTypeClass] ) );
::typelib_typedescriptionreference_new( &s_aTypes[eTypeClass], eTypeClass, aTypeName.pData );
#ifndef CPPU_LEAK_STATIC_DATA
// another static ref
// another static ref:
++s_aTypes[eTypeClass]->nStaticRefCount;
#endif
}
}
}
@@ -327,10 +315,8 @@ void SAL_CALL typelib_static_type_init(
OUString aTypeName( OUString::createFromAscii( pTypeName ) );
::typelib_typedescriptionreference_new( ppRef, eTypeClass, aTypeName.pData );
#ifndef CPPU_LEAK_STATIC_DATA
// another static ref
// another static ref:
++((*ppRef)->nStaticRefCount);
#endif
}
}
}
@@ -364,10 +350,8 @@ void SAL_CALL typelib_static_sequence_type_init(
*ppRef = (typelib_TypeDescriptionReference *)pReg;
OSL_ASSERT( *ppRef == pReg->pWeakRef );
}
#ifndef CPPU_LEAK_STATIC_DATA
// another static ref
// another static ref:
++((*ppRef)->nStaticRefCount);
#endif
}
}
}
@@ -450,10 +434,8 @@ void init(
*ppRef = (typelib_TypeDescriptionReference *)pReg;
OSL_ASSERT( *ppRef == pReg->pWeakRef );
}
#ifndef CPPU_LEAK_STATIC_DATA
// another static ref
// another static ref:
++((*ppRef)->nStaticRefCount);
#endif
}
}
}
@@ -551,10 +533,8 @@ void SAL_CALL typelib_static_mi_interface_type_init(
*ppRef = (typelib_TypeDescriptionReference *)pReg;
OSL_ASSERT( *ppRef == pReg->pWeakRef );
}
#ifndef CPPU_LEAK_STATIC_DATA
// another static ref
// another static ref:
++((*ppRef)->nStaticRefCount);
#endif
}
}
}
@@ -593,10 +573,8 @@ void SAL_CALL typelib_static_enum_type_init(
*ppRef = (typelib_TypeDescriptionReference *)pReg;
OSL_ASSERT( *ppRef == pReg->pWeakRef );
}
#ifndef CPPU_LEAK_STATIC_DATA
// another static ref
// another static ref:
++(*(sal_Int32 *)&(*ppRef)->pReserved);
#endif
}
}
}
@@ -660,10 +638,8 @@ void SAL_CALL typelib_static_array_type_init(
OSL_ASSERT( *ppRef == pReg->pWeakRef );
} else
delete [] pDimensions;
#ifndef CPPU_LEAK_STATIC_DATA
// another static ref
// another static ref:
++((*ppRef)->nStaticRefCount);
#endif
}
}
}

View File

@@ -264,17 +264,9 @@ inline void TypeDescriptor_Init_Impl::callChain(
}
}
// never called
#if defined(CPPU_LEAK_STATIC_DATA) && defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)
static void dumb_sunpro5_must_have_dtor_stl_hashmap_code_if_compiled_with_minus_g() SAL_THROW( () )
{
delete (WeakMap_Impl *)0xbeef1e;
}
#endif
//__________________________________________________________________________________________________
TypeDescriptor_Init_Impl::~TypeDescriptor_Init_Impl() SAL_THROW( () )
{
#ifndef CPPU_LEAK_STATIC_DATA
if( pCache )
{
TypeDescriptionList_Impl::const_iterator aIt = pCache->begin();
@@ -303,7 +295,6 @@ TypeDescriptor_Init_Impl::~TypeDescriptor_Init_Impl() SAL_THROW( () )
for( i = 0; i < nSize; i++ )
{
typelib_TypeDescriptionReference * pTDR = ppTDR[i];
sal_Int32 nStaticCounts = pTDR->nStaticRefCount;
OSL_ASSERT( pTDR->nRefCount > pTDR->nStaticRefCount );
pTDR->nRefCount -= pTDR->nStaticRefCount;
@@ -355,9 +346,7 @@ TypeDescriptor_Init_Impl::~TypeDescriptor_Init_Impl() SAL_THROW( () )
#endif
delete pCallbacks;
pCallbacks = 0;
#endif // CPPU_LEAK_STATIC_DATA
// todo: maybe into leak block
if( pMutex )
{
delete pMutex;

View File

@@ -139,6 +139,7 @@ struct EnvironmentsData
::osl::Mutex mutex;
OUString2EnvironmentMap aName2EnvMap;
EnvironmentsData() : isDisposing(false) {}
~EnvironmentsData();
inline void getEnvironment(
@@ -147,6 +148,8 @@ struct EnvironmentsData
inline void getRegisteredEnvironments(
uno_Environment *** pppEnvs, sal_Int32 * pnLen,
uno_memAlloc memAlloc, const OUString & rEnvDcp );
bool isDisposing;
};
namespace
@@ -595,9 +598,14 @@ static void SAL_CALL defenv_harden(
*ppHardEnv = 0;
}
EnvironmentsData & rData = theEnvironmentsData::get();
if (rData.isDisposing)
return;
uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
{
::osl::MutexGuard guard( theEnvironmentsData::get().mutex );
::osl::MutexGuard guard( rData.mutex );
if (1 == ::osl_incrementInterlockedCount( &that->nRef )) // is dead
{
that->nRef = 0;
@@ -914,6 +922,7 @@ static void SAL_CALL unoenv_releaseInterface(
EnvironmentsData::~EnvironmentsData()
{
::osl::MutexGuard guard( mutex );
isDisposing = true;
for ( OUString2EnvironmentMap::const_iterator iPos( aName2EnvMap.begin() );
iPos != aName2EnvMap.end(); ++iPos )
@@ -928,11 +937,7 @@ EnvironmentsData::~EnvironmentsData()
#if OSL_DEBUG_LEVEL > 1
::uno_dumpEnvironment( 0, pHard, 0 );
#endif
#if defined CPPU_LEAK_STATIC_DATA
pHard->environmentDisposing = 0; // set to null => wont be called
#else
(*pHard->dispose)( pHard ); // send explicit dispose
#endif
(*pHard->release)( pHard );
}
}

View File

@@ -51,12 +51,3 @@ CFLAGS += -Ob0
.ENDIF
.ENDIF
# other stuff
.IF "$(cppu_no_leak)" == ""
.IF "$(bndchk)" == ""
CFLAGS += -DCPPU_LEAK_STATIC_DATA
.ENDIF
.ENDIF