[Libreoffice-commits] core.git: sc/source
Luboš Luňák
l.lunak at collabora.com
Wed May 30 10:57:59 UTC 2018
sc/source/core/data/global.cxx | 53 +++++++++++++++++++++++++++++++----------
1 file changed, 41 insertions(+), 12 deletions(-)
New commits:
commit dfda2730a11e165f081dacbb4b5c30da3db07070
Author: Luboš Luňák <l.lunak at 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.meeks at collabora.com>
Tested-by: Luboš Luňák <l.lunak at 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()
{
More information about the Libreoffice-commits
mailing list