build fix
[LibreOffice.git] / include / comphelper / unique_disposing_ptr.hxx
blobc986b12e316feb504e4d127e3711df6e2fa107df
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
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>
22 namespace comphelper
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
27 private:
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;
33 public:
34 unique_disposing_ptr( const css::uno::Reference< css::lang::XComponent > &rComponent, T * p = nullptr, bool bComponent = false)
35 : m_xItem(p)
37 m_xTerminateListener = new TerminateListener(rComponent, *this, bComponent);
40 virtual void reset(T * p = nullptr)
42 m_xItem.reset(p);
45 T & operator*() const
47 return *m_xItem;
50 T * get() const
52 return m_xItem.get();
55 T * operator->() const
57 return m_xItem.get();
60 operator bool () const
62 return static_cast< bool >(m_xItem);
65 virtual ~unique_disposing_ptr()
67 reset();
69 private:
70 class TerminateListener : public ::cppu::WeakImplHelper< css::frame::XTerminateListener,
71 css::lang::XServiceInfo>
73 private:
74 css::uno::Reference< css::lang::XComponent > m_xComponent;
75 unique_disposing_ptr<T>& m_rItem;
76 bool mbComponentDLL;
77 public:
78 TerminateListener(const css::uno::Reference< css::lang::XComponent > &rComponent,
79 unique_disposing_ptr<T>& rItem, bool bComponentDLL) :
80 m_xComponent(rComponent),
81 m_rItem(rItem),
82 mbComponentDLL(bComponentDLL)
84 if (m_xComponent.is())
86 css::uno::Reference< css::frame::XDesktop> xDesktop(m_xComponent, css::uno::UNO_QUERY);
87 if (xDesktop.is())
88 xDesktop->addTerminateListener(this);
89 else
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);
99 if (xDesktop.is())
100 xDesktop->removeTerminateListener(this);
101 else
102 m_xComponent->removeEventListener(this);
106 // XEventListener
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);
115 if (xDesktop.is())
116 xDesktop->removeTerminateListener(this);
117 else
118 m_xComponent->removeEventListener(this);
119 m_xComponent.clear();
122 if (shutDown)
123 m_rItem.reset();
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
136 disposing(rEvt);
139 virtual OUString SAL_CALL getImplementationName()
140 throw (css::uno::RuntimeException, std::exception) override
142 if (mbComponentDLL)
143 return OUString("com.sun.star.comp.ComponentDLLListener");
144 else
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
151 return false;
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>
169 public:
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);
184 #endif
186 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */