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