Coverage Report

Created: 2025-06-13 06:46

/src/Fast-DDS/src/cpp/rtps/resources/ResourceEvent.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
/**
16
 * @file ResourceEvent.h
17
 *
18
 */
19
20
#ifndef FASTDDS_RTPS_RESOURCES__RESOURCEEVENT_H
21
#define FASTDDS_RTPS_RESOURCES__RESOURCEEVENT_H
22
23
#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
24
25
#include <atomic>
26
#include <functional>
27
#include <memory>
28
#include <vector>
29
30
#include <fastdds/rtps/attributes/ThreadSettings.hpp>
31
#include <fastdds/utils/TimedMutex.hpp>
32
#include <fastdds/utils/TimedConditionVariable.hpp>
33
34
namespace eprosima {
35
36
class thread;
37
38
namespace fastdds {
39
namespace rtps {
40
41
class TimedEventImpl;
42
43
/**
44
 * This class centralizes all operations over timed events in the same thread.
45
 * @ingroup MANAGEMENT_MODULE
46
 */
47
class ResourceEvent
48
{
49
public:
50
51
    ResourceEvent();
52
53
    ~ResourceEvent();
54
55
    /*!
56
     * @brief Method to initialize the internal thread.
57
     *
58
     * @param [in]  thread_cfg  Settings to apply to the created thread.
59
     * @param [in]  name_fmt    A null-terminated string to be used as the format argument of
60
     *                         a `snprintf` like function, taking `thread_id` as additional
61
     *                         argument, and used to give a name to the created thread.
62
     * @param [in]  thread_id   Single variadic argument passed to the formatting function.
63
     */
64
    void init_thread(
65
            const fastdds::rtps::ThreadSettings& thread_cfg = {},
66
            const char* name_fmt = "event %u",
67
            uint32_t thread_id = 0);
68
69
    void stop_thread();
70
71
    /*!
72
     * @brief This method informs that a TimedEventImpl has been created.
73
     *
74
     * This method has to be called when creating a TimedEventImpl object.
75
     * @param event TimedEventImpl object that has been created.
76
     */
77
    void register_timer(
78
            TimedEventImpl* event);
79
80
    /*!
81
     * @brief This method removes a TimedEventImpl object in case it is waiting to be processed by ResourceEvent's
82
     * internal thread.
83
     *
84
     * This method has to be called before deleting the TimedEventImpl object.
85
     * This method cancels any operation of the timer.
86
     * Then it avoids the situation of the execution thread calling the event handler when it was previously removed.
87
     * @param event TimedEventImpl object that will be deleted and we have to be sure all its operations are cancelled.
88
     */
89
    void unregister_timer(
90
            TimedEventImpl* event);
91
92
    /*!
93
     * @brief This method notifies to ResourceEvent that the TimedEventImpl object has operations to be scheduled.
94
     *
95
     * These operations can be the cancellation of the timer or starting another async_wait.
96
     * @param event TimedEventImpl object that has operations to be scheduled.
97
     */
98
    void notify(
99
            TimedEventImpl* event);
100
101
    /*!
102
     * @brief This method notifies to ResourceEvent that the TimedEventImpl object has operations to be scheduled.
103
     *
104
     * These operations can be the cancellation of the timer or starting another async_wait.
105
     * @note Non-blocking call version of the method.
106
     * @param event TimedEventImpl object that has operations to be scheduled.
107
     * @param timeout Maximum blocking time of the method.
108
     */
109
    void notify(
110
            TimedEventImpl* event,
111
            const std::chrono::steady_clock::time_point& timeout);
112
113
private:
114
115
    //! Warns the internal thread can stop.
116
    std::atomic<bool> stop_{ false };
117
118
    //! Protects internal data.
119
    TimedMutex mutex_;
120
121
    //! Used to warn about changes on allow_vector_manipulation_.
122
    TimedConditionVariable cv_manipulation_;
123
124
    //! Flag used to allow a thread to manipulate the timer collections when the execution thread is not using them.
125
    bool allow_vector_manipulation_ = true;
126
127
    //! Used to warn there are new TimedEventImpl objects to be processed.
128
    TimedConditionVariable cv_;
129
130
    //! The total number of created timers.
131
    size_t timers_count_ = 0;
132
133
    //! Collection of events pending update action.
134
    std::vector<TimedEventImpl*> pending_timers_;
135
136
    //! Collection of registered events waiting completion.
137
    std::vector<TimedEventImpl*> active_timers_;
138
139
    //! Prevents iterator invalidation when active_timers are manipulated inside loops
140
    std::atomic<bool> skip_checking_active_timers_;
141
142
    //! Current time as seen by the execution thread.
143
    std::chrono::steady_clock::time_point current_time_;
144
145
    //! Execution thread.
146
    std::unique_ptr<eprosima::thread> thread_;
147
148
    /*!
149
     * @brief Registers a new TimedEventImpl object in the internal queue to be processed.
150
     * Non thread safe.
151
     * @param event Event to be added in the queue.
152
     * @return True value if the insertion was successful. In other case, it return False.
153
     */
154
    bool register_timer_nts(
155
            TimedEventImpl* event);
156
157
    //! Method called by the internal thread.
158
    void event_service();
159
160
    //! Sorts waiting timers in ascending order of trigger time.
161
    void sort_timers();
162
163
    //! Updates internal register of current time.
164
    void update_current_time();
165
166
    //! Method called by the internal thread to process due actions.
167
    void do_timer_actions();
168
169
    //! Ensures internal collections can accommodate current total number of timers.
170
    void resize_collections()
171
0
    {
172
0
        pending_timers_.reserve(timers_count_);
173
0
        active_timers_.reserve(timers_count_);
174
0
    }
175
176
};
177
178
} /* namespace rtps */
179
} /* namespace fastdds */
180
} /* namespace eprosima */
181
182
#endif //DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
183
184
#endif //FASTDDS_RTPS_RESOURCES__RESOURCEEVENT_H