Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/vcl/threadex.hxx
Line
Count
Source
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
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#ifndef INCLUDED_VCL_THREADEX_HXX
21
#define INCLUDED_VCL_THREADEX_HXX
22
23
#include <osl/conditn.hxx>
24
#include <tools/link.hxx>
25
#include <vcl/dllapi.h>
26
27
#include <exception>
28
#include <optional>
29
#include <memory>
30
31
namespace vcl
32
{
33
    class VCL_DLLPUBLIC SolarThreadExecutor
34
    {
35
        osl::Condition          m_aStart;
36
        osl::Condition          m_aFinish;
37
        bool                    m_bTimeout;
38
39
        DECL_DLLPRIVATE_LINK( worker, void*, void );
40
41
    public:
42
        SolarThreadExecutor();
43
        virtual ~SolarThreadExecutor();
44
45
        virtual void doIt() = 0;
46
        void execute();
47
    };
48
49
namespace solarthread {
50
51
/// @internal
52
namespace detail {
53
54
template <typename FuncT, typename ResultT>
55
class GenericSolarThreadExecutor final : public SolarThreadExecutor
56
{
57
public:
58
    static ResultT exec( FuncT const& func )
59
0
    {
60
0
        typedef GenericSolarThreadExecutor<FuncT, ResultT> ExecutorT;
61
0
        ::std::unique_ptr<ExecutorT> const pExecutor( new ExecutorT(func) );
62
0
        pExecutor->execute();
63
0
        if (pExecutor->m_exc)
64
0
            std::rethrow_exception(pExecutor->m_exc);
65
0
        return *pExecutor->m_result;
66
0
    }
Unexecuted instantiation: sfxbasemodel.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<SfxBaseModel::storeSelf(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_1, bool>::exec(SfxBaseModel::storeSelf(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_1 const&)
Unexecuted instantiation: desktop.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<framework::Desktop::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, com::sun::star::uno::Reference<com::sun::star::lang::XComponent> >::exec(framework::Desktop::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0 const&)
Unexecuted instantiation: dispatchhelper.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<framework::DispatchHelper::executeDispatch(com::sun::star::uno::Reference<com::sun::star::frame::XDispatchProvider> const&, rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, com::sun::star::uno::Any>::exec(framework::DispatchHelper::executeDispatch(com::sun::star::uno::Reference<com::sun::star::frame::XDispatchProvider> const&, rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0 const&)
Unexecuted instantiation: frame.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<(anonymous namespace)::XFrameImpl::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, com::sun::star::uno::Reference<com::sun::star::lang::XComponent> >::exec((anonymous namespace)::XFrameImpl::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0 const&)
67
68
private:
69
    explicit GenericSolarThreadExecutor( FuncT func )
70
0
        : m_func(std::move(func)), m_result() {}
Unexecuted instantiation: sfxbasemodel.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<SfxBaseModel::storeSelf(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_1, bool>::GenericSolarThreadExecutor(SfxBaseModel::storeSelf(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_1)
Unexecuted instantiation: desktop.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<framework::Desktop::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, com::sun::star::uno::Reference<com::sun::star::lang::XComponent> >::GenericSolarThreadExecutor(framework::Desktop::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0)
Unexecuted instantiation: dispatchhelper.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<framework::DispatchHelper::executeDispatch(com::sun::star::uno::Reference<com::sun::star::frame::XDispatchProvider> const&, rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, com::sun::star::uno::Any>::GenericSolarThreadExecutor(framework::DispatchHelper::executeDispatch(com::sun::star::uno::Reference<com::sun::star::frame::XDispatchProvider> const&, rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0)
Unexecuted instantiation: frame.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<(anonymous namespace)::XFrameImpl::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, com::sun::star::uno::Reference<com::sun::star::lang::XComponent> >::GenericSolarThreadExecutor((anonymous namespace)::XFrameImpl::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0)
71
72
    virtual void doIt() override
73
0
    {
74
0
        try {
75
0
            m_result = m_func();
76
0
        }
77
0
        catch (...) {
78
0
            m_exc = std::current_exception();
79
0
        }
80
0
    }
Unexecuted instantiation: sfxbasemodel.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<SfxBaseModel::storeSelf(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_1, bool>::doIt()
Unexecuted instantiation: desktop.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<framework::Desktop::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, com::sun::star::uno::Reference<com::sun::star::lang::XComponent> >::doIt()
Unexecuted instantiation: dispatchhelper.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<framework::DispatchHelper::executeDispatch(com::sun::star::uno::Reference<com::sun::star::frame::XDispatchProvider> const&, rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, com::sun::star::uno::Any>::doIt()
Unexecuted instantiation: frame.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<(anonymous namespace)::XFrameImpl::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, com::sun::star::uno::Reference<com::sun::star::lang::XComponent> >::doIt()
81
82
    std::exception_ptr m_exc;
83
#ifdef _MSC_VER
84
    FuncT m_func; // "const" and std::bind() results in Error C3848 expression would lose const-volatile qualifiers
85
#else
86
    FuncT const m_func;
87
#endif
88
    // using std::optional here omits the need that ResultT is default
89
    // constructable:
90
    ::std::optional<ResultT> m_result;
91
};
92
93
template <typename FuncT>
94
class GenericSolarThreadExecutor<FuncT, void> final : public SolarThreadExecutor
95
{
96
public:
97
    static void exec( FuncT const& func )
98
0
    {
99
0
        typedef GenericSolarThreadExecutor<FuncT, void> ExecutorT;
100
0
        ::std::unique_ptr<ExecutorT> const pExecutor( new ExecutorT(func) );
101
0
        pExecutor->execute();
102
0
        if (pExecutor->m_exc)
103
0
            std::rethrow_exception(pExecutor->m_exc);
104
0
    }
Unexecuted instantiation: unoctitm.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<SfxOfficeDispatch::dispatch(com::sun::star::util::URL const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, void>::exec(SfxOfficeDispatch::dispatch(com::sun::star::util::URL const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0 const&)
Unexecuted instantiation: sfxbasemodel.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<SfxBaseModel::print(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, void>::exec(SfxBaseModel::print(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0 const&)
Unexecuted instantiation: sfxbasemodel.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<SfxBaseModel::storeAsURL(rtl::OUString const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, void>::exec(SfxBaseModel::storeAsURL(rtl::OUString const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0 const&)
Unexecuted instantiation: sfxbasemodel.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<SfxBaseModel::storeToURL(rtl::OUString const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, void>::exec(SfxBaseModel::storeToURL(rtl::OUString const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0 const&)
105
106
private:
107
    explicit GenericSolarThreadExecutor( FuncT func )
108
0
        : m_func(std::move(func)) {}
Unexecuted instantiation: unoctitm.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<SfxOfficeDispatch::dispatch(com::sun::star::util::URL const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, void>::GenericSolarThreadExecutor(SfxOfficeDispatch::dispatch(com::sun::star::util::URL const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0)
Unexecuted instantiation: sfxbasemodel.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<SfxBaseModel::print(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, void>::GenericSolarThreadExecutor(SfxBaseModel::print(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0)
Unexecuted instantiation: sfxbasemodel.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<SfxBaseModel::storeAsURL(rtl::OUString const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, void>::GenericSolarThreadExecutor(SfxBaseModel::storeAsURL(rtl::OUString const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0)
Unexecuted instantiation: sfxbasemodel.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<SfxBaseModel::storeToURL(rtl::OUString const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, void>::GenericSolarThreadExecutor(SfxBaseModel::storeToURL(rtl::OUString const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0)
109
110
    virtual void doIt() override
111
0
    {
112
0
        try {
113
0
            m_func();
114
0
        }
115
0
        catch (...) {
116
0
            m_exc = std::current_exception();
117
0
        }
118
0
    }
Unexecuted instantiation: unoctitm.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<SfxOfficeDispatch::dispatch(com::sun::star::util::URL const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, void>::doIt()
Unexecuted instantiation: sfxbasemodel.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<SfxBaseModel::print(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, void>::doIt()
Unexecuted instantiation: sfxbasemodel.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<SfxBaseModel::storeAsURL(rtl::OUString const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, void>::doIt()
Unexecuted instantiation: sfxbasemodel.cxx:vcl::solarthread::detail::GenericSolarThreadExecutor<SfxBaseModel::storeToURL(rtl::OUString const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0, void>::doIt()
119
120
    std::exception_ptr m_exc;
121
    FuncT const m_func;
122
};
123
124
} // namespace detail
125
126
127
/** This function will execute the passed functor synchronously in the
128
    solar thread, thus the calling thread will (eventually) be blocked until
129
    the functor has been called.
130
    Any exception that came up calling the functor in the solar thread
131
    will be caught and rethrown in the calling thread.
132
    The result type of this function needs to be default constructable.
133
    Please keep in mind not to pass addresses to stack variables
134
    (e.g. for out parameters) to foreign threads, use inout_by_ref()
135
    for this purpose.  For in parameters, this may not affect you, because
136
    the functor object is copy constructed into free store.  This way
137
    you must not use \verbatim std::cref()/std::ref() \endverbatim or similar
138
    for objects on your thread's stack.
139
    Use inout_by_ref() or inout_by_ptr() for this purpose, e.g.
140
141
    \code{.cpp}
142
        using namespace vcl::solarthread;
143
144
        long n = 3;
145
        // calling foo( long & r ):
146
        syncExecute( std::bind( &foo, inout_by_ref(n) ) );
147
        // calling foo( long * p ):
148
        syncExecute( std::bind( &foo, inout_by_ptr(&n) ) );
149
150
        char const* pc = "default";
151
        // calling foo( char const** ppc ):
152
        syncExecute( std::bind( &foo, inout_by_ptr(&pc) ) );
153
        // calling foo( char const*& rpc ):
154
        syncExecute( std::bind( &foo, inout_by_ref(pc) ) );
155
    \endcode
156
157
    @tpl ResultT result type, defaults to FuncT::result_type to seamlessly
158
                 support mem_fn and bind
159
    @tpl FuncT functor type, let your compiler deduce this type
160
    @param func functor object to be executed in solar thread
161
    @return return value of functor
162
*/
163
template <typename FuncT>
164
inline auto syncExecute(FuncT const& func) -> decltype(func())
165
0
{
166
0
    return detail::GenericSolarThreadExecutor<
167
0
        FuncT, decltype(func())>::exec(func);
168
0
}
Unexecuted instantiation: unoctitm.cxx:decltype ({parm#1}()) vcl::solarthread::syncExecute<SfxOfficeDispatch::dispatch(com::sun::star::util::URL const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0>(SfxOfficeDispatch::dispatch(com::sun::star::util::URL const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0 const&)
Unexecuted instantiation: sfxbasemodel.cxx:decltype ({parm#1}()) vcl::solarthread::syncExecute<SfxBaseModel::print(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0>(SfxBaseModel::print(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0 const&)
Unexecuted instantiation: sfxbasemodel.cxx:decltype ({parm#1}()) vcl::solarthread::syncExecute<SfxBaseModel::storeSelf(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_1>(SfxBaseModel::storeSelf(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_1 const&)
Unexecuted instantiation: sfxbasemodel.cxx:decltype ({parm#1}()) vcl::solarthread::syncExecute<SfxBaseModel::storeAsURL(rtl::OUString const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0>(SfxBaseModel::storeAsURL(rtl::OUString const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0 const&)
Unexecuted instantiation: sfxbasemodel.cxx:decltype ({parm#1}()) vcl::solarthread::syncExecute<SfxBaseModel::storeToURL(rtl::OUString const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0>(SfxBaseModel::storeToURL(rtl::OUString const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0 const&)
Unexecuted instantiation: desktop.cxx:decltype ({parm#1}()) vcl::solarthread::syncExecute<framework::Desktop::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0>(framework::Desktop::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0 const&)
Unexecuted instantiation: dispatchhelper.cxx:decltype ({parm#1}()) vcl::solarthread::syncExecute<framework::DispatchHelper::executeDispatch(com::sun::star::uno::Reference<com::sun::star::frame::XDispatchProvider> const&, rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0>(framework::DispatchHelper::executeDispatch(com::sun::star::uno::Reference<com::sun::star::frame::XDispatchProvider> const&, rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0 const&)
Unexecuted instantiation: frame.cxx:decltype ({parm#1}()) vcl::solarthread::syncExecute<(anonymous namespace)::XFrameImpl::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0>((anonymous namespace)::XFrameImpl::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&)::$_0 const&)
169
170
} // namespace solarthread
171
} // namespace vcl
172
173
#endif // INCLUDED_VCL_THREADEX_HXX
174
175
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */