include/comphelper/doublecheckedinit.hxx | 64 +++++++++++++++++++++++++++++++ sc/source/core/data/global.cxx | 37 +++-------------- 2 files changed, 72 insertions(+), 29 deletions(-)
New commits: commit 1bc314b50cd760164803da98dd9ccf189d3410fb Author: Luboš Luňák <l.lu...@collabora.com> Date: Wed Jun 13 17:58:26 2018 +0200 move doubleCheckedInit() to a comphelper header file For further reuse in more source files. Change-Id: I2fcbb98a81725e14d6d433f62622d2c48d146de1 Reviewed-on: https://gerrit.libreoffice.org/55763 Tested-by: Jenkins Reviewed-by: Michael Meeks <michael.me...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/56144 Reviewed-by: Luboš Luňák <l.lu...@collabora.com> Tested-by: Luboš Luňák <l.lu...@collabora.com> diff --git a/include/comphelper/doublecheckedinit.hxx b/include/comphelper/doublecheckedinit.hxx new file mode 100644 index 000000000000..200a9c88c42b --- /dev/null +++ b/include/comphelper/doublecheckedinit.hxx @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_COMPHELPER_DOUBLECHECKEDINIT_HXX +#define INCLUDED_COMPHELPER_DOUBLECHECKEDINIT_HXX + +#include <osl/getglobalmutex.hxx> + +#include <atomic> +// HACK: <atomic> includes <stdbool.h>, which in some Clang versions does '#define bool bool', +// which confuses clang plugins. +#undef bool +#include <functional> + +namespace comphelper +{ +/** + * Thread-safe singleton creation. + * + * It is normally sufficient to create singletons using static variables in a function. + * This function is only for use cases that have a more complex lifetime of the object, + * such as when the object may require specific cleanup or may be created more times + * (e.g. when there is a "singleton" per each instance of another object). + */ +template <typename Type, typename Function = std::function<Type*()>, + typename Guard = osl::MutexGuard, typename GuardCtor = osl::GetGlobalMutex> +static inline Type* doubleCheckedInit(std::atomic<Type*>& pointer, Function function, + GuardCtor guardCtor = osl::GetGlobalMutex()) +{ + Type* p = pointer.load(std::memory_order_acquire); + if (!p) + { + Guard guard(guardCtor()); + p = pointer.load(std::memory_order_relaxed); + if (!p) + { + p = function(); + pointer.store(p, std::memory_order_release); + } + } + return p; +} + +} // namespace + +#endif // INCLUDED_COMPHELPER_DOUBLECHECKEDINIT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/global.cxx b/sc/source/core/data/global.cxx index 01b770415b03..7c05743572a2 100644 --- a/sc/source/core/data/global.cxx +++ b/sc/source/core/data/global.cxx @@ -47,6 +47,7 @@ #include <i18nlangtag/mslangid.hxx> #include <com/sun/star/lang/Locale.hpp> +#include <comphelper/doublecheckedinit.hxx> #include <comphelper/processfactory.hxx> #include <comphelper/random.hxx> #include <comphelper/string.hxx> @@ -127,28 +128,6 @@ sal_uInt16 nScFillModeMouseModifier = 0; //FIXME: And this bool ScGlobal::bThreadedGroupCalcInProgress = false; -// 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( std::atomic<Type*>& pointer, Function function, GuardCtor guardCtor = osl::GetGlobalMutex()) -{ - Type* p = pointer.load( std::memory_order_acquire ); - if (!p) - { - Guard guard(guardCtor()); - p = pointer.load( std::memory_order_relaxed ); - if (!p) - { - p = function(); - pointer.store( p, std::memory_order_release ); - } - } - return p; -} - // Static functions bool ScGlobal::HasAttrChanged( const SfxItemSet& rNewAttrs, @@ -300,12 +279,12 @@ ScAutoFormat* ScGlobal::GetOrCreateAutoFormat() LegacyFuncCollection* ScGlobal::GetLegacyFuncCollection() { - return doubleCheckedInit( pLegacyFuncCollection, []() { return new LegacyFuncCollection(); }); + return comphelper::doubleCheckedInit( pLegacyFuncCollection, []() { return new LegacyFuncCollection(); }); } ScUnoAddInCollection* ScGlobal::GetAddInCollection() { - return doubleCheckedInit( pAddInCollection, []() { return new ScUnoAddInCollection(); }); + return comphelper::doubleCheckedInit( pAddInCollection, []() { return new ScUnoAddInCollection(); }); } ScUserList* ScGlobal::GetUserList() @@ -1000,7 +979,7 @@ void ScGlobal::AddLanguage( SfxItemSet& rSet, const SvNumberFormatter& rFormatte utl::TransliterationWrapper* ScGlobal::GetpTransliteration() { - return doubleCheckedInit( pTransliteration, + return comphelper::doubleCheckedInit( pTransliteration, []() { const LanguageType eOfficeLanguage = Application::GetSettings().GetLanguageTag().getLanguageType(); @@ -1012,7 +991,7 @@ utl::TransliterationWrapper* ScGlobal::GetpTransliteration() } ::utl::TransliterationWrapper* ScGlobal::GetCaseTransliteration() { - return doubleCheckedInit( pCaseTransliteration, + return comphelper::doubleCheckedInit( pCaseTransliteration, []() { const LanguageType eOfficeLanguage = Application::GetSettings().GetLanguageTag().getLanguageType(); @@ -1042,7 +1021,7 @@ CalendarWrapper* ScGlobal::GetCalendar() } CollatorWrapper* ScGlobal::GetCollator() { - return doubleCheckedInit( pCollator, + return comphelper::doubleCheckedInit( pCollator, []() { CollatorWrapper* p = new CollatorWrapper( ::comphelper::getProcessComponentContext() ); @@ -1052,7 +1031,7 @@ CollatorWrapper* ScGlobal::GetCollator() } CollatorWrapper* ScGlobal::GetCaseCollator() { - return doubleCheckedInit( pCaseCollator, + return comphelper::doubleCheckedInit( pCaseCollator, []() { CollatorWrapper* p = new CollatorWrapper( ::comphelper::getProcessComponentContext() ); @@ -1062,7 +1041,7 @@ CollatorWrapper* ScGlobal::GetCaseCollator() } css::lang::Locale* ScGlobal::GetLocale() { - return doubleCheckedInit( pLocale, + return comphelper::doubleCheckedInit( pLocale, []() { return new css::lang::Locale( Application::GetSettings().GetLanguageTag().getLocale()); }); } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits