Coverage Report

Created: 2026-10-14 09:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/comphelper/doublecheckedinit.hxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#ifndef INCLUDED_COMPHELPER_DOUBLECHECKEDINIT_HXX
21
#define INCLUDED_COMPHELPER_DOUBLECHECKEDINIT_HXX
22
23
#include <osl/getglobalmutex.hxx>
24
25
#include <atomic>
26
// HACK: <atomic> includes <stdbool.h>, which in some Clang versions does '#define bool bool',
27
// which confuses clang plugins.
28
#undef bool
29
#include <functional>
30
31
namespace comphelper
32
{
33
/**
34
 * Thread-safe singleton creation.
35
 *
36
 * It is normally sufficient to create singletons using static variables in a function.
37
 * This function is only for use cases that have a more complex lifetime of the object,
38
 * such as when the object may require specific cleanup or may be created more times
39
 * (e.g. when there is a "singleton" per each instance of another object).
40
 */
41
template <typename Type, typename Function = std::function<Type*()>,
42
          typename Guard = osl::MutexGuard, typename GuardCtor = osl::GetGlobalMutex>
43
static inline Type* doubleCheckedInit(std::atomic<Type*>& pointer, Function function,
44
                                      GuardCtor guardCtor = osl::GetGlobalMutex())
45
4.28M
{
46
4.28M
    Type* p = pointer.load(std::memory_order_acquire);
47
4.28M
    if (!p)
48
18.5k
    {
49
18.5k
        Guard guard(guardCtor());
50
18.5k
        p = pointer.load(std::memory_order_relaxed);
51
18.5k
        if (!p)
52
18.5k
        {
53
18.5k
            p = function();
54
18.5k
            pointer.store(p, std::memory_order_release);
55
18.5k
        }
56
18.5k
    }
57
4.28M
    return p;
58
4.28M
}
global.cxx:LegacyFuncCollection* comphelper::doubleCheckedInit<LegacyFuncCollection, ScGlobal::GetLegacyFuncCollection()::$_0, osl::Guard<osl::Mutex>, osl::GetGlobalMutex>(std::__1::atomic<LegacyFuncCollection*>&, ScGlobal::GetLegacyFuncCollection()::$_0, osl::GetGlobalMutex)
Line
Count
Source
45
1.06M
{
46
1.06M
    Type* p = pointer.load(std::memory_order_acquire);
47
1.06M
    if (!p)
48
5
    {
49
5
        Guard guard(guardCtor());
50
5
        p = pointer.load(std::memory_order_relaxed);
51
5
        if (!p)
52
5
        {
53
5
            p = function();
54
5
            pointer.store(p, std::memory_order_release);
55
5
        }
56
5
    }
57
1.06M
    return p;
58
1.06M
}
global.cxx:ScUnoAddInCollection* comphelper::doubleCheckedInit<ScUnoAddInCollection, ScGlobal::GetAddInCollection()::$_0, osl::Guard<osl::Mutex>, osl::GetGlobalMutex>(std::__1::atomic<ScUnoAddInCollection*>&, ScGlobal::GetAddInCollection()::$_0, osl::GetGlobalMutex)
Line
Count
Source
45
1.08M
{
46
1.08M
    Type* p = pointer.load(std::memory_order_acquire);
47
1.08M
    if (!p)
48
6
    {
49
6
        Guard guard(guardCtor());
50
6
        p = pointer.load(std::memory_order_relaxed);
51
6
        if (!p)
52
6
        {
53
6
            p = function();
54
6
            pointer.store(p, std::memory_order_release);
55
6
        }
56
6
    }
57
1.08M
    return p;
58
1.08M
}
Unexecuted instantiation: global.cxx:ScUnitConverter* comphelper::doubleCheckedInit<ScUnitConverter, ScGlobal::GetUnitConverter()::$_0, osl::Guard<osl::Mutex>, osl::GetGlobalMutex>(std::__1::atomic<ScUnitConverter*>&, ScGlobal::GetUnitConverter()::$_0, osl::GetGlobalMutex)
global.cxx:utl::TransliterationWrapper* comphelper::doubleCheckedInit<utl::TransliterationWrapper, ScGlobal::GetTransliteration()::$_0, osl::Guard<osl::Mutex>, osl::GetGlobalMutex>(std::__1::atomic<utl::TransliterationWrapper*>&, ScGlobal::GetTransliteration()::$_0, osl::GetGlobalMutex)
Line
Count
Source
45
1.84M
{
46
1.84M
    Type* p = pointer.load(std::memory_order_acquire);
47
1.84M
    if (!p)
48
3
    {
49
3
        Guard guard(guardCtor());
50
3
        p = pointer.load(std::memory_order_relaxed);
51
3
        if (!p)
52
3
        {
53
3
            p = function();
54
3
            pointer.store(p, std::memory_order_release);
55
3
        }
56
3
    }
57
1.84M
    return p;
58
1.84M
}
Unexecuted instantiation: global.cxx:utl::TransliterationWrapper* comphelper::doubleCheckedInit<utl::TransliterationWrapper, ScGlobal::GetCaseTransliteration()::$_0, osl::Guard<osl::Mutex>, osl::GetGlobalMutex>(std::__1::atomic<utl::TransliterationWrapper*>&, ScGlobal::GetCaseTransliteration()::$_0, osl::GetGlobalMutex)
global.cxx:CollatorWrapper* comphelper::doubleCheckedInit<CollatorWrapper, ScGlobal::GetCollator()::$_0, osl::Guard<osl::Mutex>, (anonymous namespace)::GetMutex>(std::__1::atomic<CollatorWrapper*>&, ScGlobal::GetCollator()::$_0, (anonymous namespace)::GetMutex)
Line
Count
Source
45
28.5k
{
46
28.5k
    Type* p = pointer.load(std::memory_order_acquire);
47
28.5k
    if (!p)
48
1
    {
49
1
        Guard guard(guardCtor());
50
1
        p = pointer.load(std::memory_order_relaxed);
51
1
        if (!p)
52
1
        {
53
1
            p = function();
54
1
            pointer.store(p, std::memory_order_release);
55
1
        }
56
1
    }
57
28.5k
    return p;
58
28.5k
}
Unexecuted instantiation: global.cxx:CollatorWrapper* comphelper::doubleCheckedInit<CollatorWrapper, ScGlobal::GetCaseCollator()::$_0, osl::Guard<osl::Mutex>, (anonymous namespace)::GetMutex>(std::__1::atomic<CollatorWrapper*>&, ScGlobal::GetCaseCollator()::$_0, (anonymous namespace)::GetMutex)
global.cxx:com::sun::star::lang::Locale* comphelper::doubleCheckedInit<com::sun::star::lang::Locale, ScGlobal::GetLocale()::$_0, osl::Guard<osl::Mutex>, osl::GetGlobalMutex>(std::__1::atomic<com::sun::star::lang::Locale*>&, ScGlobal::GetLocale()::$_0, osl::GetGlobalMutex)
Line
Count
Source
45
4
{
46
4
    Type* p = pointer.load(std::memory_order_acquire);
47
4
    if (!p)
48
3
    {
49
3
        Guard guard(guardCtor());
50
3
        p = pointer.load(std::memory_order_relaxed);
51
3
        if (!p)
52
3
        {
53
3
            p = function();
54
3
            pointer.store(p, std::memory_order_release);
55
3
        }
56
3
    }
57
4
    return p;
58
4
}
Unexecuted instantiation: global.cxx:sc::SharedStringPoolPurge* comphelper::doubleCheckedInit<sc::SharedStringPoolPurge, ScGlobal::GetSharedStringPoolPurge()::$_0, osl::Guard<osl::Mutex>, osl::GetGlobalMutex>(std::__1::atomic<sc::SharedStringPoolPurge*>&, ScGlobal::GetSharedStringPoolPurge()::$_0, osl::GetGlobalMutex)
documentlinkmgr.cxx:sfx2::LinkManager* comphelper::doubleCheckedInit<sfx2::LinkManager, sc::DocumentLinkManager::getLinkManager(bool)::$_0, osl::Guard<osl::Mutex>, osl::GetGlobalMutex>(std::__1::atomic<sfx2::LinkManager*>&, sc::DocumentLinkManager::getLinkManager(bool)::$_0, osl::GetGlobalMutex)
Line
Count
Source
45
258k
{
46
258k
    Type* p = pointer.load(std::memory_order_acquire);
47
258k
    if (!p)
48
18.5k
    {
49
18.5k
        Guard guard(guardCtor());
50
18.5k
        p = pointer.load(std::memory_order_relaxed);
51
18.5k
        if (!p)
52
18.5k
        {
53
18.5k
            p = function();
54
18.5k
            pointer.store(p, std::memory_order_release);
55
18.5k
        }
56
18.5k
    }
57
258k
    return p;
58
258k
}
59
60
} // namespace
61
62
#endif // INCLUDED_COMPHELPER_DOUBLECHECKEDINIT_HXX
63
64
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */