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 
31 namespace eprosima {
32 namespace fastrtps {
33 
54 template<typename T>
56 {
57 public:
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 
94  class Instance
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 
160  void deactivate()
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 
170 private:
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
T * operator->() const
operator to call the T methods.
Definition: RefCountedPointer.hpp:145
~Instance()
Destructor.
Definition: RefCountedPointer.hpp:116
Instance(const std::shared_ptr< RefCountedPointer< T >> &parent)
Constructor.
Definition: RefCountedPointer.hpp:102
Instance & operator=(const Instance &)=delete
Class to manage a local pointer with reference counting.
Definition: RefCountedPointer.hpp:56
RefCountedPointer & operator=(const RefCountedPointer &)=delete
void deactivate()
Ensure no more valid local pointer instances are created, and wait for current ones to die.
Definition: RefCountedPointer.hpp:160
RefCountedPointer(RefCountedPointer &&)=delete
RefCountedPointer(T *ptr)
Explicit constructor.
Definition: RefCountedPointer.hpp:68
RefCountedPointer(const RefCountedPointer &)=delete
eProsima namespace.
Definition: LibrarySettingsAttributes.h:23