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