xref: /aoo42x/main/cppuhelper/source/weak.cxx (revision 9d7e27ac)
1*9d7e27acSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*9d7e27acSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*9d7e27acSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*9d7e27acSAndrew Rist  * distributed with this work for additional information
6*9d7e27acSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*9d7e27acSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*9d7e27acSAndrew Rist  * "License"); you may not use this file except in compliance
9*9d7e27acSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*9d7e27acSAndrew Rist  *
11*9d7e27acSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*9d7e27acSAndrew Rist  *
13*9d7e27acSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*9d7e27acSAndrew Rist  * software distributed under the License is distributed on an
15*9d7e27acSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9d7e27acSAndrew Rist  * KIND, either express or implied.  See the License for the
17*9d7e27acSAndrew Rist  * specific language governing permissions and limitations
18*9d7e27acSAndrew Rist  * under the License.
19*9d7e27acSAndrew Rist  *
20*9d7e27acSAndrew Rist  *************************************************************/
21*9d7e27acSAndrew Rist 
22*9d7e27acSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_cppuhelper.hxx"
26cdf0e10cSrcweir #include <osl/mutex.hxx>
27cdf0e10cSrcweir #ifndef _CPPU_WEAKAGG_HXX_
28cdf0e10cSrcweir #include <cppuhelper/weakagg.hxx>
29cdf0e10cSrcweir #endif
30cdf0e10cSrcweir #ifndef _CPPU_HELPER_INTERFACECONTAINER_HXX_
31cdf0e10cSrcweir #include <cppuhelper/interfacecontainer.hxx>
32cdf0e10cSrcweir #endif
33cdf0e10cSrcweir #include "cppuhelper/exc_hlp.hxx"
34cdf0e10cSrcweir 
35cdf0e10cSrcweir using namespace osl;
36cdf0e10cSrcweir using namespace com::sun::star::uno;
37cdf0e10cSrcweir 
38cdf0e10cSrcweir /** */ //for docpp
39cdf0e10cSrcweir namespace cppu
40cdf0e10cSrcweir {
41cdf0e10cSrcweir 
42cdf0e10cSrcweir // due to static Reflection destruction from usr, ther must be a mutex leak (#73272#)
43cdf0e10cSrcweir inline static Mutex & getWeakMutex() SAL_THROW( () )
44cdf0e10cSrcweir {
45cdf0e10cSrcweir 	static Mutex * s_pMutex = 0;
46cdf0e10cSrcweir 	if (! s_pMutex)
47cdf0e10cSrcweir 		s_pMutex = new Mutex();
48cdf0e10cSrcweir 	return *s_pMutex;
49cdf0e10cSrcweir }
50cdf0e10cSrcweir 
51cdf0e10cSrcweir //------------------------------------------------------------------------
52cdf0e10cSrcweir //-- OWeakConnectionPoint ----------------------------------------------------
53cdf0e10cSrcweir //------------------------------------------------------------------------
54cdf0e10cSrcweir class OWeakConnectionPoint : public XAdapter
55cdf0e10cSrcweir {
56cdf0e10cSrcweir public:
57cdf0e10cSrcweir 	/**
58cdf0e10cSrcweir 		Hold the weak object without an acquire (only the pointer).
59cdf0e10cSrcweir 	 */
60cdf0e10cSrcweir 	OWeakConnectionPoint( OWeakObject* pObj ) SAL_THROW( () )
61cdf0e10cSrcweir 		: m_aRefCount( 0 )
62cdf0e10cSrcweir 		, m_pObject(pObj)
63cdf0e10cSrcweir 		, m_aReferences( getWeakMutex() )
64cdf0e10cSrcweir 		{}
65cdf0e10cSrcweir 
66cdf0e10cSrcweir 	// XInterface
67cdf0e10cSrcweir 	Any SAL_CALL		queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException);
68cdf0e10cSrcweir 	void SAL_CALL		acquire() throw();
69cdf0e10cSrcweir 	void SAL_CALL		release() throw();
70cdf0e10cSrcweir 
71cdf0e10cSrcweir 	// XAdapter
72cdf0e10cSrcweir     ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL queryAdapted() throw(::com::sun::star::uno::RuntimeException);
73cdf0e10cSrcweir     void SAL_CALL addReference( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XReference >& xRef ) throw(::com::sun::star::uno::RuntimeException);
74cdf0e10cSrcweir     void SAL_CALL removeReference( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XReference >& xRef ) throw(::com::sun::star::uno::RuntimeException);
75cdf0e10cSrcweir 
76cdf0e10cSrcweir 	/// Called from the weak object if the reference count goes to zero.
77cdf0e10cSrcweir 	void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
78cdf0e10cSrcweir 
79cdf0e10cSrcweir private:
80cdf0e10cSrcweir     OWeakConnectionPoint(OWeakConnectionPoint &); // not defined
81cdf0e10cSrcweir     void operator =(OWeakConnectionPoint &); // not defined
82cdf0e10cSrcweir 
83cdf0e10cSrcweir     virtual ~OWeakConnectionPoint() {}
84cdf0e10cSrcweir 
85cdf0e10cSrcweir 	/// The reference counter.
86cdf0e10cSrcweir     oslInterlockedCount			m_aRefCount;
87cdf0e10cSrcweir 	/// The weak object
88cdf0e10cSrcweir 	OWeakObject* 				m_pObject;
89cdf0e10cSrcweir 	/// The container to hold the weak references
90cdf0e10cSrcweir 	OInterfaceContainerHelper	m_aReferences;
91cdf0e10cSrcweir };
92cdf0e10cSrcweir 
93cdf0e10cSrcweir // XInterface
94cdf0e10cSrcweir Any SAL_CALL OWeakConnectionPoint::queryInterface( const Type & rType )
95cdf0e10cSrcweir 	throw(com::sun::star::uno::RuntimeException)
96cdf0e10cSrcweir {
97cdf0e10cSrcweir 	return ::cppu::queryInterface(
98cdf0e10cSrcweir 		rType, static_cast< XAdapter * >( this ), static_cast< XInterface * >( this ) );
99cdf0e10cSrcweir }
100cdf0e10cSrcweir 
101cdf0e10cSrcweir // XInterface
102cdf0e10cSrcweir void SAL_CALL OWeakConnectionPoint::acquire() throw()
103cdf0e10cSrcweir {
104cdf0e10cSrcweir 	osl_incrementInterlockedCount( &m_aRefCount );
105cdf0e10cSrcweir }
106cdf0e10cSrcweir 
107cdf0e10cSrcweir // XInterface
108cdf0e10cSrcweir void SAL_CALL OWeakConnectionPoint::release() throw()
109cdf0e10cSrcweir {
110cdf0e10cSrcweir 	if (! osl_decrementInterlockedCount( &m_aRefCount ))
111cdf0e10cSrcweir 		delete this;
112cdf0e10cSrcweir }
113cdf0e10cSrcweir 
114cdf0e10cSrcweir void SAL_CALL OWeakConnectionPoint::dispose() throw(::com::sun::star::uno::RuntimeException)
115cdf0e10cSrcweir {
116cdf0e10cSrcweir     Any ex;
117cdf0e10cSrcweir 	OInterfaceIteratorHelper aIt( m_aReferences );
118cdf0e10cSrcweir 	while( aIt.hasMoreElements() )
119cdf0e10cSrcweir     {
120cdf0e10cSrcweir         try
121cdf0e10cSrcweir         {
122cdf0e10cSrcweir             ((XReference *)aIt.next())->dispose();
123cdf0e10cSrcweir         }
124cdf0e10cSrcweir         catch (com::sun::star::lang::DisposedException &) {}
125cdf0e10cSrcweir         catch (RuntimeException &)
126cdf0e10cSrcweir         {
127cdf0e10cSrcweir             ex = cppu::getCaughtException();
128cdf0e10cSrcweir         }
129cdf0e10cSrcweir     }
130cdf0e10cSrcweir     if (ex.hasValue())
131cdf0e10cSrcweir     {
132cdf0e10cSrcweir         cppu::throwException(ex);
133cdf0e10cSrcweir     }
134cdf0e10cSrcweir }
135cdf0e10cSrcweir 
136cdf0e10cSrcweir // XInterface
137cdf0e10cSrcweir Reference< XInterface > SAL_CALL OWeakConnectionPoint::queryAdapted() throw(::com::sun::star::uno::RuntimeException)
138cdf0e10cSrcweir {
139cdf0e10cSrcweir 	Reference< XInterface > ret;
140cdf0e10cSrcweir 
141cdf0e10cSrcweir 	ClearableMutexGuard guard(getWeakMutex());
142cdf0e10cSrcweir 
143cdf0e10cSrcweir 	if (m_pObject)
144cdf0e10cSrcweir 	{
145cdf0e10cSrcweir 		oslInterlockedCount n = osl_incrementInterlockedCount( &m_pObject->m_refCount );
146cdf0e10cSrcweir 
147cdf0e10cSrcweir 		if (n > 1)
148cdf0e10cSrcweir 		{
149cdf0e10cSrcweir 			// The refence is incremented. The object cannot be destroyed.
150cdf0e10cSrcweir 			// Release the guard at the earliest point.
151cdf0e10cSrcweir 			guard.clear();
152cdf0e10cSrcweir 			// WeakObject has a (XInterface *) cast operator
153cdf0e10cSrcweir 			ret = *m_pObject;
154cdf0e10cSrcweir 			n = osl_decrementInterlockedCount( &m_pObject->m_refCount );
155cdf0e10cSrcweir 		}
156cdf0e10cSrcweir 		else
157cdf0e10cSrcweir 			// Another thread wait in the dispose method at the guard
158cdf0e10cSrcweir 			n = osl_decrementInterlockedCount( &m_pObject->m_refCount );
159cdf0e10cSrcweir 	}
160cdf0e10cSrcweir 
161cdf0e10cSrcweir 	return ret;
162cdf0e10cSrcweir }
163cdf0e10cSrcweir 
164cdf0e10cSrcweir // XInterface
165cdf0e10cSrcweir void SAL_CALL OWeakConnectionPoint::addReference(const Reference< XReference >& rRef)
166cdf0e10cSrcweir 	throw(::com::sun::star::uno::RuntimeException)
167cdf0e10cSrcweir {
168cdf0e10cSrcweir 	m_aReferences.addInterface( (const Reference< XInterface > &)rRef );
169cdf0e10cSrcweir }
170cdf0e10cSrcweir 
171cdf0e10cSrcweir // XInterface
172cdf0e10cSrcweir void SAL_CALL OWeakConnectionPoint::removeReference(const Reference< XReference >& rRef)
173cdf0e10cSrcweir 	throw(::com::sun::star::uno::RuntimeException)
174cdf0e10cSrcweir {
175cdf0e10cSrcweir 	m_aReferences.removeInterface( (const Reference< XInterface > &)rRef );
176cdf0e10cSrcweir }
177cdf0e10cSrcweir 
178cdf0e10cSrcweir 
179cdf0e10cSrcweir //------------------------------------------------------------------------
180cdf0e10cSrcweir //-- OWeakObject -------------------------------------------------------
181cdf0e10cSrcweir //------------------------------------------------------------------------
182cdf0e10cSrcweir 
183cdf0e10cSrcweir #ifdef _MSC_VER
184cdf0e10cSrcweir // Accidentally occurs in msvc mapfile = > had to be outlined.
185cdf0e10cSrcweir OWeakObject::OWeakObject() SAL_THROW( () )
186cdf0e10cSrcweir     : m_refCount( 0 ),
187cdf0e10cSrcweir       m_pWeakConnectionPoint( 0 )
188cdf0e10cSrcweir {
189cdf0e10cSrcweir }
190cdf0e10cSrcweir #endif
191cdf0e10cSrcweir 
192cdf0e10cSrcweir // XInterface
193cdf0e10cSrcweir Any SAL_CALL OWeakObject::queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException)
194cdf0e10cSrcweir {
195cdf0e10cSrcweir 	return ::cppu::queryInterface(
196cdf0e10cSrcweir 		rType,
197cdf0e10cSrcweir 		static_cast< XWeak * >( this ), static_cast< XInterface * >( this ) );
198cdf0e10cSrcweir }
199cdf0e10cSrcweir 
200cdf0e10cSrcweir // XInterface
201cdf0e10cSrcweir void SAL_CALL OWeakObject::acquire() throw()
202cdf0e10cSrcweir {
203cdf0e10cSrcweir 	osl_incrementInterlockedCount( &m_refCount );
204cdf0e10cSrcweir }
205cdf0e10cSrcweir 
206cdf0e10cSrcweir // XInterface
207cdf0e10cSrcweir void SAL_CALL OWeakObject::release() throw()
208cdf0e10cSrcweir {
209cdf0e10cSrcweir     if (osl_decrementInterlockedCount( &m_refCount ) == 0) {
210cdf0e10cSrcweir         // notify/clear all weak-refs before object's dtor is executed
211cdf0e10cSrcweir         // (which may check weak-refs to this object):
212cdf0e10cSrcweir         disposeWeakConnectionPoint();
213cdf0e10cSrcweir         // destroy object:
214cdf0e10cSrcweir         delete this;
215cdf0e10cSrcweir     }
216cdf0e10cSrcweir }
217cdf0e10cSrcweir 
218cdf0e10cSrcweir void OWeakObject::disposeWeakConnectionPoint()
219cdf0e10cSrcweir {
220cdf0e10cSrcweir     OSL_PRECOND( m_refCount == 0, "OWeakObject::disposeWeakConnectionPoint: only to be called with a ref count of 0!" );
221cdf0e10cSrcweir     if (m_pWeakConnectionPoint != 0) {
222cdf0e10cSrcweir         OWeakConnectionPoint * const p = m_pWeakConnectionPoint;
223cdf0e10cSrcweir         m_pWeakConnectionPoint = 0;
224cdf0e10cSrcweir         try {
225cdf0e10cSrcweir             p->dispose();
226cdf0e10cSrcweir         }
227cdf0e10cSrcweir         catch (RuntimeException const& exc) {
228cdf0e10cSrcweir             OSL_ENSURE(
229cdf0e10cSrcweir                 false, OUStringToOString(
230cdf0e10cSrcweir                     exc.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
231cdf0e10cSrcweir             static_cast<void>(exc);
232cdf0e10cSrcweir         }
233cdf0e10cSrcweir         p->release();
234cdf0e10cSrcweir     }
235cdf0e10cSrcweir }
236cdf0e10cSrcweir 
237cdf0e10cSrcweir OWeakObject::~OWeakObject() SAL_THROW( (RuntimeException) )
238cdf0e10cSrcweir {
239cdf0e10cSrcweir }
240cdf0e10cSrcweir 
241cdf0e10cSrcweir // XWeak
242cdf0e10cSrcweir Reference< XAdapter > SAL_CALL OWeakObject::queryAdapter()
243cdf0e10cSrcweir 	throw (::com::sun::star::uno::RuntimeException)
244cdf0e10cSrcweir {
245cdf0e10cSrcweir 	if (!m_pWeakConnectionPoint)
246cdf0e10cSrcweir 	{
247cdf0e10cSrcweir 		// only acquire mutex if member is not created
248cdf0e10cSrcweir 		MutexGuard aGuard( getWeakMutex() );
249cdf0e10cSrcweir 		if( !m_pWeakConnectionPoint )
250cdf0e10cSrcweir 		{
251cdf0e10cSrcweir 			OWeakConnectionPoint * p = new OWeakConnectionPoint(this);
252cdf0e10cSrcweir 			p->acquire();
253cdf0e10cSrcweir 			m_pWeakConnectionPoint = p;
254cdf0e10cSrcweir 		}
255cdf0e10cSrcweir 	}
256cdf0e10cSrcweir 
257cdf0e10cSrcweir 	return m_pWeakConnectionPoint;
258cdf0e10cSrcweir }
259cdf0e10cSrcweir 
260cdf0e10cSrcweir //------------------------------------------------------------------------
261cdf0e10cSrcweir //-- OWeakAggObject ----------------------------------------------------
262cdf0e10cSrcweir //------------------------------------------------------------------------
263cdf0e10cSrcweir OWeakAggObject::~OWeakAggObject() SAL_THROW( (RuntimeException) )
264cdf0e10cSrcweir {
265cdf0e10cSrcweir }
266cdf0e10cSrcweir 
267cdf0e10cSrcweir // XInterface
268cdf0e10cSrcweir void OWeakAggObject::acquire() throw()
269cdf0e10cSrcweir {
270cdf0e10cSrcweir 	Reference<XInterface > x( xDelegator );
271cdf0e10cSrcweir 	if (x.is())
272cdf0e10cSrcweir 		x->acquire();
273cdf0e10cSrcweir 	else
274cdf0e10cSrcweir 		OWeakObject::acquire();
275cdf0e10cSrcweir }
276cdf0e10cSrcweir 
277cdf0e10cSrcweir // XInterface
278cdf0e10cSrcweir void OWeakAggObject::release() throw()
279cdf0e10cSrcweir {
280cdf0e10cSrcweir 	Reference<XInterface > x( xDelegator );
281cdf0e10cSrcweir 	if (x.is())
282cdf0e10cSrcweir 		x->release();
283cdf0e10cSrcweir 	else
284cdf0e10cSrcweir 		OWeakObject::release();
285cdf0e10cSrcweir }
286cdf0e10cSrcweir 
287cdf0e10cSrcweir // XInterface
288cdf0e10cSrcweir Any OWeakAggObject::queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException)
289cdf0e10cSrcweir {
290cdf0e10cSrcweir 	Reference< XInterface > x( xDelegator ); // harden ref
291cdf0e10cSrcweir 	return (x.is() ? x->queryInterface( rType ) : queryAggregation( rType ));
292cdf0e10cSrcweir 
293cdf0e10cSrcweir //  	// set rOut to zero, if failed
294cdf0e10cSrcweir //  	if( !xDelegator.queryHardRef( aUik, rOut ) )
295cdf0e10cSrcweir //  	{
296cdf0e10cSrcweir //  		XInterfaceRef x;
297cdf0e10cSrcweir //  		if( !xDelegator.queryHardRef( ((XInterface*)0)->getSmartUik(), x ) )
298cdf0e10cSrcweir //  			// reference is not valid
299cdf0e10cSrcweir //  			queryAggregation( aUik, rOut );
300cdf0e10cSrcweir //  	}
301cdf0e10cSrcweir //  	return rOut.is();
302cdf0e10cSrcweir }
303cdf0e10cSrcweir 
304cdf0e10cSrcweir // XAggregation
305cdf0e10cSrcweir Any OWeakAggObject::queryAggregation( const Type & rType ) throw(::com::sun::star::uno::RuntimeException)
306cdf0e10cSrcweir {
307cdf0e10cSrcweir 	return ::cppu::queryInterface(
308cdf0e10cSrcweir 		rType,
309cdf0e10cSrcweir 		static_cast< XInterface * >( static_cast< OWeakObject * >( this ) ),
310cdf0e10cSrcweir 		static_cast< XAggregation * >( this ),
311cdf0e10cSrcweir 		static_cast< XWeak * >( this ) );
312cdf0e10cSrcweir }
313cdf0e10cSrcweir 
314cdf0e10cSrcweir // XAggregation
315cdf0e10cSrcweir void OWeakAggObject::setDelegator( const Reference<XInterface > & rDelegator ) throw(::com::sun::star::uno::RuntimeException)
316cdf0e10cSrcweir {
317cdf0e10cSrcweir 	xDelegator = rDelegator;
318cdf0e10cSrcweir }
319cdf0e10cSrcweir 
320cdf0e10cSrcweir }
321cdf0e10cSrcweir 
322cdf0e10cSrcweir /** */ //for docpp
323cdf0e10cSrcweir namespace com
324cdf0e10cSrcweir {
325cdf0e10cSrcweir /** */ //for docpp
326cdf0e10cSrcweir namespace sun
327cdf0e10cSrcweir {
328cdf0e10cSrcweir /** */ //for docpp
329cdf0e10cSrcweir namespace star
330cdf0e10cSrcweir {
331cdf0e10cSrcweir /** */ //for docpp
332cdf0e10cSrcweir namespace uno
333cdf0e10cSrcweir {
334cdf0e10cSrcweir 
335cdf0e10cSrcweir 
336cdf0e10cSrcweir //------------------------------------------------------------------------
337cdf0e10cSrcweir //-- OWeakRefListener -----------------------------------------------------
338cdf0e10cSrcweir //------------------------------------------------------------------------
339cdf0e10cSrcweir class OWeakRefListener : public XReference
340cdf0e10cSrcweir {
341cdf0e10cSrcweir public:
342cdf0e10cSrcweir 	OWeakRefListener(const OWeakRefListener& rRef) SAL_THROW( () );
343cdf0e10cSrcweir 	OWeakRefListener(const Reference< XInterface >& xInt) SAL_THROW( () );
344cdf0e10cSrcweir 	virtual ~OWeakRefListener() SAL_THROW( () );
345cdf0e10cSrcweir 
346cdf0e10cSrcweir 	// XInterface
347cdf0e10cSrcweir     Any SAL_CALL queryInterface( const Type & rType ) throw(RuntimeException);
348cdf0e10cSrcweir     void SAL_CALL acquire() throw();
349cdf0e10cSrcweir     void SAL_CALL release() throw();
350cdf0e10cSrcweir 
351cdf0e10cSrcweir 	// XReference
352cdf0e10cSrcweir 	void SAL_CALL 	dispose() throw(::com::sun::star::uno::RuntimeException);
353cdf0e10cSrcweir 
354cdf0e10cSrcweir 	/// The reference counter.
355cdf0e10cSrcweir     oslInterlockedCount			m_aRefCount;
356cdf0e10cSrcweir 	/// The connection point of the weak object
357cdf0e10cSrcweir 	Reference< XAdapter >		m_XWeakConnectionPoint;
358cdf0e10cSrcweir 
359cdf0e10cSrcweir private:
360cdf0e10cSrcweir 	OWeakRefListener& SAL_CALL operator=(const OWeakRefListener& rRef) SAL_THROW( () );
361cdf0e10cSrcweir };
362cdf0e10cSrcweir 
363cdf0e10cSrcweir OWeakRefListener::OWeakRefListener(const OWeakRefListener& rRef) SAL_THROW( () )
364cdf0e10cSrcweir 	: com::sun::star::uno::XReference()
365cdf0e10cSrcweir     , m_aRefCount( 1 )
366cdf0e10cSrcweir {
367cdf0e10cSrcweir     try
368cdf0e10cSrcweir     {
369cdf0e10cSrcweir 	m_XWeakConnectionPoint = rRef.m_XWeakConnectionPoint;
370cdf0e10cSrcweir 
371cdf0e10cSrcweir 	if (m_XWeakConnectionPoint.is())
372cdf0e10cSrcweir     {
373cdf0e10cSrcweir         m_XWeakConnectionPoint->addReference((XReference*)this);
374cdf0e10cSrcweir     }
375cdf0e10cSrcweir     }
376cdf0e10cSrcweir     catch (RuntimeException &) { OSL_ASSERT( 0 ); } // assert here, but no unexpected()
377cdf0e10cSrcweir     osl_decrementInterlockedCount( &m_aRefCount );
378cdf0e10cSrcweir }
379cdf0e10cSrcweir 
380cdf0e10cSrcweir OWeakRefListener::OWeakRefListener(const Reference< XInterface >& xInt) SAL_THROW( () )
381cdf0e10cSrcweir 	: m_aRefCount( 1 )
382cdf0e10cSrcweir {
383cdf0e10cSrcweir     try
384cdf0e10cSrcweir     {
385cdf0e10cSrcweir 	Reference< XWeak > xWeak( Reference< XWeak >::query( xInt ) );
386cdf0e10cSrcweir 
387cdf0e10cSrcweir 	if (xWeak.is())
388cdf0e10cSrcweir 	{
389cdf0e10cSrcweir 		m_XWeakConnectionPoint = xWeak->queryAdapter();
390cdf0e10cSrcweir 
391cdf0e10cSrcweir 		if (m_XWeakConnectionPoint.is())
392cdf0e10cSrcweir 		{
393cdf0e10cSrcweir             m_XWeakConnectionPoint->addReference((XReference*)this);
394cdf0e10cSrcweir 		}
395cdf0e10cSrcweir 	}
396cdf0e10cSrcweir     }
397cdf0e10cSrcweir     catch (RuntimeException &) { OSL_ASSERT( 0 ); } // assert here, but no unexpected()
398cdf0e10cSrcweir     osl_decrementInterlockedCount( &m_aRefCount );
399cdf0e10cSrcweir }
400cdf0e10cSrcweir 
401cdf0e10cSrcweir OWeakRefListener::~OWeakRefListener() SAL_THROW( () )
402cdf0e10cSrcweir {
403cdf0e10cSrcweir     try
404cdf0e10cSrcweir     {
405cdf0e10cSrcweir 	if (m_XWeakConnectionPoint.is())
406cdf0e10cSrcweir     {
407cdf0e10cSrcweir         acquire(); // dont die again
408cdf0e10cSrcweir 		m_XWeakConnectionPoint->removeReference((XReference*)this);
409cdf0e10cSrcweir     }
410cdf0e10cSrcweir     }
411cdf0e10cSrcweir     catch (RuntimeException &) { OSL_ASSERT( 0 ); } // assert here, but no unexpected()
412cdf0e10cSrcweir }
413cdf0e10cSrcweir 
414cdf0e10cSrcweir // XInterface
415cdf0e10cSrcweir Any SAL_CALL OWeakRefListener::queryInterface( const Type & rType ) throw(RuntimeException)
416cdf0e10cSrcweir {
417cdf0e10cSrcweir 	return ::cppu::queryInterface(
418cdf0e10cSrcweir 		rType, static_cast< XReference * >( this ), static_cast< XInterface * >( this ) );
419cdf0e10cSrcweir }
420cdf0e10cSrcweir 
421cdf0e10cSrcweir // XInterface
422cdf0e10cSrcweir void SAL_CALL OWeakRefListener::acquire() throw()
423cdf0e10cSrcweir {
424cdf0e10cSrcweir 	osl_incrementInterlockedCount( &m_aRefCount );
425cdf0e10cSrcweir }
426cdf0e10cSrcweir 
427cdf0e10cSrcweir // XInterface
428cdf0e10cSrcweir void SAL_CALL OWeakRefListener::release() throw()
429cdf0e10cSrcweir {
430cdf0e10cSrcweir 	if( ! osl_decrementInterlockedCount( &m_aRefCount ) )
431cdf0e10cSrcweir 		delete this;
432cdf0e10cSrcweir }
433cdf0e10cSrcweir 
434cdf0e10cSrcweir void SAL_CALL OWeakRefListener::dispose()
435cdf0e10cSrcweir 	throw(::com::sun::star::uno::RuntimeException)
436cdf0e10cSrcweir {
437cdf0e10cSrcweir 	Reference< XAdapter > xAdp;
438cdf0e10cSrcweir 	{
439cdf0e10cSrcweir 		MutexGuard guard(cppu::getWeakMutex());
440cdf0e10cSrcweir 		if( m_XWeakConnectionPoint.is() )
441cdf0e10cSrcweir 		{
442cdf0e10cSrcweir 			xAdp = m_XWeakConnectionPoint;
443cdf0e10cSrcweir 			m_XWeakConnectionPoint.clear();
444cdf0e10cSrcweir 		}
445cdf0e10cSrcweir 	}
446cdf0e10cSrcweir 
447cdf0e10cSrcweir 	if( xAdp.is() )
448cdf0e10cSrcweir 		xAdp->removeReference((XReference*)this);
449cdf0e10cSrcweir }
450cdf0e10cSrcweir 
451cdf0e10cSrcweir //------------------------------------------------------------------------
452cdf0e10cSrcweir //-- WeakReferenceHelper ----------------------------------------------------------
453cdf0e10cSrcweir //------------------------------------------------------------------------
454cdf0e10cSrcweir WeakReferenceHelper::WeakReferenceHelper(const Reference< XInterface >& xInt) SAL_THROW( () )
455cdf0e10cSrcweir 	: m_pImpl( 0 )
456cdf0e10cSrcweir {
457cdf0e10cSrcweir 	if (xInt.is())
458cdf0e10cSrcweir 	{
459cdf0e10cSrcweir 		m_pImpl = new OWeakRefListener(xInt);
460cdf0e10cSrcweir 		m_pImpl->acquire();
461cdf0e10cSrcweir 	}
462cdf0e10cSrcweir }
463cdf0e10cSrcweir 
464cdf0e10cSrcweir WeakReferenceHelper::WeakReferenceHelper(const WeakReferenceHelper& rWeakRef) SAL_THROW( () )
465cdf0e10cSrcweir 	: m_pImpl( 0 )
466cdf0e10cSrcweir {
467cdf0e10cSrcweir 	Reference< XInterface > xInt( rWeakRef.get() );
468cdf0e10cSrcweir 	if (xInt.is())
469cdf0e10cSrcweir 	{
470cdf0e10cSrcweir 		m_pImpl = new OWeakRefListener(xInt);
471cdf0e10cSrcweir 		m_pImpl->acquire();
472cdf0e10cSrcweir 	}
473cdf0e10cSrcweir }
474cdf0e10cSrcweir 
475cdf0e10cSrcweir void WeakReferenceHelper::clear() SAL_THROW( () )
476cdf0e10cSrcweir {
477cdf0e10cSrcweir     try
478cdf0e10cSrcweir     {
479cdf0e10cSrcweir         if (m_pImpl)
480cdf0e10cSrcweir         {
481cdf0e10cSrcweir             if (m_pImpl->m_XWeakConnectionPoint.is())
482cdf0e10cSrcweir             {
483cdf0e10cSrcweir                 m_pImpl->m_XWeakConnectionPoint->removeReference(
484cdf0e10cSrcweir                         (XReference*)m_pImpl);
485cdf0e10cSrcweir                 m_pImpl->m_XWeakConnectionPoint.clear();
486cdf0e10cSrcweir             }
487cdf0e10cSrcweir             m_pImpl->release();
488cdf0e10cSrcweir             m_pImpl = 0;
489cdf0e10cSrcweir         }
490cdf0e10cSrcweir     }
491cdf0e10cSrcweir     catch (RuntimeException &) { OSL_ASSERT( 0 ); } // assert here, but no unexpected()
492cdf0e10cSrcweir }
493cdf0e10cSrcweir 
494cdf0e10cSrcweir WeakReferenceHelper& WeakReferenceHelper::operator=(const WeakReferenceHelper& rWeakRef) SAL_THROW( () )
495cdf0e10cSrcweir {
496cdf0e10cSrcweir     if (this == &rWeakRef)
497cdf0e10cSrcweir     {
498cdf0e10cSrcweir         return *this;
499cdf0e10cSrcweir     }
500cdf0e10cSrcweir     Reference< XInterface > xInt( rWeakRef.get() );
501cdf0e10cSrcweir     return operator = ( xInt );
502cdf0e10cSrcweir }
503cdf0e10cSrcweir 
504cdf0e10cSrcweir WeakReferenceHelper & SAL_CALL
505cdf0e10cSrcweir WeakReferenceHelper::operator= (const Reference< XInterface > & xInt)
506cdf0e10cSrcweir SAL_THROW( () )
507cdf0e10cSrcweir {
508cdf0e10cSrcweir     try
509cdf0e10cSrcweir     {
510cdf0e10cSrcweir         clear();
511cdf0e10cSrcweir 		if (xInt.is())
512cdf0e10cSrcweir 		{
513cdf0e10cSrcweir 			m_pImpl = new OWeakRefListener(xInt);
514cdf0e10cSrcweir 			m_pImpl->acquire();
515cdf0e10cSrcweir 		}
516cdf0e10cSrcweir     }
517cdf0e10cSrcweir     catch (RuntimeException &) { OSL_ASSERT( 0 ); } // assert here, but no unexpected()
518cdf0e10cSrcweir     return *this;
519cdf0e10cSrcweir }
520cdf0e10cSrcweir 
521cdf0e10cSrcweir WeakReferenceHelper::~WeakReferenceHelper() SAL_THROW( () )
522cdf0e10cSrcweir {
523cdf0e10cSrcweir     clear();
524cdf0e10cSrcweir }
525cdf0e10cSrcweir 
526cdf0e10cSrcweir Reference< XInterface > WeakReferenceHelper::get() const SAL_THROW( () )
527cdf0e10cSrcweir {
528cdf0e10cSrcweir     try
529cdf0e10cSrcweir     {
530cdf0e10cSrcweir 	Reference< XAdapter > xAdp;
531cdf0e10cSrcweir 	{
532cdf0e10cSrcweir 		MutexGuard guard(cppu::getWeakMutex());
533cdf0e10cSrcweir 		if( m_pImpl && m_pImpl->m_XWeakConnectionPoint.is() )
534cdf0e10cSrcweir 			xAdp = m_pImpl->m_XWeakConnectionPoint;
535cdf0e10cSrcweir 	}
536cdf0e10cSrcweir 
537cdf0e10cSrcweir 	if (xAdp.is())
538cdf0e10cSrcweir 		return xAdp->queryAdapted();
539cdf0e10cSrcweir     }
540cdf0e10cSrcweir     catch (RuntimeException &) { OSL_ASSERT( 0 ); } // assert here, but no unexpected()
541cdf0e10cSrcweir 
542cdf0e10cSrcweir 	return Reference< XInterface >();
543cdf0e10cSrcweir }
544cdf0e10cSrcweir 
545cdf0e10cSrcweir }
546cdf0e10cSrcweir }
547cdf0e10cSrcweir }
548cdf0e10cSrcweir }
549cdf0e10cSrcweir 
550