1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
10 #ifndef _SCOPED_DISPOSING_PTR
11 #define _SCOPED_DISPOSING_PTR
13 #include <cppuhelper/implbase1.hxx>
14 #include <boost/utility.hpp>
15 #include <boost/scoped_ptr.hpp>
17 #include <com/sun/star/lang/XComponent.hpp>
18 #include <com/sun/star/frame/XDesktop.hpp>
20 // for locking SolarMutex: svapp + mutex
21 #include <vcl/svapp.hxx>
22 #include <osl/mutex.hxx>
26 //Similar to boost::scoped_ptr, except additionally releases the ptr on XComponent::disposing and/or XTerminateListener::notifyTermination if supported
27 template<class T
> class scoped_disposing_ptr
: private boost::noncopyable
30 boost::scoped_ptr
<T
> m_aItem
;
31 ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XTerminateListener
> m_xTerminateListener
;
33 scoped_disposing_ptr( const ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XComponent
> &rComponent
, T
* p
= 0 )
36 m_xTerminateListener
= new TerminateListener(rComponent
, *this);
39 virtual void reset(T
* p
= 0)
54 T
* operator->() const
59 operator bool () const
61 return static_cast< bool >(m_aItem
);
64 virtual ~scoped_disposing_ptr()
69 class TerminateListener
: public ::cppu::WeakImplHelper1
< ::com::sun::star::frame::XTerminateListener
>
72 ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XComponent
> m_xComponent
;
73 scoped_disposing_ptr
<T
>& m_rItem
;
75 TerminateListener(const ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XComponent
> &rComponent
,
76 scoped_disposing_ptr
<T
>& rItem
) : m_xComponent(rComponent
), m_rItem(rItem
)
78 if (m_xComponent
.is())
80 ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XDesktop
> xDesktop(m_xComponent
, ::com::sun::star::uno::UNO_QUERY
);
82 xDesktop
->addTerminateListener(this);
84 m_xComponent
->addEventListener(this);
90 if ( m_xComponent
.is() )
92 ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XDesktop
> xDesktop(m_xComponent
, ::com::sun::star::uno::UNO_QUERY
);
94 xDesktop
->removeTerminateListener(this);
96 m_xComponent
->removeEventListener(this);
102 virtual void SAL_CALL
disposing( const ::com::sun::star::lang::EventObject
& rEvt
)
103 throw (::com::sun::star::uno::RuntimeException
)
105 bool shutDown
= (rEvt
.Source
== m_xComponent
);
107 if (shutDown
&& m_xComponent
.is())
109 ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XDesktop
> xDesktop(m_xComponent
, ::com::sun::star::uno::UNO_QUERY
);
111 xDesktop
->removeTerminateListener(this);
113 m_xComponent
->removeEventListener(this);
114 m_xComponent
.clear();
121 // XTerminateListener
122 virtual void SAL_CALL
queryTermination( const ::com::sun::star::lang::EventObject
& )
123 throw(::com::sun::star::frame::TerminationVetoException
,
124 ::com::sun::star::uno::RuntimeException
)
128 virtual void SAL_CALL
notifyTermination( const ::com::sun::star::lang::EventObject
& rEvt
)
129 throw (::com::sun::star::uno::RuntimeException
)
136 //Something like an OutputDevice requires the SolarMutex to be taken before use
137 //for threadsafety. The user can ensure this, except in the case of its dtor
138 //being called from reset due to a terminate on the XComponent being called
139 //from an aribitrary thread
140 template<class T
> class scoped_disposing_solar_mutex_reset_ptr
141 : public scoped_disposing_ptr
<T
>
144 scoped_disposing_solar_mutex_reset_ptr( const ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XComponent
> &rComponent
, T
* p
= 0 )
145 : scoped_disposing_ptr
<T
>(rComponent
, p
)
149 virtual void reset(T
* p
= 0)
151 SolarMutexGuard aGuard
;
152 scoped_disposing_ptr
<T
>::reset(p
);
160 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */