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