Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/cppuhelper/source/component.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 <osl/diagnose.h>
21
#include <sal/log.hxx>
22
#include <cppuhelper/component.hxx>
23
#include <cppuhelper/exc_hlp.hxx>
24
#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
25
#include <com/sun/star/uno/RuntimeException.hpp>
26
27
using namespace osl;
28
using namespace com::sun::star;
29
using namespace com::sun::star::uno;
30
using namespace com::sun::star::lang;
31
32
namespace cppu
33
{
34
35
36
//  class OComponentHelper
37
38
39
OComponentHelper::OComponentHelper( Mutex & rMutex )
40
31.5k
    : m_rBHelper( rMutex )
41
31.5k
{
42
31.5k
}
43
OComponentHelper::~OComponentHelper()
44
31.5k
{
45
31.5k
}
46
47
Any OComponentHelper::queryInterface( Type const & rType )
48
170k
{
49
170k
    return OWeakAggObject::queryInterface( rType );
50
170k
}
51
Any OComponentHelper::queryAggregation( Type const & rType )
52
52.2k
{
53
52.2k
    if (rType == cppu::UnoType<lang::XComponent>::get())
54
0
    {
55
0
        void * p = static_cast< lang::XComponent * >( this );
56
0
        return Any( &p, rType );
57
0
    }
58
52.2k
    if (rType == cppu::UnoType<lang::XTypeProvider>::get())
59
0
    {
60
0
        void * p = static_cast< lang::XTypeProvider * >( this );
61
0
        return Any( &p, rType );
62
0
    }
63
52.2k
    return OWeakAggObject::queryAggregation( rType );
64
52.2k
}
65
void OComponentHelper::acquire() noexcept
66
370k
{
67
370k
    OWeakAggObject::acquire();
68
370k
}
69
70
void OComponentHelper::release() noexcept
71
370k
{
72
370k
    Reference<XInterface > x( xDelegator );
73
370k
    if (! x.is())
74
370k
    {
75
370k
        if (osl_atomic_decrement( &m_refCount ) == 0)
76
63.1k
        {
77
63.1k
            if (! m_rBHelper.bDisposed)
78
31.5k
            {
79
                // *before* again incrementing our ref count, ensure that our weak connection point
80
                // will not create references to us anymore (via XAdapter::queryAdapted)
81
31.5k
                disposeWeakConnectionPoint();
82
83
31.5k
                Reference<XInterface > xHoldAlive( *this );
84
                // First dispose
85
31.5k
                try
86
31.5k
                {
87
31.5k
                    dispose();
88
31.5k
                }
89
31.5k
                catch (css::uno::RuntimeException & exc)
90
31.5k
                {
91
                    // release should not throw exceptions
92
0
                    SAL_WARN( "cppuhelper", exc );
93
0
                }
94
95
                // only the alive ref holds the object
96
31.5k
                OSL_ASSERT( m_refCount == 1 );
97
                // destroy the object if xHoldAlive decrement the refcount to 0
98
31.5k
                return;
99
31.5k
            }
100
63.1k
        }
101
        // restore the reference count
102
339k
        osl_atomic_increment( &m_refCount );
103
339k
    }
104
339k
    OWeakAggObject::release();
105
339k
}
106
107
Sequence< Type > OComponentHelper::getTypes()
108
0
{
109
0
    static const Sequence s_aTypes {
110
0
        cppu::UnoType<lang::XComponent>::get(),
111
0
        cppu::UnoType<lang::XTypeProvider>::get(),
112
0
        cppu::UnoType<XAggregation>::get(),
113
0
        cppu::UnoType<XWeak>::get() };
114
115
0
    return s_aTypes;
116
0
}
117
118
// XComponent
119
void OComponentHelper::disposing()
120
0
{
121
0
}
122
123
// XComponent
124
void OComponentHelper::dispose()
125
31.5k
{
126
    // An frequently programming error is to release the last
127
    // reference to this object in the disposing message.
128
    // Make it robust, hold a self Reference.
129
31.5k
    Reference<XComponent > xSelf( this );
130
131
    // Guard dispose against multiple threading
132
    // Remark: It is an error to call dispose more than once
133
31.5k
    bool bDoDispose = false;
134
31.5k
    {
135
31.5k
        MutexGuard aGuard( m_rBHelper.rMutex );
136
31.5k
        if( !m_rBHelper.bDisposed && !m_rBHelper.bInDispose )
137
31.5k
        {
138
            // only one call go into this section
139
31.5k
            m_rBHelper.bInDispose = true;
140
31.5k
            bDoDispose = true;
141
31.5k
        }
142
31.5k
    }
143
144
    // Do not hold the mutex because we are broadcasting
145
31.5k
    if( bDoDispose )
146
31.5k
    {
147
        // Create an event with this as sender
148
31.5k
        try
149
31.5k
        {
150
31.5k
            try
151
31.5k
            {
152
31.5k
                EventObject aEvt;
153
31.5k
                aEvt.Source = Reference<XInterface >::query( static_cast<XComponent *>(this) );
154
                // inform all listeners to release this object
155
                // The listener container are automatically cleared
156
31.5k
                m_rBHelper.aLC.disposeAndClear( aEvt );
157
                // notify subclasses to do their dispose
158
31.5k
                disposing();
159
31.5k
            }
160
31.5k
            catch (...)
161
31.5k
            {
162
0
                MutexGuard aGuard( m_rBHelper.rMutex );
163
                // bDispose and bInDisposing must be set in this order:
164
0
                m_rBHelper.bDisposed = true;
165
0
                m_rBHelper.bInDispose = false;
166
0
                throw;
167
0
            }
168
31.5k
            MutexGuard aGuard( m_rBHelper.rMutex );
169
            // bDispose and bInDisposing must be set in this order:
170
31.5k
            m_rBHelper.bDisposed = true;
171
31.5k
            m_rBHelper.bInDispose = false;
172
31.5k
        }
173
31.5k
        catch (RuntimeException &)
174
31.5k
        {
175
0
            throw;
176
0
        }
177
31.5k
        catch (Exception & exc)
178
31.5k
        {
179
0
            css::uno::Any anyEx = cppu::getCaughtException();
180
0
            throw lang::WrappedTargetRuntimeException(
181
0
                "unexpected UNO exception caught: " + exc.Message,
182
0
                nullptr, anyEx );
183
0
        }
184
31.5k
    }
185
0
    else
186
0
    {
187
        // in a multithreaded environment, it can't be avoided
188
        // that dispose is called twice.
189
        // However this condition is traced, because it MAY indicate an error.
190
0
        SAL_WARN("cppuhelper",  "OComponentHelper::dispose() - dispose called twice" );
191
0
    }
192
31.5k
}
193
194
// XComponent
195
void OComponentHelper::addEventListener(
196
    const Reference<XEventListener > & rxListener )
197
0
{
198
0
    ClearableMutexGuard aGuard( m_rBHelper.rMutex );
199
0
    if (m_rBHelper.bDisposed || m_rBHelper.bInDispose)
200
0
    {
201
0
        aGuard.clear();
202
0
        Reference< XInterface > x( static_cast<XComponent *>(this), UNO_QUERY );
203
0
        rxListener->disposing( EventObject( x ) );
204
0
    }
205
0
    else
206
0
    {
207
0
        m_rBHelper.addListener( cppu::UnoType<decltype(rxListener)>::get(), rxListener );
208
0
    }
209
0
}
210
211
// XComponent
212
void OComponentHelper::removeEventListener(
213
    const Reference<XEventListener > & rxListener )
214
0
{
215
0
    m_rBHelper.removeListener( cppu::UnoType<decltype(rxListener)>::get(), rxListener );
216
0
}
217
218
}
219
220
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */