OpenDDS  Snapshot(2023/04/28-20:55)
RcObject.h
Go to the documentation of this file.
1 #ifndef OPENDDS_DCPS_RCOBJECT_H
2 #define OPENDDS_DCPS_RCOBJECT_H
3 
4 #if !defined (ACE_LACKS_PRAGMA_ONCE)
5 # pragma once
6 #endif /* ACE_LACKS_PRAGMA_ONCE */
7 
8 
10 
11 #include "dcps_export.h"
12 #include "Atomic.h"
13 #include "PoolAllocationBase.h"
14 #include "RcHandle_T.h"
15 
16 #include <ace/Guard_T.h>
17 #include <ace/Synch_Traits.h>
18 
20 
21 namespace OpenDDS {
22 namespace DCPS {
23 
24  class RcObject;
25 
27  {
28  public:
29 
31  : ptr_(ptr)
32  , ref_count_(1)
33  {
34  }
35 
36  void _add_ref()
37  {
38  ACE_Guard<ACE_SYNCH_MUTEX> guard(mx_);
39  ++ref_count_;
40  }
41 
42  void _remove_ref()
43  {
44  ACE_Guard<ACE_SYNCH_MUTEX> guard(mx_);
45  const long new_count = --ref_count_;
46  if (new_count == 0) {
47  guard.release();
48  delete this;
49  }
50  }
51 
52  RcObject* lock();
53  bool check_expire(Atomic<long>& count);
54 
55  private:
58  long ref_count_;
59  };
60 
62  public:
63 
64  virtual ~RcObject()
65  {
66  weak_object_->_remove_ref();
67  }
68 
69  virtual void _add_ref()
70  {
71  ++ref_count_;
72  }
73 
74  virtual void _remove_ref()
75  {
76  if (weak_object_->check_expire(ref_count_)) {
77  delete this;
78  }
79  }
80 
81  long ref_count() const
82  {
83  return ref_count_;
84  }
85 
87  {
88  weak_object_->_add_ref();
89  return weak_object_;
90  }
91 
92  protected:
94  : ref_count_(1)
95  , weak_object_(new WeakObject(this))
96  {}
97 
98  private:
101 
102  RcObject(const RcObject&);
103  RcObject& operator=(const RcObject&);
104  };
105 
107  {
108  ACE_Guard<ACE_SYNCH_MUTEX> guard(mx_);
109  if (ptr_) {
110  ptr_->_add_ref();
111  }
112  return ptr_;
113  }
114 
116  {
117  ACE_Guard<ACE_SYNCH_MUTEX> guard(mx_);
118  const long new_count = --count;
119  if (new_count == 0 && ptr_) {
120  ptr_ = 0;
121  return true;
122  }
123  return false;
124  }
125 
126  template <typename T>
128  {
129  public:
131  : weak_object_(0)
132  , cached_(0)
133  {
134  }
135 
136  WeakRcHandle(const T& obj)
137  : weak_object_(obj._get_weak_object())
138  , cached_(const_cast<T*>(&obj))
139  {
140  }
141 
143  : weak_object_(rch.in() ? rch.in()->_get_weak_object() : 0)
144  , cached_(rch.in())
145  {
146  }
147 
149  : weak_object_(other.weak_object_)
150  , cached_(other.cached_)
151  {
152  if (weak_object_) {
153  weak_object_->_add_ref();
154  }
155  }
156 
158  {
159  if (weak_object_) {
160  weak_object_->_remove_ref();
161  }
162  }
163 
165  {
166  WeakRcHandle tmp(other);
167  std::swap(weak_object_, tmp.weak_object_);
168  std::swap(cached_, tmp.cached_);
169  return *this;
170  }
171 
173  {
174  WeakRcHandle tmp(other);
175  std::swap(weak_object_, tmp.weak_object_);
176  std::swap(cached_, tmp.cached_);
177  return *this;
178  }
179 
180  WeakRcHandle& operator=(const T& obj)
181  {
182  WeakRcHandle tmp(obj);
183  std::swap(weak_object_, tmp.weak_object_);
184  std::swap(cached_, tmp.cached_);
185  return *this;
186  }
187 
189  {
190  if (weak_object_ && weak_object_->lock()) {
191  return RcHandle<T>(cached_, keep_count());
192  }
193  return RcHandle<T>();
194  }
195 
196  bool operator==(const WeakRcHandle& rhs) const
197  {
198  return weak_object_ == rhs.weak_object_;
199  }
200 
201  bool operator!=(const WeakRcHandle& rhs) const
202  {
203  return weak_object_ != rhs.weak_object_;
204  }
205 
206  bool operator<(const WeakRcHandle& rhs) const
207  {
208  return weak_object_ < rhs.weak_object_;
209  }
210 
211  operator bool() const
212  {
213  return weak_object_;
214  }
215 
216  void reset()
217  {
218  if (weak_object_) {
219  weak_object_->_remove_ref();
220  weak_object_ = 0;
221  }
222  cached_ = 0;
223  }
224 
225  private:
226 
228  : weak_object_(obj)
229  , cached_(dynamic_cast<T*>(obj))
230  {
231  }
232 
235  };
236 
237 } // DCPS
238 } // OPENDDS
239 
241 
242 #endif /* end of include guard: OPENDDS_DCPS_RCOBJECT_H */
void swap(MessageBlock &lhs, MessageBlock &rhs)
WeakRcHandle(const RcHandle< T > &rch)
Definition: RcObject.h:142
WeakRcHandle & operator=(const WeakRcHandle &other)
Definition: RcObject.h:164
#define ACE_SYNCH_MUTEX
#define OpenDDS_Dcps_Export
Definition: dcps_export.h:24
int release(void)
bool check_expire(Atomic< long > &count)
Definition: RcObject.h:115
long ref_count() const
Definition: RcObject.h:81
virtual void _add_ref()
Definition: RcObject.h:69
WeakRcHandle(const WeakRcHandle &other)
Definition: RcObject.h:148
bool operator!=(const WeakRcHandle &rhs) const
Definition: RcObject.h:201
WeakObject * weak_object_
Definition: RcObject.h:233
bool operator<(const WeakRcHandle &rhs) const
Definition: RcObject.h:206
virtual void _remove_ref()
Definition: RcObject.h:74
ACE_SYNCH_MUTEX mx_
Definition: RcObject.h:56
WeakRcHandle(const T &obj)
Definition: RcObject.h:136
WeakObject * weak_object_
Definition: RcObject.h:100
WeakRcHandle(WeakObject *obj)
Definition: RcObject.h:227
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
WeakObject(RcObject *ptr)
Definition: RcObject.h:30
WeakObject * _get_weak_object() const
Definition: RcObject.h:86
bool operator==(const WeakRcHandle &rhs) const
Definition: RcObject.h:196
RcHandle< T > lock() const
Definition: RcObject.h:188
Atomic< long > ref_count_
Definition: RcObject.h:99
WeakRcHandle & operator=(const RcHandle< T > &other)
Definition: RcObject.h:172
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28
WeakRcHandle & operator=(const T &obj)
Definition: RcObject.h:180