Fast RTPS  Version 2.14.5
Fast RTPS
RefCountedPointer.hpp
1// Copyright 2024 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
19#ifndef UTILS__REFCOUNTEDPOINTER_HPP
20#define UTILS__REFCOUNTEDPOINTER_HPP
21
22#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
23
24#include <atomic>
25#include <cassert>
26#include <condition_variable>
27#include <cstdint>
28#include <memory>
29#include <mutex>
30
31namespace eprosima {
32namespace fastrtps {
33
54template<typename T>
56{
57public:
58
59 class Instance;
60
69 T* ptr)
70 : ptr_(ptr)
71 , is_active_(true)
72 , instances_(0)
73 {
74 assert(nullptr != ptr);
75 }
76
77 ~RefCountedPointer() = default;
78
79 // Non-copyable and non-movable
81 const RefCountedPointer&) = delete;
83 const RefCountedPointer&) = delete;
85 RefCountedPointer&&) = delete;
87 RefCountedPointer&&) = delete;
88
95 {
96 public:
97
102 explicit Instance(
103 const std::shared_ptr<RefCountedPointer<T>>& parent)
104 : parent_(parent)
105 , ptr_(parent && parent->is_active_ ? parent->ptr_ : nullptr)
106 {
107 if (parent_)
108 {
109 parent_->inc_instances();
110 }
111 }
112
117 {
118 if (parent_)
119 {
120 parent_->dec_instances();
121 }
122 }
123
124 // Non-copyable, default movable
126 const Instance&) = delete;
128 const Instance&) = delete;
130 Instance&&) = default;
132 Instance&&) = default;
133
137 operator bool() const
138 {
139 return nullptr != ptr_;
140 }
141
145 T* operator ->() const
146 {
147 assert(nullptr != ptr_);
148 return ptr_;
149 }
150
151 private:
152
153 std::shared_ptr<RefCountedPointer<T>> parent_;
154 T* const ptr_;
155 };
156
161 {
162 std::unique_lock<std::mutex> lock(mutex_);
163 is_active_ = false;
164 cv_.wait(lock, [this]() -> bool
165 {
166 return instances_ == 0;
167 });
168 }
169
170private:
171
175 void inc_instances()
176 {
177 std::unique_lock<std::mutex> lock(mutex_);
178 ++instances_;
179 }
180
184 void dec_instances()
185 {
186 std::unique_lock<std::mutex> lock(mutex_);
187 --instances_;
188 if (instances_ == 0)
189 {
190 cv_.notify_one();
191 }
192 }
193
197 T* const ptr_;
198
203 std::atomic<bool> is_active_;
204
208 mutable std::mutex mutex_;
209 std::condition_variable cv_;
210
214 size_t instances_;
215};
216
217} // namespace fastdds
218} // namespace eprosima
219
220#endif // DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
221
222#endif // UTILS__REFCOUNTEDPOINTER_HPP
Class to manage the local pointer instance.
Definition: RefCountedPointer.hpp:95
Instance(const std::shared_ptr< RefCountedPointer< T > > &parent)
Constructor.
Definition: RefCountedPointer.hpp:102
T * operator->() const
operator to call the T methods.
Definition: RefCountedPointer.hpp:145
~Instance()
Destructor.
Definition: RefCountedPointer.hpp:116
Instance & operator=(const Instance &)=delete
Class to manage a local pointer with reference counting.
Definition: RefCountedPointer.hpp:56
void deactivate()
Ensure no more valid local pointer instances are created, and wait for current ones to die.
Definition: RefCountedPointer.hpp:160
RefCountedPointer & operator=(const RefCountedPointer &)=delete
RefCountedPointer(RefCountedPointer &&)=delete
RefCountedPointer(T *ptr)
Explicit constructor.
Definition: RefCountedPointer.hpp:68
RefCountedPointer(const RefCountedPointer &)=delete
eProsima namespace.
Definition: LibrarySettingsAttributes.h:23