Coverage Report

Created: 2026-11-06 11:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/salhelper/simplereferenceobject.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
/*
21
 * This file is part of LibreOffice published API.
22
 */
23
24
#ifndef INCLUDED_SALHELPER_SIMPLEREFERENCEOBJECT_HXX
25
#define INCLUDED_SALHELPER_SIMPLEREFERENCEOBJECT_HXX
26
27
#include "osl/interlck.h"
28
#include "salhelper/salhelperdllapi.h"
29
30
#include <cstddef>
31
#include <new>
32
33
namespace salhelper {
34
35
/** A simple base implementation for reference-counted objects.
36
37
    Classes that want to implement a reference-counting mechanism based on the
38
    acquire()/release() interface should derive from this class.
39
40
    The reason to have class local operators new and delete here is technical.
41
    Imagine a class D derived from SimpleReferenceObject, but implemented in
42
    another shared library that happens to use different global operators new
43
    and delete from those used in this shared library (which, sadly, seems to
44
    be possible with shared libraries).  Now, without the class local
45
    operators new and delete here, a code sequence like "new D" would use the
46
    global operator new as found in the other shared library, while the code
47
    sequence "delete this" in release() would use the global operator delete
48
    as found in this shared library---and these two operators would not be
49
    guaranteed to match.
50
51
    There are no overloaded operators new and delete for placement new here,
52
    because it is felt that the concept of placement new does not work well
53
    with the concept of reference-counted objects; so it seems best to simply
54
    leave those operators out.
55
56
    The same problem as with operators new and delete would also be there with
57
    operators new[] and delete[].  But since arrays of reference-counted
58
    objects are of no use, anyway, it seems best to simply
59
    define operators new[] and delete[] as deleted.
60
 */
61
class SALHELPER_DLLPUBLIC SimpleReferenceObject
62
{
63
    static const size_t nStaticFlag = 0x80000000;
64
65
public:
66
62.4M
    SimpleReferenceObject(): m_nCount(0) {}
67
68
    /** @attention
69
        If, for any individual instance of SimpleReferenceObject, the total
70
        number of calls to acquire() exceeds the total number of calls to
71
        release() by 2^31 - the object will never subsequently be released.
72
     */
73
    void acquire()
74
368M
    {
75
368M
        if (!(m_nCount & nStaticFlag))
76
368M
            osl_atomic_increment(&m_nCount);
77
368M
    }
78
79
    void release()
80
368M
    {
81
368M
        if (!(m_nCount & nStaticFlag) &&
82
368M
            osl_atomic_decrement(&m_nCount) == 0)
83
62.4M
            delete this;
84
368M
    }
85
86
    /** see general class documentation
87
     */
88
    static void * operator new(std::size_t nSize);
89
90
    /** see general class documentation
91
     */
92
    static void * operator new(std::size_t nSize,
93
                               std::nothrow_t const & rNothrow);
94
95
    /** see general class documentation
96
     */
97
    static void operator delete(void * pPtr);
98
99
    /** see general class documentation
100
     */
101
    static void operator delete(void * pPtr, std::nothrow_t const & rNothrow);
102
103
protected:
104
    virtual ~SimpleReferenceObject() COVERITY_NOEXCEPT_FALSE;
105
106
    /** mark reference count as not to be touched, and the
107
     * related object as having an indefinite lifespan.
108
     * NB. do not use if you have a non-empty destructor.
109
     */
110
    void staticize()
111
0
    {
112
0
        m_nCount |= nStaticFlag;
113
0
    }
114
115
    oslInterlockedCount m_nCount;
116
117
private:
118
    /** not implemented
119
     */
120
    SimpleReferenceObject(SimpleReferenceObject &) SAL_DELETED_FUNCTION;
121
122
    /** not implemented
123
     */
124
    void operator =(SimpleReferenceObject) SAL_DELETED_FUNCTION;
125
126
    /** see general class documentation
127
     */
128
    static void * operator new[](std::size_t) SAL_DELETED_FUNCTION;
129
130
    /** see general class documentation
131
     */
132
    static void operator delete[](void * pPtr) SAL_DELETED_FUNCTION;
133
};
134
135
}
136
137
#endif // INCLUDED_SALHELPER_SIMPLEREFERENCEOBJECT_HXX
138
139
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */