xref: /trunk/main/cppuhelper/source/weak.cxx (revision 9d7e27acf3441a88e7e2e9d0bd0e0c145f24ac0d)
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
10cdf0e10cSrcweir  *
11*9d7e27acSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
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.
19cdf0e10cSrcweir  *
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