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 INCLUDED_COMPHELPER_UNIQUE_DISPOSING_PTR_HXX
11 #define INCLUDED_COMPHELPER_UNIQUE_DISPOSING_PTR_HXX
13 #include <cppuhelper/implbase.hxx>
15 #include <com/sun/star/lang/XComponent.hpp>
16 #include <com/sun/star/frame/XDesktop.hpp>
17 #include <com/sun/star/lang/XServiceInfo.hpp>
19 #include <vcl/svapp.hxx>
20 #include <osl/mutex.hxx>
24 //Similar to std::unique_ptr, except additionally releases the ptr on XComponent::disposing and/or XTerminateListener::notifyTermination if supported
25 template<class T
> class unique_disposing_ptr
28 std::unique_ptr
<T
> m_xItem
;
29 css::uno::Reference
< css::frame::XTerminateListener
> m_xTerminateListener
;
31 unique_disposing_ptr(const unique_disposing_ptr
&) = delete;
32 unique_disposing_ptr
& operator=(const unique_disposing_ptr
&) = delete;
34 unique_disposing_ptr( const css::uno::Reference
< css::lang::XComponent
> &rComponent
, T
* p
= nullptr, bool bComponent
= false)
37 m_xTerminateListener
= new TerminateListener(rComponent
, *this, bComponent
);
40 virtual void reset(T
* p
= nullptr)
55 T
* operator->() const
60 operator bool () const
62 return static_cast< bool >(m_xItem
);
65 virtual ~unique_disposing_ptr()
70 class TerminateListener
: public ::cppu::WeakImplHelper
< css::frame::XTerminateListener
,
71 css::lang::XServiceInfo
>
74 css::uno::Reference
< css::lang::XComponent
> m_xComponent
;
75 unique_disposing_ptr
<T
>& m_rItem
;
78 TerminateListener(const css::uno::Reference
< css::lang::XComponent
> &rComponent
,
79 unique_disposing_ptr
<T
>& rItem
, bool bComponentDLL
) :
80 m_xComponent(rComponent
),
82 mbComponentDLL(bComponentDLL
)
84 if (m_xComponent
.is())
86 css::uno::Reference
< css::frame::XDesktop
> xDesktop(m_xComponent
, css::uno::UNO_QUERY
);
88 xDesktop
->addTerminateListener(this);
90 m_xComponent
->addEventListener(this);
94 virtual ~TerminateListener() override
96 if ( m_xComponent
.is() )
98 css::uno::Reference
< css::frame::XDesktop
> xDesktop(m_xComponent
, css::uno::UNO_QUERY
);
100 xDesktop
->removeTerminateListener(this);
102 m_xComponent
->removeEventListener(this);
107 virtual void SAL_CALL
disposing( const css::lang::EventObject
& rEvt
)
108 throw (css::uno::RuntimeException
, std::exception
) override
110 bool shutDown
= (rEvt
.Source
== m_xComponent
);
112 if (shutDown
&& m_xComponent
.is())
114 css::uno::Reference
< css::frame::XDesktop
> xDesktop(m_xComponent
, css::uno::UNO_QUERY
);
116 xDesktop
->removeTerminateListener(this);
118 m_xComponent
->removeEventListener(this);
119 m_xComponent
.clear();
126 // XTerminateListener
127 virtual void SAL_CALL
queryTermination( const css::lang::EventObject
& )
128 throw(css::frame::TerminationVetoException
,
129 css::uno::RuntimeException
, std::exception
) override
133 virtual void SAL_CALL
notifyTermination( const css::lang::EventObject
& rEvt
)
134 throw (css::uno::RuntimeException
, std::exception
) override
139 virtual OUString SAL_CALL
getImplementationName()
140 throw (css::uno::RuntimeException
, std::exception
) override
143 return OUString("com.sun.star.comp.ComponentDLLListener");
145 return OUString("com.sun.star.comp.DisposingTerminateListener");
148 virtual sal_Bool SAL_CALL
supportsService(const OUString
& /*rName*/)
149 throw (css::uno::RuntimeException
, std::exception
) override
154 virtual css::uno::Sequence
<OUString
> SAL_CALL
getSupportedServiceNames()
155 throw (css::uno::RuntimeException
, std::exception
) override
157 return css::uno::Sequence
<OUString
>();
162 //Something like an OutputDevice requires the SolarMutex to be taken before use
163 //for threadsafety. The user can ensure this, except in the case of its dtor
164 //being called from reset due to a terminate on the XComponent being called
165 //from an arbitrary thread
166 template<class T
> class unique_disposing_solar_mutex_reset_ptr
167 : public unique_disposing_ptr
<T
>
170 unique_disposing_solar_mutex_reset_ptr( const css::uno::Reference
< css::lang::XComponent
> &rComponent
, T
* p
= nullptr, bool bComponent
= false)
171 : unique_disposing_ptr
<T
>(rComponent
, p
, bComponent
)
175 virtual void reset(T
* p
= nullptr) override
177 SolarMutexGuard aGuard
;
178 unique_disposing_ptr
<T
>::reset(p
);
186 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */