Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/include/comphelper/unique_disposing_ptr.hxx
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
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
 */
9
10
#ifndef INCLUDED_COMPHELPER_UNIQUE_DISPOSING_PTR_HXX
11
#define INCLUDED_COMPHELPER_UNIQUE_DISPOSING_PTR_HXX
12
13
#include <memory>
14
#include <cppuhelper/implbase.hxx>
15
16
#include <com/sun/star/lang/XComponent.hpp>
17
#include <com/sun/star/frame/XDesktop.hpp>
18
#include <com/sun/star/lang/XServiceInfo.hpp>
19
20
#include <o3tl/deleter.hxx>
21
#include <utility>
22
#include <vcl/svapp.hxx>
23
24
namespace comphelper
25
{
26
//Similar to std::unique_ptr, except additionally releases the ptr on XComponent::disposing and/or XTerminateListener::notifyTermination if supported
27
template<class T> class unique_disposing_ptr
28
{
29
private:
30
    std::unique_ptr<T, o3tl::default_delete<T>> m_xItem;
31
    css::uno::Reference< css::frame::XTerminateListener> m_xTerminateListener;
32
33
    unique_disposing_ptr(const unique_disposing_ptr&) = delete;
34
    unique_disposing_ptr& operator=(const unique_disposing_ptr&) = delete;
35
public:
36
    unique_disposing_ptr( const css::uno::Reference< css::lang::XComponent > &rComponent, T * p = nullptr, bool bComponent = false)
37
14
        : m_xItem(p)
38
14
    {
39
14
        m_xTerminateListener = new TerminateListener(rComponent, *this, bComponent);
40
14
    }
textlayoutdevice.cxx:comphelper::unique_disposing_ptr<drawinglayer::primitive2d::(anonymous namespace)::ImpTimedRefDev>::unique_disposing_ptr(com::sun::star::uno::Reference<com::sun::star::lang::XComponent> const&, drawinglayer::primitive2d::(anonymous namespace)::ImpTimedRefDev*, bool)
Line
Count
Source
37
5
        : m_xItem(p)
38
5
    {
39
5
        m_xTerminateListener = new TerminateListener(rComponent, *this, bComponent);
40
5
    }
comphelper::unique_disposing_ptr<SwDLL>::unique_disposing_ptr(com::sun::star::uno::Reference<com::sun::star::lang::XComponent> const&, SwDLL*, bool)
Line
Count
Source
37
9
        : m_xItem(p)
38
9
    {
39
9
        m_xTerminateListener = new TerminateListener(rComponent, *this, bComponent);
40
9
    }
Unexecuted instantiation: comphelper::unique_disposing_ptr<sd::SdGlobalResourceContainer>::unique_disposing_ptr(com::sun::star::uno::Reference<com::sun::star::lang::XComponent> const&, sd::SdGlobalResourceContainer*, bool)
41
42
    virtual void reset(T * p = nullptr)
43
28
    {
44
28
        m_xItem.reset(p);
45
28
    }
textlayoutdevice.cxx:comphelper::unique_disposing_ptr<drawinglayer::primitive2d::(anonymous namespace)::ImpTimedRefDev>::reset(drawinglayer::primitive2d::(anonymous namespace)::ImpTimedRefDev*)
Line
Count
Source
43
10
    {
44
10
        m_xItem.reset(p);
45
10
    }
comphelper::unique_disposing_ptr<SwDLL>::reset(SwDLL*)
Line
Count
Source
43
18
    {
44
18
        m_xItem.reset(p);
45
18
    }
Unexecuted instantiation: comphelper::unique_disposing_ptr<sd::SdGlobalResourceContainer>::reset(sd::SdGlobalResourceContainer*)
46
47
    T & operator*() const
48
    {
49
        return *m_xItem;
50
    }
51
52
    T * get() const
53
9
    {
54
9
        return m_xItem.get();
55
9
    }
comphelper::unique_disposing_ptr<SwDLL>::get() const
Line
Count
Source
53
9
    {
54
9
        return m_xItem.get();
55
9
    }
Unexecuted instantiation: comphelper::unique_disposing_ptr<sd::SdGlobalResourceContainer>::get() const
56
57
    T * operator->() const
58
5.00k
    {
59
5.00k
        return m_xItem.get();
60
5.00k
    }
61
62
    operator bool () const
63
2.50k
    {
64
2.50k
        return static_cast< bool >(m_xItem);
65
2.50k
    }
66
67
    virtual ~unique_disposing_ptr() COVERITY_NOEXCEPT_FALSE
68
14
    {
69
14
        reset();
70
14
    }
textlayoutdevice.cxx:comphelper::unique_disposing_ptr<drawinglayer::primitive2d::(anonymous namespace)::ImpTimedRefDev>::~unique_disposing_ptr()
Line
Count
Source
68
5
    {
69
5
        reset();
70
5
    }
comphelper::unique_disposing_ptr<SwDLL>::~unique_disposing_ptr()
Line
Count
Source
68
9
    {
69
9
        reset();
70
9
    }
Unexecuted instantiation: comphelper::unique_disposing_ptr<sd::SdGlobalResourceContainer>::~unique_disposing_ptr()
71
private:
72
    class TerminateListener final : public ::cppu::WeakImplHelper< css::frame::XTerminateListener,
73
                                            css::lang::XServiceInfo>
74
    {
75
    private:
76
        css::uno::Reference< css::lang::XComponent > m_xComponent;
77
        unique_disposing_ptr<T>& m_rItem;
78
        bool const mbComponentDLL;
79
    public:
80
        TerminateListener(css::uno::Reference< css::lang::XComponent > xComponent,
81
            unique_disposing_ptr<T>& rItem, bool bComponentDLL) :
82
14
                    m_xComponent(std::move(xComponent)),
83
14
                    m_rItem(rItem),
84
14
                    mbComponentDLL(bComponentDLL)
85
14
        {
86
14
            if (m_xComponent.is())
87
14
            {
88
14
                css::uno::Reference< css::frame::XDesktop> xDesktop(m_xComponent, css::uno::UNO_QUERY);
89
14
                if (xDesktop.is())
90
9
                    xDesktop->addTerminateListener(this);
91
5
                else
92
5
                    m_xComponent->addEventListener(this);
93
14
            }
94
14
        }
textlayoutdevice.cxx:comphelper::unique_disposing_ptr<drawinglayer::primitive2d::(anonymous namespace)::ImpTimedRefDev>::TerminateListener::TerminateListener(com::sun::star::uno::Reference<com::sun::star::lang::XComponent>, comphelper::unique_disposing_ptr<drawinglayer::primitive2d::(anonymous namespace)::ImpTimedRefDev>&, bool)
Line
Count
Source
82
5
                    m_xComponent(std::move(xComponent)),
83
5
                    m_rItem(rItem),
84
5
                    mbComponentDLL(bComponentDLL)
85
5
        {
86
5
            if (m_xComponent.is())
87
5
            {
88
5
                css::uno::Reference< css::frame::XDesktop> xDesktop(m_xComponent, css::uno::UNO_QUERY);
89
5
                if (xDesktop.is())
90
0
                    xDesktop->addTerminateListener(this);
91
5
                else
92
5
                    m_xComponent->addEventListener(this);
93
5
            }
94
5
        }
comphelper::unique_disposing_ptr<SwDLL>::TerminateListener::TerminateListener(com::sun::star::uno::Reference<com::sun::star::lang::XComponent>, comphelper::unique_disposing_ptr<SwDLL>&, bool)
Line
Count
Source
82
9
                    m_xComponent(std::move(xComponent)),
83
9
                    m_rItem(rItem),
84
9
                    mbComponentDLL(bComponentDLL)
85
9
        {
86
9
            if (m_xComponent.is())
87
9
            {
88
9
                css::uno::Reference< css::frame::XDesktop> xDesktop(m_xComponent, css::uno::UNO_QUERY);
89
9
                if (xDesktop.is())
90
9
                    xDesktop->addTerminateListener(this);
91
0
                else
92
0
                    m_xComponent->addEventListener(this);
93
9
            }
94
9
        }
Unexecuted instantiation: comphelper::unique_disposing_ptr<sd::SdGlobalResourceContainer>::TerminateListener::TerminateListener(com::sun::star::uno::Reference<com::sun::star::lang::XComponent>, comphelper::unique_disposing_ptr<sd::SdGlobalResourceContainer>&, bool)
95
96
        virtual ~TerminateListener() override
97
0
        {
98
0
            if ( m_xComponent.is() )
99
0
            {
100
0
                css::uno::Reference< css::frame::XDesktop> xDesktop(m_xComponent, css::uno::UNO_QUERY);
101
0
                if (xDesktop.is())
102
0
                    xDesktop->removeTerminateListener(this);
103
0
                else
104
0
                    m_xComponent->removeEventListener(this);
105
0
            }
106
0
        }
Unexecuted instantiation: textlayoutdevice.cxx:comphelper::unique_disposing_ptr<drawinglayer::primitive2d::(anonymous namespace)::ImpTimedRefDev>::TerminateListener::~TerminateListener()
Unexecuted instantiation: comphelper::unique_disposing_ptr<SwDLL>::TerminateListener::~TerminateListener()
Unexecuted instantiation: comphelper::unique_disposing_ptr<sd::SdGlobalResourceContainer>::TerminateListener::~TerminateListener()
107
108
        // XEventListener
109
        virtual void SAL_CALL disposing( const css::lang::EventObject& rEvt ) override
110
0
        {
111
0
            bool shutDown = (rEvt.Source == m_xComponent);
112
113
0
            if (shutDown && m_xComponent.is())
114
0
            {
115
0
                css::uno::Reference< css::frame::XDesktop> xDesktop(m_xComponent, css::uno::UNO_QUERY);
116
0
                if (xDesktop.is())
117
0
                    xDesktop->removeTerminateListener(this);
118
0
                else
119
0
                    m_xComponent->removeEventListener(this);
120
0
                m_xComponent.clear();
121
0
            }
122
123
0
            if (shutDown)
124
0
               m_rItem.reset();
125
0
        }
Unexecuted instantiation: textlayoutdevice.cxx:comphelper::unique_disposing_ptr<drawinglayer::primitive2d::(anonymous namespace)::ImpTimedRefDev>::TerminateListener::disposing(com::sun::star::lang::EventObject const&)
Unexecuted instantiation: comphelper::unique_disposing_ptr<SwDLL>::TerminateListener::disposing(com::sun::star::lang::EventObject const&)
Unexecuted instantiation: comphelper::unique_disposing_ptr<sd::SdGlobalResourceContainer>::TerminateListener::disposing(com::sun::star::lang::EventObject const&)
126
127
        // XTerminateListener
128
        virtual void SAL_CALL queryTermination( const css::lang::EventObject& ) override
129
0
        {
130
0
        }
Unexecuted instantiation: textlayoutdevice.cxx:comphelper::unique_disposing_ptr<drawinglayer::primitive2d::(anonymous namespace)::ImpTimedRefDev>::TerminateListener::queryTermination(com::sun::star::lang::EventObject const&)
Unexecuted instantiation: comphelper::unique_disposing_ptr<SwDLL>::TerminateListener::queryTermination(com::sun::star::lang::EventObject const&)
Unexecuted instantiation: comphelper::unique_disposing_ptr<sd::SdGlobalResourceContainer>::TerminateListener::queryTermination(com::sun::star::lang::EventObject const&)
131
132
        virtual void SAL_CALL notifyTermination( const css::lang::EventObject& rEvt ) override
133
0
        {
134
0
            disposing(rEvt);
135
0
        }
Unexecuted instantiation: textlayoutdevice.cxx:comphelper::unique_disposing_ptr<drawinglayer::primitive2d::(anonymous namespace)::ImpTimedRefDev>::TerminateListener::notifyTermination(com::sun::star::lang::EventObject const&)
Unexecuted instantiation: comphelper::unique_disposing_ptr<SwDLL>::TerminateListener::notifyTermination(com::sun::star::lang::EventObject const&)
Unexecuted instantiation: comphelper::unique_disposing_ptr<sd::SdGlobalResourceContainer>::TerminateListener::notifyTermination(com::sun::star::lang::EventObject const&)
136
137
        virtual OUString SAL_CALL getImplementationName() override
138
9
        {
139
9
            if (mbComponentDLL)
140
9
                return u"com.sun.star.comp.ComponentDLLListener"_ustr;
141
0
            else
142
0
                return u"com.sun.star.comp.DisposingTerminateListener"_ustr;
143
9
        }
Unexecuted instantiation: textlayoutdevice.cxx:comphelper::unique_disposing_ptr<drawinglayer::primitive2d::(anonymous namespace)::ImpTimedRefDev>::TerminateListener::getImplementationName()
comphelper::unique_disposing_ptr<SwDLL>::TerminateListener::getImplementationName()
Line
Count
Source
138
9
        {
139
9
            if (mbComponentDLL)
140
9
                return u"com.sun.star.comp.ComponentDLLListener"_ustr;
141
0
            else
142
0
                return u"com.sun.star.comp.DisposingTerminateListener"_ustr;
143
9
        }
Unexecuted instantiation: comphelper::unique_disposing_ptr<sd::SdGlobalResourceContainer>::TerminateListener::getImplementationName()
144
145
        virtual sal_Bool SAL_CALL supportsService(const OUString& /*rName*/) override
146
0
        {
147
0
            return false;
148
0
        }
Unexecuted instantiation: textlayoutdevice.cxx:comphelper::unique_disposing_ptr<drawinglayer::primitive2d::(anonymous namespace)::ImpTimedRefDev>::TerminateListener::supportsService(rtl::OUString const&)
Unexecuted instantiation: comphelper::unique_disposing_ptr<SwDLL>::TerminateListener::supportsService(rtl::OUString const&)
Unexecuted instantiation: comphelper::unique_disposing_ptr<sd::SdGlobalResourceContainer>::TerminateListener::supportsService(rtl::OUString const&)
149
150
        virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
151
0
        {
152
0
            return css::uno::Sequence<OUString>();
153
0
        }
Unexecuted instantiation: textlayoutdevice.cxx:comphelper::unique_disposing_ptr<drawinglayer::primitive2d::(anonymous namespace)::ImpTimedRefDev>::TerminateListener::getSupportedServiceNames()
Unexecuted instantiation: comphelper::unique_disposing_ptr<SwDLL>::TerminateListener::getSupportedServiceNames()
Unexecuted instantiation: comphelper::unique_disposing_ptr<sd::SdGlobalResourceContainer>::TerminateListener::getSupportedServiceNames()
154
   };
155
};
156
157
//Something like an OutputDevice requires the SolarMutex to be taken before use
158
//for threadsafety. The user can ensure this, except in the case of its dtor
159
//being called from reset due to a terminate on the XComponent being called
160
//from an arbitrary thread
161
template<class T> class unique_disposing_solar_mutex_reset_ptr
162
    : public unique_disposing_ptr<T>
163
{
164
public:
165
    unique_disposing_solar_mutex_reset_ptr( const css::uno::Reference< css::lang::XComponent > &rComponent, T * p = nullptr, bool bComponent = false)
166
9
        : unique_disposing_ptr<T>(rComponent, p, bComponent)
167
9
    {
168
9
    }
comphelper::unique_disposing_solar_mutex_reset_ptr<SwDLL>::unique_disposing_solar_mutex_reset_ptr(com::sun::star::uno::Reference<com::sun::star::lang::XComponent> const&, SwDLL*, bool)
Line
Count
Source
166
9
        : unique_disposing_ptr<T>(rComponent, p, bComponent)
167
9
    {
168
9
    }
Unexecuted instantiation: comphelper::unique_disposing_solar_mutex_reset_ptr<sd::SdGlobalResourceContainer>::unique_disposing_solar_mutex_reset_ptr(com::sun::star::uno::Reference<com::sun::star::lang::XComponent> const&, sd::SdGlobalResourceContainer*, bool)
169
170
    virtual void reset(T * p = nullptr) override
171
9
    {
172
9
        SolarMutexGuard aGuard;
173
9
        unique_disposing_ptr<T>::reset(p);
174
9
    }
comphelper::unique_disposing_solar_mutex_reset_ptr<SwDLL>::reset(SwDLL*)
Line
Count
Source
171
9
    {
172
9
        SolarMutexGuard aGuard;
173
9
        unique_disposing_ptr<T>::reset(p);
174
9
    }
Unexecuted instantiation: comphelper::unique_disposing_solar_mutex_reset_ptr<sd::SdGlobalResourceContainer>::reset(sd::SdGlobalResourceContainer*)
175
176
    virtual ~unique_disposing_solar_mutex_reset_ptr() override
177
9
    {
178
9
        if (unique_disposing_ptr<T>::get() && comphelper::SolarMutex::get())
179
9
            reset();
180
9
    }
comphelper::unique_disposing_solar_mutex_reset_ptr<SwDLL>::~unique_disposing_solar_mutex_reset_ptr()
Line
Count
Source
177
9
    {
178
9
        if (unique_disposing_ptr<T>::get() && comphelper::SolarMutex::get())
179
9
            reset();
180
9
    }
Unexecuted instantiation: comphelper::unique_disposing_solar_mutex_reset_ptr<sd::SdGlobalResourceContainer>::~unique_disposing_solar_mutex_reset_ptr()
181
};
182
183
}
184
185
#endif
186
187
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */