2 #include "ace/Guard_T.h"
3 #if !defined (ACE_NEW_THROWS_EXCEPTIONS)
4 # include "ace/Log_Category.h"
5 #endif /* ACE_NEW_THROWS_EXCEPTIONS */
7 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
9 template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
10 ACE_Bound_Ptr_Counter<ACE_LOCK>::internal_create (long init_obj_ref_count)
12 ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = 0;
14 ACE_Bound_Ptr_Counter<ACE_LOCK> (init_obj_ref_count),
19 template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
20 ACE_Bound_Ptr_Counter<ACE_LOCK>::create_strong (void)
22 // Set initial object reference count to 1.
23 ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = internal_create (1);
24 #if defined (ACE_NEW_THROWS_EXCEPTIONS)
28 ACE_ASSERT (temp != 0);
29 #endif /* ACE_NEW_THROWS_EXCEPTIONS */
35 template <class ACE_LOCK> inline long
36 ACE_Bound_Ptr_Counter<ACE_LOCK>::attach_strong (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
38 ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, -1);
40 // Can't attach a strong pointer to an object that has already been deleted.
41 if (counter->obj_ref_count_ == -1)
44 long new_obj_ref_count = ++counter->obj_ref_count_;
45 ++counter->self_ref_count_;
47 return new_obj_ref_count;
50 template <class ACE_LOCK> inline long
51 ACE_Bound_Ptr_Counter<ACE_LOCK>::detach_strong (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
53 ACE_Bound_Ptr_Counter<ACE_LOCK> *counter_del = 0;
54 long new_obj_ref_count;
57 ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, -1);
59 if ((new_obj_ref_count = --counter->obj_ref_count_) == 0)
60 // Change the object reference count to -1 to indicate that the
61 // object has been deleted, as opposed to a weak pointer that
62 // simply hasn't had any strong pointers created from it yet.
63 counter->obj_ref_count_ = -1;
65 if (--counter->self_ref_count_ == 0)
66 // Since counter contains the lock held by the guard, the
67 // guard needs to be released before freeing the memory holding
68 // the lock. So save the pointer to free, then release, then
70 counter_del = counter;
76 return new_obj_ref_count;
79 template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
80 ACE_Bound_Ptr_Counter<ACE_LOCK>::create_weak (void)
82 // Set initial object reference count to 0.
84 ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = internal_create (0);
85 #if defined (ACE_NEW_THROWS_EXCEPTIONS)
89 ACE_ASSERT (temp != 0);
90 #endif /* ACE_NEW_THROWS_EXCEPTIONS */
94 template <class ACE_LOCK> inline void
95 ACE_Bound_Ptr_Counter<ACE_LOCK>::attach_weak (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
97 ACE_GUARD (ACE_LOCK, guard, counter->lock_);
99 ++counter->self_ref_count_;
102 template <class ACE_LOCK> inline void
103 ACE_Bound_Ptr_Counter<ACE_LOCK>::detach_weak (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
105 ACE_Bound_Ptr_Counter<ACE_LOCK> *counter_del = 0;
108 ACE_GUARD (ACE_LOCK, guard, counter->lock_);
110 if (--counter->self_ref_count_ == 0)
111 // Since counter contains the lock held by the guard, the
112 // guard needs to be released before freeing the memory holding
113 // the lock. So save the pointer to free, then release, then
115 counter_del = counter;
117 } // Release the lock
122 template <class ACE_LOCK> inline bool
123 ACE_Bound_Ptr_Counter<ACE_LOCK>::object_was_deleted (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter)
125 ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, 0);
127 return counter->obj_ref_count_ == -1;
130 template <class ACE_LOCK> inline
131 ACE_Bound_Ptr_Counter<ACE_LOCK>::ACE_Bound_Ptr_Counter (long init_obj_ref_count)
132 : obj_ref_count_ (init_obj_ref_count),
137 template <class ACE_LOCK> inline
138 ACE_Bound_Ptr_Counter<ACE_LOCK>::~ACE_Bound_Ptr_Counter (void)
142 template <class X, class ACE_LOCK> inline
143 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (X *p)
144 : counter_ (COUNTER::create_strong ()),
149 #if !defined (ACE_HAS_CPP11)
150 template <class X, class ACE_LOCK> inline
151 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (auto_ptr<X> p)
152 : counter_ (COUNTER::create_strong ()),
156 #endif /* !ACE_HAS_CPP11 */
158 template <class X, class ACE_LOCK> inline
159 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r)
160 : counter_ (r.counter_),
163 COUNTER::attach_strong (this->counter_);
166 template <class X, class ACE_LOCK> inline
167 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r)
168 : counter_ (r.counter_),
171 // When creating a strong pointer from a weak one we can't assume that the
172 // underlying object still exists. Therefore we must check for a return value
173 // of -1, which indicates that the object has been destroyed.
174 if (COUNTER::attach_strong (this->counter_) == -1)
176 // Underlying object has already been deleted, so set this pointer to null.
177 this->counter_ = COUNTER::create_strong ();
182 template <class X, class ACE_LOCK> inline
183 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::~ACE_Strong_Bound_Ptr (void)
185 if (COUNTER::detach_strong (this->counter_) == 0)
189 template <class X, class ACE_LOCK> inline void
190 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &rhs)
192 // This will work if &r == this, by first increasing the ref count, but
193 // why go through all that?
197 COUNTER *new_counter = rhs.counter_;
198 X_t *new_ptr = rhs.ptr_;
199 COUNTER::attach_strong (new_counter);
200 if (COUNTER::detach_strong (this->counter_) == 0)
202 this->counter_ = new_counter;
203 this->ptr_ = new_ptr;
206 template <class X, class ACE_LOCK> inline void
207 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &rhs)
209 // This will work if &r == this, by first increasing the ref count, but
210 // why go through all that?
214 COUNTER *new_counter = rhs.counter_;
215 X_t *new_ptr = rhs.ptr_;
217 // When creating a strong pointer from a weak one we can't assume that the
218 // underlying object still exists. Therefore we must check for a return value
219 // of -1, which indicates that the object has been destroyed.
220 if (COUNTER::attach_strong (new_counter) == -1)
222 // Underlying object has already been deleted, so set this pointer to null.
223 new_counter = COUNTER::create_strong ();
227 if (COUNTER::detach_strong (this->counter_) == 0)
229 this->counter_ = new_counter;
230 this->ptr_ = new_ptr;
233 template <class X, class ACE_LOCK> inline bool
234 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
236 return this->ptr_ == r.ptr_;
239 template <class X, class ACE_LOCK> inline bool
240 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
242 // Use the weak pointer's operator== since it will check for null.
246 template <class X, class ACE_LOCK> inline bool
247 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (X *p) const
249 return this->ptr_ == p;
252 template <class X, class ACE_LOCK> inline bool
253 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
255 return this->ptr_ != r.ptr_;
258 template <class X, class ACE_LOCK> inline bool
259 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
261 // Use the weak pointer's operator!= since it will check for null.
265 template <class X, class ACE_LOCK> inline bool
266 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (X *p) const
268 return this->ptr_ != p;
271 template <class X, class ACE_LOCK> inline X *
272 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator-> (void) const
277 template<class X, class ACE_LOCK> inline X &
278 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator *() const
283 template <class X, class ACE_LOCK> inline X*
284 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::get (void) const
289 template <class X, class ACE_LOCK> inline bool
290 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::null (void) const
292 return this->ptr_ == 0;
295 template<class X, class ACE_LOCK> inline void
296 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::reset (X *p)
298 COUNTER *old_counter = this->counter_;
299 X_t *old_ptr = this->ptr_;
300 this->counter_ = COUNTER::create_strong ();
302 if (COUNTER::detach_strong (old_counter) == 0)
306 #if !defined (ACE_HAS_CPP11)
307 template<class X, class ACE_LOCK> inline void
308 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::reset (auto_ptr<X> p)
310 COUNTER *old_counter = this->counter_;
311 X_t *old_ptr = this->ptr_;
312 this->counter_ = COUNTER::create_strong ();
313 this->ptr_ = p.release ();
314 if (COUNTER::detach_strong (old_counter) == 0)
317 #endif /* !ACE_HAS_CPP11 */
319 template <class X, class ACE_LOCK> inline
320 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (X *p)
321 : counter_ (COUNTER::create_weak ()),
326 template <class X, class ACE_LOCK> inline
327 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r)
328 : counter_ (r.counter_),
331 COUNTER::attach_weak (this->counter_);
334 template <class X, class ACE_LOCK> inline
335 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r)
336 : counter_ (r.counter_),
339 COUNTER::attach_weak (this->counter_);
342 template <class X, class ACE_LOCK> inline
343 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::~ACE_Weak_Bound_Ptr (void)
345 COUNTER::detach_weak (this->counter_);
348 template <class X, class ACE_LOCK> inline void
349 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &rhs)
351 // This will work if &rhs == this, by first increasing the ref count
352 COUNTER *new_counter = rhs.counter_;
353 COUNTER::attach_weak (new_counter);
354 COUNTER::detach_weak (this->counter_);
355 this->counter_ = new_counter;
356 this->ptr_ = rhs.ptr_;
359 template <class X, class ACE_LOCK> inline void
360 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &rhs)
362 // This will work if &rhs == this, by first increasing the ref count
363 COUNTER *new_counter = rhs.counter_;
364 COUNTER::attach_weak (new_counter);
365 COUNTER::detach_weak (this->counter_);
366 this->counter_ = new_counter;
367 this->ptr_ = rhs.ptr_;
370 template <class X, class ACE_LOCK> inline bool
371 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
373 // A weak pointer must behave as though it is automatically set to null
374 // if the underlying object has been deleted.
375 if (COUNTER::object_was_deleted (this->counter_))
378 return this->ptr_ == r.ptr_;
381 template <class X, class ACE_LOCK> inline bool
382 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
384 // A weak pointer must behave as though it is automatically set to null
385 // if the underlying object has been deleted.
386 if (COUNTER::object_was_deleted (this->counter_))
389 return this->ptr_ == r.ptr_;
392 template <class X, class ACE_LOCK> inline bool
393 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (X *p) const
395 // A weak pointer must behave as though it is automatically set to null
396 // if the underlying object has been deleted.
397 if (COUNTER::object_was_deleted (this->counter_))
400 return this->ptr_ == p;
403 template <class X, class ACE_LOCK> inline bool
404 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
406 // A weak pointer must behave as though it is automatically set to null
407 // if the underlying object has been deleted.
408 if (COUNTER::object_was_deleted (this->counter_))
411 return this->ptr_ != r.ptr_;
414 template <class X, class ACE_LOCK> inline bool
415 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
417 // A weak pointer must behave as though it is automatically set to null
418 // if the underlying object has been deleted.
419 if (COUNTER::object_was_deleted (this->counter_))
422 return this->ptr_ != r.ptr_;
425 template <class X, class ACE_LOCK> inline bool
426 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (X *p) const
428 // A weak pointer must behave as though it is automatically set to null
429 // if the underlying object has been deleted.
430 if (COUNTER::object_was_deleted (this->counter_))
433 return this->ptr_ != p;
436 template <class X, class ACE_LOCK> inline ACE_Strong_Bound_Ptr<X, ACE_LOCK>
437 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator-> (void) const
439 return ACE_Strong_Bound_Ptr<X, ACE_LOCK> (*this);
442 template <class X, class ACE_LOCK> inline ACE_Strong_Bound_Ptr<X, ACE_LOCK>
443 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::strong (void) const
445 return ACE_Strong_Bound_Ptr<X, ACE_LOCK> (*this);
448 template <class X, class ACE_LOCK> inline X*
449 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::unsafe_get (void) const
451 // We do not check if the object has been deleted, since this operation
452 // is defined to be unsafe!
456 template <class X, class ACE_LOCK> inline bool
457 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::null (void) const
459 // A weak pointer must behave as though it is automatically set to null
460 // if the underlying object has been deleted.
461 if (COUNTER::object_was_deleted (this->counter_))
464 return this->ptr_ == 0;
467 template<class X, class ACE_LOCK> inline void
468 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::reset (X *p)
470 COUNTER *old_counter = this->counter_;
471 this->counter_ = COUNTER::create_weak ();
473 COUNTER::detach_weak (old_counter);
476 template<class X, class ACE_LOCK> inline long
477 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::add_ref ()
479 return COUNTER::attach_strong (counter_);
482 template<class X, class ACE_LOCK> inline long
483 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::remove_ref ()
485 long new_obj_ref_count = COUNTER::detach_strong (counter_);
486 if (new_obj_ref_count == 0)
491 return new_obj_ref_count;
494 ACE_END_VERSIONED_NAMESPACE_DECL