Revert "Don't use global mutex here for local mutex initialization"
This reverts commit 0752de6850, as it causes
initialization-order-fiasco, e.g. when building Gallery_backgrounds:
> ==913067==ERROR: AddressSanitizer: initialization-order-fiasco on address 0x7fee04a01ba0 at pc 0x7fee0467257e bp 0x7ffd678aaa30 sp 0x7ffd678aaa28
> READ of size 8 at 0x7fee04a01ba0 thread T0
> #0 in osl::Mutex::acquire() at include/osl/mutex.hxx:57:37 (instdir/program/libuno_cppu.so.3 +0x32957d)
> #1 in osl::Guard<osl::Mutex>::Guard(osl::Mutex&) at include/osl/mutex.hxx:138:17 (instdir/program/libuno_cppu.so.3 +0x316a4e)
> #2 in typelib_typedescriptionreference_new at cppu/source/typelib/typelib.cxx:2130:16 (instdir/program/libuno_cppu.so.3 +0x3e2d9a)
> #3 in typelib_static_type_getByTypeClass at cppu/source/typelib/static_types.cxx:266:17 (instdir/program/libuno_cppu.so.3 +0x3c04af)
> #4 in cppu::detail::getTypeFromTypeClass(_typelib_TypeClass) at include/cppu/unotype.hxx:110:9 (instdir/program/libxolo.so +0x2e87e61)
> #5 in cppu::detail::cppu_detail_getUnoType(signed char const*) at include/cppu/unotype.hxx:136:12 (instdir/program/libxolo.so +0x2e902dd)
> #6 in cppu::UnoType<signed char>::get() at include/cppu/unotype.hxx:296:16 (instdir/program/libxolo.so +0x2e90278)
> #7 in com::sun::star::uno::Type const& cppu::getTypeFavourUnsigned<signed char>(signed char const*) at include/cppu/unotype.hxx:321:12 (instdir/program/libxolo.so +0x2e90218)
> #8 in com::sun::star::uno::Type const& cppu::getTypeFavourUnsigned<signed char>(com::sun::star::uno::Sequence<signed char> const*) at include/com/sun/star/uno/Sequence.hxx:292:14 (instdir/program/libxolo.so +0x2e9001a)
> #9 in com::sun::star::uno::Sequence<signed char>::Sequence() at include/com/sun/star/uno/Sequence.hxx:59:26 (instdir/program/libxolo.so +0x2e8ff58)
> #10 in __cxx_global_var_init at xmloff/source/core/fasttokenhandler.cxx:35:48 (instdir/program/libxolo.so +0x3455d3f)
> #11 in _GLOBAL__sub_I_fasttokenhandler.cxx at xmloff/source/core/fasttokenhandler.cxx (instdir/program/libxolo.so +0x3455da4)
> #12 in call_init.part.0 at <null> (/lib64/ld-linux-x86-64.so.2 +0x108dd)
> #13 in _dl_init at <null> (/lib64/ld-linux-x86-64.so.2 +0x109c7)
> #14 at <null> (/lib64/ld-linux-x86-64.so.2 +0x10c9)
>
> 0x7fee04a01ba0 is located 0 bytes inside of global variable '(anonymous namespace)::s_Mutex' defined in 'cppu/source/typelib/typelib.cxx:286:12' (0x7fee04a01ba0) of size 8
> registered at:
> #0 in __asan_register_globals at ~/github.com/llvm/llvm-project/compiler-rt/lib/asan/asan_globals.cpp:360:3 (instdir/program/gengal.bin +0x28698d)
> #1 in asan.module_ctor at <null> (instdir/program/libuno_cppu.so.3 +0x42649b)
Change-Id: Iab673f048bfb76165de2c47c2db63e339069fd17
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110228
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
This commit is contained in:
@@ -175,6 +175,10 @@ struct TypeDescriptor_Init_Impl
|
||||
std::unique_ptr<CallbackSet_Impl> pCallbacks;
|
||||
// A cache to hold descriptions
|
||||
std::unique_ptr<TypeDescriptionList_Impl> pCache;
|
||||
// The mutex to guard all type library accesses
|
||||
std::unique_ptr<Mutex> pMutex;
|
||||
|
||||
inline Mutex & getMutex();
|
||||
|
||||
inline void callChain( typelib_TypeDescription ** ppRet, rtl_uString * pName );
|
||||
|
||||
@@ -197,6 +201,17 @@ struct TypeDescriptor_Init_Impl
|
||||
|
||||
}
|
||||
|
||||
inline Mutex & TypeDescriptor_Init_Impl::getMutex()
|
||||
{
|
||||
if( !pMutex )
|
||||
{
|
||||
MutexGuard aGuard( Mutex::getGlobalMutex() );
|
||||
if( !pMutex )
|
||||
pMutex.reset(new Mutex());
|
||||
}
|
||||
return * pMutex;
|
||||
}
|
||||
|
||||
inline void TypeDescriptor_Init_Impl::callChain(
|
||||
typelib_TypeDescription ** ppRet, rtl_uString * pName )
|
||||
{
|
||||
@@ -280,13 +295,7 @@ TypeDescriptor_Init_Impl::~TypeDescriptor_Init_Impl()
|
||||
pCallbacks.reset();
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
// The mutex to guard all type library accesses, goes before Init to be available in its dtor
|
||||
osl::Mutex s_Mutex;
|
||||
|
||||
struct Init : public rtl::Static< TypeDescriptor_Init_Impl, Init > {};
|
||||
}
|
||||
namespace { struct Init : public rtl::Static< TypeDescriptor_Init_Impl, Init > {}; }
|
||||
|
||||
extern "C" void SAL_CALL typelib_typedescription_registerCallback(
|
||||
void * pContext, typelib_typedescription_Callback pCallback )
|
||||
@@ -294,7 +303,7 @@ extern "C" void SAL_CALL typelib_typedescription_registerCallback(
|
||||
{
|
||||
// todo mt safe: guard is no solution, can not acquire while calling callback!
|
||||
TypeDescriptor_Init_Impl &rInit = Init::get();
|
||||
// OslGuard aGuard( s_Mutex );
|
||||
// OslGuard aGuard( rInit.getMutex() );
|
||||
if( !rInit.pCallbacks )
|
||||
rInit.pCallbacks.reset(new CallbackSet_Impl);
|
||||
rInit.pCallbacks->push_back( CallbackEntry( pContext, pCallback ) );
|
||||
@@ -309,7 +318,7 @@ extern "C" void SAL_CALL typelib_typedescription_revokeCallback(
|
||||
if( rInit.pCallbacks )
|
||||
{
|
||||
// todo mt safe: guard is no solution, can not acquire while calling callback!
|
||||
// OslGuard aGuard( s_Mutex );
|
||||
// OslGuard aGuard( rInit.getMutex() );
|
||||
CallbackEntry aEntry( pContext, pCallback );
|
||||
rInit.pCallbacks->erase(std::remove(rInit.pCallbacks->begin(), rInit.pCallbacks->end(), aEntry),
|
||||
rInit.pCallbacks->end());
|
||||
@@ -342,7 +351,7 @@ static void typelib_typedescription_initTables(
|
||||
}
|
||||
}
|
||||
|
||||
MutexGuard aGuard(s_Mutex);
|
||||
MutexGuard aGuard( Init::get().getMutex() );
|
||||
if( pTD->bComplete )
|
||||
return;
|
||||
|
||||
@@ -456,7 +465,7 @@ bool complete(typelib_TypeDescription ** ppTypeDescr, bool initTables) {
|
||||
OSL_ASSERT( pTD == *ppTypeDescr ); // has to merge into existing one
|
||||
|
||||
// insert into the cache
|
||||
MutexGuard aGuard(s_Mutex);
|
||||
MutexGuard aGuard( rInit.getMutex() );
|
||||
if( !rInit.pCache )
|
||||
rInit.pCache.reset( new TypeDescriptionList_Impl );
|
||||
if( static_cast<sal_Int32>(rInit.pCache->size()) >= nCacheSize )
|
||||
@@ -1355,7 +1364,7 @@ extern "C" void SAL_CALL typelib_typedescription_release(
|
||||
if( pTD->pWeakRef )
|
||||
{
|
||||
{
|
||||
MutexGuard aGuard(s_Mutex);
|
||||
MutexGuard aGuard( rInit.getMutex() );
|
||||
// remove this description from the weak reference
|
||||
pTD->pWeakRef->pType = nullptr;
|
||||
}
|
||||
@@ -1367,7 +1376,7 @@ extern "C" void SAL_CALL typelib_typedescription_release(
|
||||
// this description is a reference too, so remove it from the hash table
|
||||
if( rInit.pWeakMap )
|
||||
{
|
||||
MutexGuard aGuard(s_Mutex);
|
||||
MutexGuard aGuard( rInit.getMutex() );
|
||||
WeakMap_Impl::iterator aIt = rInit.pWeakMap->find( pTD->pTypeName->buffer );
|
||||
if( aIt != rInit.pWeakMap->end() && static_cast<void *>((*aIt).second) == static_cast<void *>(pTD) )
|
||||
{
|
||||
@@ -1417,7 +1426,7 @@ extern "C" void SAL_CALL typelib_typedescription_register(
|
||||
{
|
||||
// connect the description with the weak reference
|
||||
TypeDescriptor_Init_Impl &rInit = Init::get();
|
||||
ClearableMutexGuard aGuard(s_Mutex);
|
||||
ClearableMutexGuard aGuard( rInit.getMutex() );
|
||||
|
||||
typelib_TypeDescriptionReference * pTDR = nullptr;
|
||||
typelib_typedescriptionreference_getByName( &pTDR, (*ppNewDescription)->pTypeName );
|
||||
@@ -1901,7 +1910,7 @@ extern "C" void SAL_CALL typelib_typedescription_getByName(
|
||||
if( !bInited )
|
||||
{
|
||||
// guard against multi thread access
|
||||
MutexGuard aGuard(s_Mutex);
|
||||
MutexGuard aGuard( rInit.getMutex() );
|
||||
if( !bInited )
|
||||
{
|
||||
// avoid recursion during the next ...new calls
|
||||
@@ -1948,7 +1957,7 @@ extern "C" void SAL_CALL typelib_typedescription_getByName(
|
||||
{
|
||||
{
|
||||
// guard against multi thread access
|
||||
MutexGuard aGuard(s_Mutex);
|
||||
MutexGuard aGuard( rInit.getMutex() );
|
||||
// pTDR->pType->pWeakRef == 0 means that the description is empty
|
||||
if( pTDR->pType && pTDR->pType->pWeakRef )
|
||||
{
|
||||
@@ -2045,7 +2054,7 @@ extern "C" void SAL_CALL typelib_typedescription_getByName(
|
||||
typelib_typedescription_register( ppRet );
|
||||
|
||||
// insert into the cache
|
||||
MutexGuard aGuard(s_Mutex);
|
||||
MutexGuard aGuard( rInit.getMutex() );
|
||||
if( !rInit.pCache )
|
||||
rInit.pCache.reset( new TypeDescriptionList_Impl );
|
||||
if( static_cast<sal_Int32>(rInit.pCache->size()) >= nCacheSize )
|
||||
@@ -2101,7 +2110,7 @@ extern "C" void SAL_CALL typelib_typedescriptionreference_new(
|
||||
typelib_typedescription_register( &pRet );
|
||||
|
||||
// insert into the cache
|
||||
MutexGuard aGuard(s_Mutex);
|
||||
MutexGuard aGuard( rInit.getMutex() );
|
||||
if( !rInit.pCache )
|
||||
rInit.pCache.reset( new TypeDescriptionList_Impl );
|
||||
if( static_cast<sal_Int32>(rInit.pCache->size()) >= nCacheSize )
|
||||
@@ -2127,7 +2136,7 @@ extern "C" void SAL_CALL typelib_typedescriptionreference_new(
|
||||
return;
|
||||
}
|
||||
|
||||
MutexGuard aGuard(s_Mutex);
|
||||
MutexGuard aGuard( rInit.getMutex() );
|
||||
typelib_typedescriptionreference_getByName( ppTDR, pTypeName );
|
||||
if( *ppTDR )
|
||||
return;
|
||||
@@ -2184,7 +2193,7 @@ extern "C" void SAL_CALL typelib_typedescriptionreference_release(
|
||||
TypeDescriptor_Init_Impl &rInit = Init::get();
|
||||
if( rInit.pWeakMap )
|
||||
{
|
||||
MutexGuard aGuard(s_Mutex);
|
||||
MutexGuard aGuard( rInit.getMutex() );
|
||||
WeakMap_Impl::iterator aIt = rInit.pWeakMap->find( pRef->pTypeName->buffer );
|
||||
if( aIt != rInit.pWeakMap->end() && (*aIt).second == pRef )
|
||||
{
|
||||
@@ -2227,7 +2236,7 @@ extern "C" void SAL_CALL typelib_typedescriptionreference_getDescription(
|
||||
}
|
||||
|
||||
{
|
||||
MutexGuard aGuard(s_Mutex);
|
||||
MutexGuard aGuard( Init::get().getMutex() );
|
||||
// pRef->pType->pWeakRef == 0 means that the description is empty
|
||||
if( pRef->pType && pRef->pType->pWeakRef )
|
||||
{
|
||||
@@ -2267,7 +2276,7 @@ extern "C" void typelib_typedescriptionreference_getByName(
|
||||
if( !rInit.pWeakMap )
|
||||
return;
|
||||
|
||||
MutexGuard aGuard(s_Mutex);
|
||||
MutexGuard aGuard( rInit.getMutex() );
|
||||
WeakMap_Impl::const_iterator aIt = rInit.pWeakMap->find( pName->buffer );
|
||||
if( aIt == rInit.pWeakMap->end() )
|
||||
return;
|
||||
@@ -2322,7 +2331,7 @@ extern "C" void SAL_CALL typelib_setCacheSize( sal_Int32 nNewSize )
|
||||
return;
|
||||
|
||||
TypeDescriptor_Init_Impl &rInit = Init::get();
|
||||
MutexGuard aGuard(s_Mutex);
|
||||
MutexGuard aGuard( rInit.getMutex() );
|
||||
if ((nNewSize < nCacheSize) && rInit.pCache)
|
||||
{
|
||||
while (static_cast<sal_Int32>(rInit.pCache->size()) != nNewSize)
|
||||
|
||||
Reference in New Issue
Block a user