Coverage Report

Created: 2025-12-08 09:28

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
5.49M
{
46
5.49M
    Type* p = pointer.load(std::memory_order_acquire);
47
5.49M
    if (!p)
48
35.4k
    {
49
35.4k
        Guard guard(guardCtor());
50
35.4k
        p = pointer.load(std::memory_order_relaxed);
51
35.4k
        if (!p)
52
35.4k
        {
53
35.4k
            p = function();
54
35.4k
            pointer.store(p, std::memory_order_release);
55
35.4k
        }
56
35.4k
    }
57
5.49M
    return p;
58
5.49M
}
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
443k
{
46
443k
    Type* p = pointer.load(std::memory_order_acquire);
47
443k
    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
443k
    return p;
58
443k
}
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
461k
{
46
461k
    Type* p = pointer.load(std::memory_order_acquire);
47
461k
    if (!p)
48
8
    {
49
8
        Guard guard(guardCtor());
50
8
        p = pointer.load(std::memory_order_relaxed);
51
8
        if (!p)
52
8
        {
53
8
            p = function();
54
8
            pointer.store(p, std::memory_order_release);
55
8
        }
56
8
    }
57
461k
    return p;
58
461k
}
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
3.97M
{
46
3.97M
    Type* p = pointer.load(std::memory_order_acquire);
47
3.97M
    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
3.97M
    return p;
58
3.97M
}
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
34.0k
{
46
34.0k
    Type* p = pointer.load(std::memory_order_acquire);
47
34.0k
    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
34.0k
    return p;
58
34.0k
}
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)
Line
Count
Source
45
548
{
46
548
    Type* p = pointer.load(std::memory_order_acquire);
47
548
    if (!p)
48
2
    {
49
2
        Guard guard(guardCtor());
50
2
        p = pointer.load(std::memory_order_relaxed);
51
2
        if (!p)
52
2
        {
53
2
            p = function();
54
2
            pointer.store(p, std::memory_order_release);
55
2
        }
56
2
    }
57
548
    return p;
58
548
}
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
8
{
46
8
    Type* p = pointer.load(std::memory_order_acquire);
47
8
    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
8
    return p;
58
8
}
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
580k
{
46
580k
    Type* p = pointer.load(std::memory_order_acquire);
47
580k
    if (!p)
48
35.3k
    {
49
35.3k
        Guard guard(guardCtor());
50
35.3k
        p = pointer.load(std::memory_order_relaxed);
51
35.3k
        if (!p)
52
35.3k
        {
53
35.3k
            p = function();
54
35.3k
            pointer.store(p, std::memory_order_release);
55
35.3k
        }
56
35.3k
    }
57
580k
    return p;
58
580k
}
59
60
} // namespace
61
62
#endif // INCLUDED_COMPHELPER_DOUBLECHECKEDINIT_HXX
63
64
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */