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 INCLUDED_CHART2_SOURCE_INC_LIFETIME_HXX
20 : #define INCLUDED_CHART2_SOURCE_INC_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() SAL_OVERRIDE;
110 : virtual void impl_apiCallCountReachedNull() SAL_OVERRIDE;
111 :
112 : void impl_setOwnership( sal_Bool bDeliverOwnership, sal_Bool bMyVeto );
113 : sal_Bool impl_shouldCloseAtNextChance();
114 : void impl_doClose();
115 :
116 0 : void impl_init()
117 : {
118 0 : m_bClosed = sal_False;
119 0 : m_bInTryClose = sal_False;
120 0 : m_bOwnership = sal_False;
121 0 : m_bOwnershipIsWellKnown = sal_False;
122 0 : m_aEndTryClosingCondition.set();
123 0 : }
124 : };
125 :
126 : /*
127 : Use this Guard in your apicalls to protect access on resources
128 : which will be released in dispose.
129 : It's guarantied, that the release of resources only starts if your
130 : guarded call has finished.
131 : ! It's only partly guaranteed that this resources will not change during the call.
132 : See the example for details.
133 :
134 : This class is to be used as described in the example.
135 :
136 : If this guard is used in all api calls of an XCloseable object
137 : it's guarantied, that the closeable will close itself after finishing the last call
138 : if it should do so.
139 :
140 : ::ApiCall
141 : {
142 : //hold no mutex!!!
143 : LifeTimeGuard aLifeTimeGuard(m_aLifeTimeManager);
144 :
145 : //mutex is acquired; call is not registered
146 :
147 : if(!aLifeTimeGuard.startApiCall())
148 : return ; //behave as passive as possible, if disposed or closed
149 :
150 : //mutex is acquired, call is registered
151 : {
152 : //you might access some private members here
153 : //but than you need to protect access to these members always like this
154 : //never call to the outside here
155 : }
156 :
157 : aLifeTimeGuard.clear(); //!!!
158 :
159 : //Mutex is released, the running call is still registered
160 : //this call will finish before the 'release-section' in dispose is allowed to start
161 :
162 : {
163 : //you might access some private members here guarded with your own mutex
164 : //but release your mutex at the end of this block
165 : }
166 :
167 : //you can call to the outside (without holding the mutex) without becoming disposed
168 :
169 : //End of method -> ~LifeTimeGuard
170 : //-> call is unregistered
171 : //-> this object might be disposed now
172 : }
173 :
174 : your XComponent::dispose method has to be implemented in the following way:
175 :
176 : ::dispose()
177 : {
178 : //hold no mutex!!!
179 : if( !m_aLifeTimeManager.dispose() )
180 : return;
181 :
182 : //--release all resources and references
183 :
184 : }
185 :
186 : */
187 :
188 : class OOO_DLLPUBLIC_CHARTTOOLS LifeTimeGuard
189 : {
190 :
191 : public:
192 0 : LifeTimeGuard( LifeTimeManager& rManager )
193 : : m_guard( rManager.m_aAccessMutex )
194 : , m_rManager(rManager)
195 : , m_bCallRegistered(sal_False)
196 0 : , m_bLongLastingCallRegistered(sal_False)
197 : {
198 :
199 0 : }
200 : sal_Bool startApiCall(sal_Bool bLongLastingCall=sal_False);
201 : ~LifeTimeGuard();
202 0 : void clear() { m_guard.clear(); }
203 :
204 : private:
205 : osl::ClearableMutexGuard m_guard;
206 : LifeTimeManager& m_rManager;
207 : sal_Bool m_bCallRegistered;
208 : sal_Bool m_bLongLastingCallRegistered;
209 :
210 : private:
211 : // these make no sense
212 : LifeTimeGuard( ::osl::Mutex& rMutex );
213 : LifeTimeGuard( const LifeTimeGuard& );
214 : LifeTimeGuard& operator= ( const LifeTimeGuard& );
215 : };
216 :
217 : template<class T>
218 : class NegativeGuard
219 : {
220 : protected:
221 : T * m_pT;
222 : public:
223 :
224 : NegativeGuard(T * pT) : m_pT(pT)
225 : {
226 : m_pT->release();
227 : }
228 :
229 0 : NegativeGuard(T & t) : m_pT(&t)
230 : {
231 0 : m_pT->release();
232 0 : }
233 :
234 0 : ~NegativeGuard()
235 : {
236 0 : m_pT->acquire();
237 0 : }
238 : };
239 :
240 : }//end namespace apphelper
241 : #endif
242 :
243 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|