Coverage Report

Created: 2026-05-16 09:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/cppuhelper/source/implbase.cxx
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
#include <cppuhelper/compbase_ex.hxx>
21
#include <cppuhelper/exc_hlp.hxx>
22
#include <osl/diagnose.h>
23
#include <sal/log.hxx>
24
25
#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
26
#include <com/sun/star/uno/RuntimeException.hpp>
27
28
using namespace ::osl;
29
using namespace ::com::sun::star;
30
using namespace ::com::sun::star::uno;
31
32
33
namespace cppu
34
{
35
36
// WeakComponentImplHelperBase
37
38
WeakComponentImplHelperBase::WeakComponentImplHelperBase( Mutex & rMutex )
39
3.74M
    : rBHelper( rMutex )
40
3.74M
{
41
3.74M
}
42
43
WeakComponentImplHelperBase::~WeakComponentImplHelperBase()
44
3.73M
{
45
3.73M
}
46
47
void WeakComponentImplHelperBase::disposing()
48
115k
{
49
115k
}
50
51
Any WeakComponentImplHelperBase::queryInterface( Type const & rType )
52
135M
{
53
135M
    if (rType == cppu::UnoType<lang::XComponent>::get())
54
2.81M
    {
55
2.81M
        void * p = static_cast< lang::XComponent * >( this );
56
2.81M
        return Any( &p, rType );
57
2.81M
    }
58
133M
    return OWeakObject::queryInterface( rType );
59
135M
}
60
61
void WeakComponentImplHelperBase::acquire()
62
    noexcept
63
248M
{
64
248M
    OWeakObject::acquire();
65
248M
}
66
67
void WeakComponentImplHelperBase::release()
68
    noexcept
69
247M
{
70
247M
    if (osl_atomic_decrement( &m_refCount ) != 0)
71
244M
        return;
72
73
    // ensure no other references are created, via the weak connection point, from now on
74
3.72M
    disposeWeakConnectionPoint();
75
    // restore reference count:
76
3.72M
    osl_atomic_increment( &m_refCount );
77
3.72M
    if (! rBHelper.bDisposed) {
78
2.79M
        try {
79
2.79M
            dispose();
80
2.79M
        }
81
2.79M
        catch (RuntimeException const& exc) { // don't break throw ()
82
0
            SAL_WARN( "cppuhelper", exc );
83
0
        }
84
2.79M
        OSL_ASSERT( rBHelper.bDisposed );
85
2.79M
    }
86
3.72M
    OWeakObject::release();
87
3.72M
}
88
89
void WeakComponentImplHelperBase::dispose()
90
4.22M
{
91
4.22M
    ClearableMutexGuard aGuard( rBHelper.rMutex );
92
4.22M
    if (rBHelper.bDisposed || rBHelper.bInDispose)
93
484k
        return;
94
95
3.73M
    rBHelper.bInDispose = true;
96
3.73M
    aGuard.clear();
97
3.73M
    try
98
3.73M
    {
99
        // side effect: keeping a reference to this
100
3.73M
        lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
101
3.73M
        try
102
3.73M
        {
103
3.73M
            rBHelper.aLC.disposeAndClear( aEvt );
104
3.73M
            disposing();
105
3.73M
        }
106
3.73M
        catch (...)
107
3.73M
        {
108
0
            MutexGuard aGuard2( rBHelper.rMutex );
109
            // bDisposed and bInDispose must be set in this order:
110
0
            rBHelper.bDisposed = true;
111
0
            rBHelper.bInDispose = false;
112
0
            throw;
113
0
        }
114
3.73M
        MutexGuard aGuard2( rBHelper.rMutex );
115
        // bDisposed and bInDispose must be set in this order:
116
3.73M
        rBHelper.bDisposed = true;
117
3.73M
        rBHelper.bInDispose = false;
118
3.73M
    }
119
3.73M
    catch (RuntimeException &)
120
3.73M
    {
121
0
        throw;
122
0
    }
123
3.73M
    catch (Exception & exc)
124
3.73M
    {
125
0
        css::uno::Any anyEx = cppu::getCaughtException();
126
0
        throw lang::WrappedTargetRuntimeException(
127
0
            "unexpected UNO exception caught: " + exc.Message,
128
0
            nullptr, anyEx );
129
0
    }
130
3.73M
}
131
132
void WeakComponentImplHelperBase::addEventListener(
133
    Reference< lang::XEventListener > const & xListener )
134
51.3k
{
135
51.3k
    ClearableMutexGuard aGuard( rBHelper.rMutex );
136
51.3k
    if (rBHelper.bDisposed || rBHelper.bInDispose)
137
0
    {
138
0
        aGuard.clear();
139
0
        lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
140
0
        xListener->disposing( aEvt );
141
0
    }
142
51.3k
    else
143
51.3k
    {
144
51.3k
        rBHelper.addListener( cppu::UnoType<decltype(xListener)>::get(), xListener );
145
51.3k
    }
146
51.3k
}
147
148
void WeakComponentImplHelperBase::removeEventListener(
149
    Reference< lang::XEventListener > const & xListener )
150
30.5k
{
151
30.5k
    rBHelper.removeListener( cppu::UnoType<decltype(xListener)>::get(), xListener );
152
30.5k
}
153
154
// WeakAggComponentImplHelperBase
155
156
WeakAggComponentImplHelperBase::WeakAggComponentImplHelperBase( Mutex & rMutex )
157
10.3k
    : rBHelper( rMutex )
158
10.3k
{
159
10.3k
}
160
161
WeakAggComponentImplHelperBase::~WeakAggComponentImplHelperBase()
162
10.3k
{
163
10.3k
}
164
165
void WeakAggComponentImplHelperBase::disposing()
166
0
{
167
0
}
168
169
Any WeakAggComponentImplHelperBase::queryInterface( Type const & rType )
170
258k
{
171
258k
    return OWeakAggObject::queryInterface( rType );
172
258k
}
173
174
Any WeakAggComponentImplHelperBase::queryAggregation( Type const & rType )
175
93.0k
{
176
93.0k
    if (rType == cppu::UnoType<lang::XComponent>::get())
177
10.3k
    {
178
10.3k
        void * p = static_cast< lang::XComponent * >( this );
179
10.3k
        return Any( &p, rType );
180
10.3k
    }
181
82.7k
    return OWeakAggObject::queryAggregation( rType );
182
93.0k
}
183
184
void WeakAggComponentImplHelperBase::acquire()
185
    noexcept
186
10.2M
{
187
10.2M
    OWeakAggObject::acquire();
188
10.2M
}
189
190
void WeakAggComponentImplHelperBase::release()
191
    noexcept
192
10.2M
{
193
10.2M
    Reference<XInterface> const xDelegator_(xDelegator);
194
10.2M
    if (xDelegator_.is()) {
195
0
        OWeakAggObject::release();
196
0
    }
197
10.2M
    else if (osl_atomic_decrement( &m_refCount ) == 0) {
198
        // ensure no other references are created, via the weak connection point, from now on
199
10.3k
        disposeWeakConnectionPoint();
200
        // restore reference count:
201
10.3k
        osl_atomic_increment( &m_refCount );
202
10.3k
        if (! rBHelper.bDisposed) {
203
0
            try {
204
0
                dispose();
205
0
            }
206
0
            catch (RuntimeException const& exc) { // don't break throw ()
207
0
                SAL_WARN( "cppuhelper", exc );
208
0
            }
209
0
            OSL_ASSERT( rBHelper.bDisposed );
210
0
        }
211
10.3k
        OWeakAggObject::release();
212
10.3k
    }
213
10.2M
}
214
215
void WeakAggComponentImplHelperBase::dispose()
216
10.3k
{
217
10.3k
    ClearableMutexGuard aGuard( rBHelper.rMutex );
218
10.3k
    if (rBHelper.bDisposed || rBHelper.bInDispose)
219
0
        return;
220
221
10.3k
    rBHelper.bInDispose = true;
222
10.3k
    aGuard.clear();
223
10.3k
    try
224
10.3k
    {
225
        // side effect: keeping a reference to this
226
10.3k
        lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
227
10.3k
        try
228
10.3k
        {
229
10.3k
            rBHelper.aLC.disposeAndClear( aEvt );
230
10.3k
            disposing();
231
10.3k
        }
232
10.3k
        catch (...)
233
10.3k
        {
234
0
            MutexGuard aGuard2( rBHelper.rMutex );
235
            // bDisposed and bInDispose must be set in this order:
236
0
            rBHelper.bDisposed = true;
237
0
            rBHelper.bInDispose = false;
238
0
            throw;
239
0
        }
240
10.3k
        MutexGuard aGuard2( rBHelper.rMutex );
241
        // bDisposed and bInDispose must be set in this order:
242
10.3k
        rBHelper.bDisposed = true;
243
10.3k
        rBHelper.bInDispose = false;
244
10.3k
    }
245
10.3k
    catch (RuntimeException &)
246
10.3k
    {
247
0
        throw;
248
0
    }
249
10.3k
    catch (Exception & exc)
250
10.3k
    {
251
0
        css::uno::Any anyEx = cppu::getCaughtException();
252
0
        throw lang::WrappedTargetRuntimeException(
253
0
            "unexpected UNO exception caught: " + exc.Message,
254
0
            nullptr, anyEx );
255
0
    }
256
10.3k
}
257
258
void WeakAggComponentImplHelperBase::addEventListener(
259
    Reference< lang::XEventListener > const & xListener )
260
0
{
261
0
    ClearableMutexGuard aGuard( rBHelper.rMutex );
262
0
    if (rBHelper.bDisposed || rBHelper.bInDispose)
263
0
    {
264
0
        aGuard.clear();
265
0
        lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
266
0
        xListener->disposing( aEvt );
267
0
    }
268
0
    else
269
0
    {
270
0
        rBHelper.addListener( cppu::UnoType<decltype(xListener)>::get(), xListener );
271
0
    }
272
0
}
273
274
void WeakAggComponentImplHelperBase::removeEventListener(
275
    Reference< lang::XEventListener > const & xListener )
276
0
{
277
    // if we have disposed, then we have cleared the list already
278
0
    MutexGuard aGuard( rBHelper.rMutex );
279
0
    if (!rBHelper.bDisposed)
280
0
        rBHelper.removeListener( cppu::UnoType<decltype(xListener)>::get(), xListener );
281
0
}
282
283
}
284
285
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */