sc/source/core/data/global.cxx | 53 +++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 12 deletions(-)
New commits: commit 8aa0c1de8073d6e21f79a916153333a1284f7bb7 Author: Luboš Luňák <l.lu...@collabora.com> Date: Wed May 30 09:00:20 2018 +0200 protect one-time creation in ScGlobal::Get(Case)Collator() by a mutex Otherwise there is a race condition when calc uses threading, and lp#390983-2 sometimes crashes. Change-Id: I390928c02b8e7d74bebef2dcc98a5c21cb3a8197 Reviewed-on: https://gerrit.libreoffice.org/54795 Reviewed-by: Michael Meeks <michael.me...@collabora.com> Tested-by: Luboš Luňák <l.lu...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/55270 Reviewed-by: Luboš Luňák <l.lu...@collabora.com> diff --git a/sc/source/core/data/global.cxx b/sc/source/core/data/global.cxx index 9e4ce14e3ddf..4ab08a7bc1bd 100644 --- a/sc/source/core/data/global.cxx +++ b/sc/source/core/data/global.cxx @@ -125,6 +125,33 @@ SfxViewShell* pScActiveViewShell = nullptr; //FIXME: Make this a member sal_uInt16 nScClickMouseModifier = 0; //FIXME: This too sal_uInt16 nScFillModeMouseModifier = 0; //FIXME: And this +// Thread-safe singleton creation. Ideally rtl_Instance should be used, but that one doesn't +// allow accessing the pointer (so ScGlobal::Clear() cannot free the objects). So this function +// is basically rtl_Instance::create() that uses a given pointer. +template< typename Type, typename Function = std::function< Type*() >, + typename Guard = osl::MutexGuard, typename GuardCtor = osl::GetGlobalMutex > +static inline +Type* doubleCheckedInit( Type* pointer, Function function, GuardCtor guardCtor = osl::GetGlobalMutex()) +{ + Type* p = pointer; + if (!p) + { + Guard guard(guardCtor()); + p = pointer; + if (!p) + { + p = function(); + OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); + pointer = p; + } + } + else + { + OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); + } + return p; +} + // Static functions bool ScGlobal::HasAttrChanged( const SfxItemSet& rNewAttrs, @@ -996,21 +1023,23 @@ CalendarWrapper* ScGlobal::GetCalendar() } CollatorWrapper* ScGlobal::GetCollator() { - if ( !pCollator ) - { - pCollator = new CollatorWrapper( ::comphelper::getProcessComponentContext() ); - pCollator->loadDefaultCollator( *GetLocale(), SC_COLLATOR_IGNORES ); - } - return pCollator; + return doubleCheckedInit( pCollator, + []() + { + CollatorWrapper* p = new CollatorWrapper( ::comphelper::getProcessComponentContext() ); + p->loadDefaultCollator( *GetLocale(), SC_COLLATOR_IGNORES ); + return p; + }); } CollatorWrapper* ScGlobal::GetCaseCollator() { - if ( !pCaseCollator ) - { - pCaseCollator = new CollatorWrapper( ::comphelper::getProcessComponentContext() ); - pCaseCollator->loadDefaultCollator( *GetLocale(), 0 ); - } - return pCaseCollator; + return doubleCheckedInit( pCaseCollator, + []() + { + CollatorWrapper* p = new CollatorWrapper( ::comphelper::getProcessComponentContext() ); + p->loadDefaultCollator( *GetLocale(), 0 ); + return p; + }); } ::utl::TransliterationWrapper* ScGlobal::GetCaseTransliteration() { _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits