• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

STEllAR-GROUP / hpx / #882

31 Aug 2023 07:44PM UTC coverage: 41.798% (-44.7%) from 86.546%
#882

push

19442 of 46514 relevant lines covered (41.8%)

126375.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

74.7
/libs/core/runtime_local/src/pool_timer.cpp
1
//  Copyright (c) 2016 Bibek Wagle
2
//  Copyright (c) 2024-2025 Hartmut Kaiser
3
//
4
//  SPDX-License-Identifier: BSL-1.0
5
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
6
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7

8
#include <hpx/config.hpp>
9
#include <hpx/assert.hpp>
10
#include <hpx/modules/functional.hpp>
11
#include <hpx/modules/io_service.hpp>
12
#include <hpx/modules/synchronization.hpp>
13
#include <hpx/modules/thread_support.hpp>
14
#include <hpx/runtime_local/pool_timer.hpp>
15
#include <hpx/runtime_local/runtime_local.hpp>
16
#include <hpx/runtime_local/shutdown_function.hpp>
17

18
#include <asio/basic_waitable_timer.hpp>
19

20
#include <boost/parameter/aux_/preprocessor/nullptr.hpp>
21
#include <chrono>
22
#include <memory>
23
#include <mutex>
24
#include <string>
25
#include <system_error>
26

27
namespace hpx::util::detail {
28

29
    ///////////////////////////////////////////////////////////////////////////
30
    class pool_timer : public std::enable_shared_from_this<pool_timer>
31
    {
32
        friend class util::pool_timer;
33

34
        using mutex_type = hpx::spinlock;
35

36
    public:
37
        pool_timer();
38

39
        pool_timer(hpx::function<bool()> const& f,
40
            hpx::function<void()> const& on_term, std::string description,
41
            bool pre_shutdown);
42

43
        pool_timer(pool_timer const&) = delete;
44
        pool_timer(pool_timer&&) = delete;
45
        pool_timer& operator=(pool_timer const&) = delete;
46
        pool_timer& operator=(pool_timer&&) = delete;
47

48
        ~pool_timer();
49

50
        bool start(
51
            hpx::chrono::steady_duration const& time_duration, bool evaluate);
52
        bool stop();
53

×
54
        [[nodiscard]] constexpr bool is_started() const noexcept
55
        {
56
            return is_started_;
57
        }
×
58
        [[nodiscard]] constexpr bool is_terminated() const noexcept
59
        {
60
            return is_terminated_;
61
        }
62
        void timer_handler(std::error_code const&);
63

64
        void terminate();    // handle system shutdown
65
        bool stop_locked();
66

67
    private:
68
        using deadline_timer =
69
            ::asio::basic_waitable_timer<std::chrono::steady_clock>;
70

71
        mutable mutex_type mtx_;
72
        hpx::function<bool()> f_;          ///< function to call
73
        hpx::function<void()> on_term_;    ///< function to call on termination
74
        std::string description_;    ///< description of this interval timer
75

76
        bool pre_shutdown_ =
77
            false;    ///< execute termination during pre-shutdown
78
        bool is_started_ = false;    ///< timer has been started (is running)
79
        bool first_start_ =
80
            true;    ///< flag to distinguish first start invocation
81
        bool is_terminated_ = false;    ///< The timer has been terminated
82
        bool is_stopped_ = false;
×
83
        deadline_timer* timer_ = nullptr;
×
84
    };
×
85

×
86
    ///////////////////////////////////////////////////////////////////////////
×
87
    pool_timer::pool_timer()
×
88
      : timer_(new deadline_timer(
×
89
            hpx::get_runtime().get_thread_pool("timer_pool")->get_io_service()))
×
90
    {
91
    }
×
92

93
    pool_timer::pool_timer(hpx::function<bool()> const& f,
6✔
94
        hpx::function<void()> const& on_term, std::string description,
95
        bool pre_shutdown)
6✔
96
      : f_(f)
97
      , on_term_(on_term)
98
      , description_(HPX_MOVE(description))
6✔
99
      , pre_shutdown_(pre_shutdown)
6✔
100
      , timer_(new deadline_timer(
6✔
101
            hpx::get_runtime().get_thread_pool("timer_pool")->get_io_service()))
6✔
102
    {
6✔
103
    }
6✔
104

6✔
105
    void pool_timer::timer_handler(std::error_code const& err)
6✔
106
    {
107
        if (!is_stopped_ || !is_terminated_)
6✔
108
        {
109
            is_started_ = false;
6✔
110
            if (!err)
111
            {
6✔
112
                [[maybe_unused]] auto _ = f_();
113
            }
6✔
114
        }
6✔
115
    }
116

117
    bool pool_timer::start(
6✔
118
        hpx::chrono::steady_duration const& time_duration, bool /* evaluate_ */)
119
    {
6✔
120
        std::unique_lock<mutex_type> l(mtx_);
121
        if (is_terminated_)
122
            return false;
6✔
123

6✔
124
        if (!is_started_)
125
        {
126
            is_stopped_ = false;
6✔
127
            is_started_ = true;
128

6✔
129
            if (first_start_)
6✔
130
            {
131
                first_start_ = false;
6✔
132

133
                hpx::unlock_guard<std::unique_lock<mutex_type>> ul(l);
6✔
134
                if (pre_shutdown_)
135
                {
136
                    register_pre_shutdown_function(util::deferred_call(
6✔
137
                        &pool_timer::terminate, this->shared_from_this()));
138
                }
6✔
139
                else
6✔
140
                {
141
                    register_shutdown_function(util::deferred_call(
142
                        &pool_timer::terminate, this->shared_from_this()));
143
                }
×
144
            }
×
145

146
            HPX_ASSERT(timer_ != nullptr);
147
            timer_->expires_at(time_duration.from_now());
148
            timer_->async_wait(hpx::bind_front(    //-V779
149
                &pool_timer::timer_handler, this->shared_from_this()));
6✔
150

6✔
151
            return true;
×
152
        }
153
        return false;
6✔
154
    }
155

156
    bool pool_timer::stop()
157
    {
158
        std::lock_guard<mutex_type> l(mtx_);
435,333✔
159
        return stop_locked();
160
    }
435,333✔
161

435,333✔
162
    bool pool_timer::stop_locked()
163
    {
164
        if (!is_terminated_ && is_started_ && !is_stopped_)
435,339✔
165
        {
166
            is_started_ = false;
435,339✔
167
            is_stopped_ = true;
168

6✔
169
            HPX_ASSERT(timer_ != nullptr);
6✔
170
            timer_->cancel();
171
            return true;
172
        }
6✔
173
        return false;
6✔
174
    }
175

176
    void pool_timer::terminate()
177
    {
178
        std::unique_lock<mutex_type> l(mtx_);
18✔
179
        if (!is_terminated_)
180
        {
18✔
181
            is_terminated_ = true;
18✔
182
            stop_locked();
183

6✔
184
            if (on_term_)
6✔
185
            {
186
                l.unlock();
6✔
187
                on_term_();
188
            }
6✔
189
        }
190
        delete timer_;
191
        timer_ = nullptr;
192
    }
24✔
193

18✔
194
    pool_timer::~pool_timer()
18✔
195
    {
196
        try
6✔
197
        {
198
            terminate();
199
        }
200
        // NOLINTNEXTLINE(bugprone-empty-catch)
6✔
201
        catch (...)
202
        {
×
203
        }
204
    }
205
}    // namespace hpx::util::detail
×
206

12✔
207
namespace hpx::util {
208

209
    pool_timer::pool_timer() = default;
210

×
211
    pool_timer::pool_timer(hpx::function<bool()> const& f,
212
        hpx::function<void()> const& on_term, std::string const& description,
6✔
213
        bool pre_shutdown)
214
      : timer_(std::make_shared<detail::pool_timer>(
6✔
215
            f, on_term, description, pre_shutdown))
216
    {
217
    }
218

6✔
219
    pool_timer::~pool_timer()
220
    {
6✔
221
        timer_->terminate();
222
    }
6✔
223

6✔
224
    bool pool_timer::start(
225
        hpx::chrono::steady_duration const& time_duration, bool evaluate) const
6✔
226
    {
227
        return timer_->start(time_duration, evaluate);
228
    }
6✔
229

230
    bool pool_timer::stop() const
231
    {
435,333✔
232
        return timer_->stop();
233
    }
435,333✔
234

235
    bool pool_timer::is_started() const
236
    {
×
237
        return timer_->is_started();
238
    }
×
239

240
    bool pool_timer::is_terminated() const
241
    {
×
242
        return timer_->is_terminated();
243
    }
×
244
}    // namespace hpx::util
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc