Branch data Line data Source code
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 : : #ifndef _LIFETIME_HXX
20 : : #define _LIFETIME_HXX
21 : :
22 : : #include <osl/mutex.hxx>
23 : : #include <osl/conditn.hxx>
24 : : #include <com/sun/star/uno/Exception.hpp>
25 : : #include <cppuhelper/interfacecontainer.hxx>
26 : : #include <com/sun/star/util/XCloseListener.hpp>
27 : : #include <com/sun/star/util/XCloseable.hpp>
28 : : #include <com/sun/star/lang/XComponent.hpp>
29 : : #include <cppuhelper/weakref.hxx>
30 : : #include "charttoolsdllapi.hxx"
31 : :
32 : : namespace apphelper
33 : : {
34 : :
35 : : class LifeTimeGuard;
36 : : class LifeTimeManager
37 : : {
38 : : friend class LifeTimeGuard;
39 : : protected:
40 : : mutable ::osl::Mutex m_aAccessMutex;
41 : : public:
42 : : OOO_DLLPUBLIC_CHARTTOOLS LifeTimeManager( ::com::sun::star::lang::XComponent* pComponent, sal_Bool bLongLastingCallsCancelable = sal_False );
43 : : OOO_DLLPUBLIC_CHARTTOOLS virtual ~LifeTimeManager();
44 : :
45 : : OOO_DLLPUBLIC_CHARTTOOLS bool impl_isDisposed( bool bAssert=true );
46 : : OOO_DLLPUBLIC_CHARTTOOLS sal_Bool dispose() throw(::com::sun::star::uno::RuntimeException);
47 : :
48 : : public:
49 : : ::cppu::OMultiTypeInterfaceContainerHelper m_aListenerContainer;
50 : :
51 : : protected:
52 : : virtual sal_Bool impl_canStartApiCall();
53 : 0 : virtual void impl_apiCallCountReachedNull(){}
54 : :
55 : : void impl_registerApiCall(sal_Bool bLongLastingCall);
56 : : void impl_unregisterApiCall(sal_Bool bLongLastingCall);
57 : :
58 : : void impl_init();
59 : :
60 : : protected:
61 : : ::com::sun::star::lang::XComponent* m_pComponent;
62 : :
63 : : ::osl::Condition m_aNoAccessCountCondition;
64 : : sal_Int32 volatile m_nAccessCount;
65 : :
66 : : sal_Bool volatile m_bDisposed;
67 : : sal_Bool volatile m_bInDispose;
68 : :
69 : : sal_Bool m_bLongLastingCallsCancelable;
70 : : ::osl::Condition m_aNoLongLastingCallCountCondition;
71 : : sal_Int32 volatile m_nLongLastingCallCount;
72 : : };
73 : :
74 : : class CloseableLifeTimeManager : public LifeTimeManager
75 : : {
76 : : protected:
77 : : ::com::sun::star::util::XCloseable* m_pCloseable;
78 : :
79 : : ::osl::Condition m_aEndTryClosingCondition;
80 : : sal_Bool volatile m_bClosed;
81 : : sal_Bool volatile m_bInTryClose;
82 : : //the ownership between model and controller is not clear at first
83 : : //each controller might consider him as owner of the model first
84 : : //at start the model is not considered as owner of itself
85 : : sal_Bool volatile m_bOwnership;
86 : : //with a XCloseable::close call and during XCloseListener::queryClosing
87 : : //the ownership can be regulated more explicit,
88 : : //if so the ownership is considered to be well known
89 : : sal_Bool volatile m_bOwnershipIsWellKnown;
90 : :
91 : : public:
92 : : OOO_DLLPUBLIC_CHARTTOOLS CloseableLifeTimeManager( ::com::sun::star::util::XCloseable* pCloseable
93 : : , ::com::sun::star::lang::XComponent* pComponent
94 : : , sal_Bool bLongLastingCallsCancelable = sal_False );
95 : : OOO_DLLPUBLIC_CHARTTOOLS virtual ~CloseableLifeTimeManager();
96 : :
97 : : OOO_DLLPUBLIC_CHARTTOOLS bool impl_isDisposedOrClosed( bool bAssert=true );
98 : : OOO_DLLPUBLIC_CHARTTOOLS sal_Bool g_close_startTryClose(sal_Bool bDeliverOwnership)
99 : : throw ( ::com::sun::star::uno::Exception );
100 : : OOO_DLLPUBLIC_CHARTTOOLS sal_Bool g_close_isNeedToCancelLongLastingCalls( sal_Bool bDeliverOwnership, ::com::sun::star::util::CloseVetoException& ex )
101 : : throw ( ::com::sun::star::util::CloseVetoException );
102 : : OOO_DLLPUBLIC_CHARTTOOLS void g_close_endTryClose(sal_Bool bDeliverOwnership, sal_Bool bMyVeto );
103 : : OOO_DLLPUBLIC_CHARTTOOLS void g_close_endTryClose_doClose();
104 : : OOO_DLLPUBLIC_CHARTTOOLS sal_Bool g_addCloseListener( const ::com::sun::star::uno::Reference<
105 : : ::com::sun::star::util::XCloseListener > & xListener )
106 : : throw(::com::sun::star::uno::RuntimeException);
107 : :
108 : : protected:
109 : : virtual sal_Bool impl_canStartApiCall();
110 : : virtual void impl_apiCallCountReachedNull();
111 : :
112 : : void impl_setOwnership( sal_Bool bDeliverOwnership, sal_Bool bMyVeto );
113 : : sal_Bool impl_shouldCloseAtNextChance();
114 : : void impl_doClose();
115 : :
116 : 56 : void impl_init()
117 : : {
118 : 56 : m_bClosed = sal_False;
119 : 56 : m_bInTryClose = sal_False;
120 : 56 : m_bOwnership = sal_False;
121 : 56 : m_bOwnershipIsWellKnown = sal_False;
122 : 56 : m_aEndTryClosingCondition.set();
123 : 56 : }
124 : : };
125 : :
126 : : //-----------------------------------------------------------------
127 : : /*
128 : : Use this Guard in your apicalls to protect access on resources
129 : : which will be released in dispose.
130 : : It's guarantied, that the release of resources only starts if your
131 : : guarded call has finished.
132 : : ! It's only partly guaranteed that this resources will not change during the call.
133 : : See the example for details.
134 : :
135 : : This class is to be used as described in the example.
136 : :
137 : : If this guard is used in all api calls of an XCloseable object
138 : : it's guarantied, that the closeable will close itself after finishing the last call
139 : : if it should do so.
140 : :
141 : : ::ApiCall
142 : : {
143 : : //hold no mutex!!!
144 : : LifeTimeGuard aLifeTimeGuard(m_aLifeTimeManager);
145 : :
146 : : //mutex is acquired; call is not registered
147 : :
148 : : if(!aLifeTimeGuard.startApiCall())
149 : : return ; //behave as passive as possible, if disposed or closed
150 : :
151 : : //mutex is acquired, call is registered
152 : : {
153 : : //you might access some private members here
154 : : //but than you need to protect access to these members always like this
155 : : //never call to the outside here
156 : : }
157 : :
158 : : aLifeTimeGuard.clear(); //!!!
159 : :
160 : : //Mutex is released, the running call is still registered
161 : : //this call will finish before the 'release-section' in dispose is allowed to start
162 : :
163 : : {
164 : : //you might access some private members here guarded with your own mutex
165 : : //but release your mutex at the end of this block
166 : : }
167 : :
168 : : //you can call to the outside (without holding the mutex) without becoming disposed
169 : :
170 : : //End of method -> ~LifeTimeGuard
171 : : //-> call is unregistered
172 : : //-> this object might be disposed now
173 : : }
174 : :
175 : : your XComponent::dispose method has to be implemented in the following way:
176 : :
177 : : ::dispose()
178 : : {
179 : : //hold no mutex!!!
180 : : if( !m_aLifeTimeManager.dispose() )
181 : : return;
182 : :
183 : : //--release all resources and references
184 : : //...
185 : : }
186 : :
187 : : */
188 : : //-----------------------------------------------------------------
189 : :
190 : : class OOO_DLLPUBLIC_CHARTTOOLS LifeTimeGuard
191 : : {
192 : :
193 : : public:
194 : 6055 : LifeTimeGuard( LifeTimeManager& rManager )
195 : : : m_guard( rManager.m_aAccessMutex )
196 : : , m_rManager(rManager)
197 : : , m_bCallRegistered(sal_False)
198 : 6055 : , m_bLongLastingCallRegistered(sal_False)
199 : : {
200 : :
201 : 6055 : }
202 : : sal_Bool startApiCall(sal_Bool bLongLastingCall=sal_False);
203 : : ~LifeTimeGuard();
204 : 1897 : void clear() { m_guard.clear(); }
205 : :
206 : : private:
207 : : osl::ClearableMutexGuard m_guard;
208 : : LifeTimeManager& m_rManager;
209 : : sal_Bool m_bCallRegistered;
210 : : sal_Bool m_bLongLastingCallRegistered;
211 : :
212 : : private:
213 : : // these make no sense
214 : : LifeTimeGuard( ::osl::Mutex& rMutex );
215 : : LifeTimeGuard( const LifeTimeGuard& );
216 : : LifeTimeGuard& operator= ( const LifeTimeGuard& );
217 : : };
218 : :
219 : :
220 : : template<class T>
221 : : class NegativeGuard
222 : : {
223 : : protected:
224 : : T * m_pT;
225 : : public:
226 : :
227 : : NegativeGuard(T * pT) : m_pT(pT)
228 : : {
229 : : m_pT->release();
230 : : }
231 : :
232 : 54 : NegativeGuard(T & t) : m_pT(&t)
233 : : {
234 : 54 : m_pT->release();
235 : 54 : }
236 : :
237 : 54 : ~NegativeGuard()
238 : : {
239 : 54 : m_pT->acquire();
240 : 54 : }
241 : : };
242 : :
243 : : }//end namespace apphelper
244 : : #endif
245 : :
246 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|