2 #include "ace/Guard_T.h"
4 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
6 template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
7 ACE_Bound_Ptr_Counter<ACE_LOCK>::internal_create (long init_obj_ref_count)
9 ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = 0;
11 ACE_Bound_Ptr_Counter<ACE_LOCK> (init_obj_ref_count),
16 template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
17 ACE_Bound_Ptr_Counter<ACE_LOCK>::create_strong ()
19 // Set initial object reference count to 1.
20 ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = internal_create (1);
22 throw std::bad_alloc ();
26 template <class ACE_LOCK> inline long
27 ACE_Bound_Ptr_Counter<ACE_LOCK>::attach_strong (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
29 ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, -1);
31 // Can't attach a strong pointer to an object that has already been deleted.
32 if (counter->obj_ref_count_ == -1)
35 long const new_obj_ref_count = ++counter->obj_ref_count_;
36 ++counter->self_ref_count_;
38 return new_obj_ref_count;
41 template <class ACE_LOCK> inline long
42 ACE_Bound_Ptr_Counter<ACE_LOCK>::detach_strong (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
44 ACE_Bound_Ptr_Counter<ACE_LOCK> *counter_del = 0;
45 long new_obj_ref_count;
48 ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, -1);
50 if ((new_obj_ref_count = --counter->obj_ref_count_) == 0)
51 // Change the object reference count to -1 to indicate that the
52 // object has been deleted, as opposed to a weak pointer that
53 // simply hasn't had any strong pointers created from it yet.
54 counter->obj_ref_count_ = -1;
56 if (--counter->self_ref_count_ == 0)
57 // Since counter contains the lock held by the guard, the
58 // guard needs to be released before freeing the memory holding
59 // the lock. So save the pointer to free, then release, then
61 counter_del = counter;
67 return new_obj_ref_count;
70 template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
71 ACE_Bound_Ptr_Counter<ACE_LOCK>::create_weak ()
73 // Set initial object reference count to 0.
75 ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = internal_create (0);
77 throw std::bad_alloc ();
81 template <class ACE_LOCK> inline void
82 ACE_Bound_Ptr_Counter<ACE_LOCK>::attach_weak (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
84 ACE_GUARD (ACE_LOCK, guard, counter->lock_);
86 ++counter->self_ref_count_;
89 template <class ACE_LOCK> inline void
90 ACE_Bound_Ptr_Counter<ACE_LOCK>::detach_weak (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
92 ACE_Bound_Ptr_Counter<ACE_LOCK> *counter_del = 0;
95 ACE_GUARD (ACE_LOCK, guard, counter->lock_);
97 if (--counter->self_ref_count_ == 0)
98 // Since counter contains the lock held by the guard, the
99 // guard needs to be released before freeing the memory holding
100 // the lock. So save the pointer to free, then release, then
102 counter_del = counter;
104 } // Release the lock
109 template <class ACE_LOCK> inline bool
110 ACE_Bound_Ptr_Counter<ACE_LOCK>::object_was_deleted (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter)
112 ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, 0);
114 return counter->obj_ref_count_ == -1;
117 template <class ACE_LOCK> inline
118 ACE_Bound_Ptr_Counter<ACE_LOCK>::ACE_Bound_Ptr_Counter (long init_obj_ref_count)
119 : obj_ref_count_ (init_obj_ref_count),
124 template <class X, class ACE_LOCK> inline
125 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (X *p)
126 : counter_ (COUNTER::create_strong ()),
131 template <class X, class ACE_LOCK> inline
132 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r)
133 : counter_ (r.counter_),
136 COUNTER::attach_strong (this->counter_);
139 template <class X, class ACE_LOCK> inline
140 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r)
141 : counter_ (r.counter_),
144 // When creating a strong pointer from a weak one we can't assume that the
145 // underlying object still exists. Therefore we must check for a return value
146 // of -1, which indicates that the object has been destroyed.
147 if (COUNTER::attach_strong (this->counter_) == -1)
149 // Underlying object has already been deleted, so set this pointer to null.
150 this->counter_ = COUNTER::create_strong ();
155 template <class X, class ACE_LOCK> inline
156 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::~ACE_Strong_Bound_Ptr ()
158 if (COUNTER::detach_strong (this->counter_) == 0)
162 template <class X, class ACE_LOCK> inline void
163 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &rhs)
165 // This will work if &r == this, by first increasing the ref count, but
166 // why go through all that?
170 COUNTER *new_counter = rhs.counter_;
171 X *new_ptr = rhs.ptr_;
172 COUNTER::attach_strong (new_counter);
173 if (COUNTER::detach_strong (this->counter_) == 0)
175 this->counter_ = new_counter;
176 this->ptr_ = new_ptr;
179 template <class X, class ACE_LOCK> inline void
180 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &rhs)
182 // This will work if &r == this, by first increasing the ref count, but
183 // why go through all that?
187 COUNTER *new_counter = rhs.counter_;
188 X *new_ptr = rhs.ptr_;
190 // When creating a strong pointer from a weak one we can't assume that the
191 // underlying object still exists. Therefore we must check for a return value
192 // of -1, which indicates that the object has been destroyed.
193 if (COUNTER::attach_strong (new_counter) == -1)
195 // Underlying object has already been deleted, so set this pointer to null.
196 new_counter = COUNTER::create_strong ();
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 bool
207 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
209 return this->ptr_ == r.ptr_;
212 template <class X, class ACE_LOCK> inline bool
213 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
215 // Use the weak pointer's operator== since it will check for null.
219 template <class X, class ACE_LOCK> inline bool
220 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (X *p) const
222 return this->ptr_ == p;
225 template <class X, class ACE_LOCK> inline bool
226 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
228 return this->ptr_ != r.ptr_;
231 template <class X, class ACE_LOCK> inline bool
232 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
234 // Use the weak pointer's operator!= since it will check for null.
238 template <class X, class ACE_LOCK> inline bool
239 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (X *p) const
241 return this->ptr_ != p;
244 template <class X, class ACE_LOCK> inline X *
245 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator-> () const
250 template<class X, class ACE_LOCK> inline X &
251 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator *() const
256 template <class X, class ACE_LOCK> inline X*
257 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::get () const
262 template <class X, class ACE_LOCK> inline bool
263 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::null () const
265 return this->ptr_ == 0;
268 template<class X, class ACE_LOCK> inline void
269 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::reset (X *p)
271 COUNTER *old_counter = this->counter_;
272 X *old_ptr = this->ptr_;
273 this->counter_ = COUNTER::create_strong ();
275 if (COUNTER::detach_strong (old_counter) == 0)
279 template <class X, class ACE_LOCK> inline
280 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (X *p)
281 : counter_ (COUNTER::create_weak ()),
286 template <class X, class ACE_LOCK> inline
287 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r)
288 : counter_ (r.counter_),
291 COUNTER::attach_weak (this->counter_);
294 template <class X, class ACE_LOCK> inline
295 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r)
296 : counter_ (r.counter_),
299 COUNTER::attach_weak (this->counter_);
302 template <class X, class ACE_LOCK> inline
303 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::~ACE_Weak_Bound_Ptr ()
305 COUNTER::detach_weak (this->counter_);
308 template <class X, class ACE_LOCK> inline void
309 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &rhs)
311 // This will work if &rhs == this, by first increasing the ref count
312 COUNTER *new_counter = rhs.counter_;
313 COUNTER::attach_weak (new_counter);
314 COUNTER::detach_weak (this->counter_);
315 this->counter_ = new_counter;
316 this->ptr_ = rhs.ptr_;
319 template <class X, class ACE_LOCK> inline void
320 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &rhs)
322 // This will work if &rhs == this, by first increasing the ref count
323 COUNTER *new_counter = rhs.counter_;
324 COUNTER::attach_weak (new_counter);
325 COUNTER::detach_weak (this->counter_);
326 this->counter_ = new_counter;
327 this->ptr_ = rhs.ptr_;
330 template <class X, class ACE_LOCK> inline bool
331 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
333 // A weak pointer must behave as though it is automatically set to null
334 // if the underlying object has been deleted.
335 if (COUNTER::object_was_deleted (this->counter_))
338 return this->ptr_ == r.ptr_;
341 template <class X, class ACE_LOCK> inline bool
342 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
344 // A weak pointer must behave as though it is automatically set to null
345 // if the underlying object has been deleted.
346 if (COUNTER::object_was_deleted (this->counter_))
349 return this->ptr_ == r.ptr_;
352 template <class X, class ACE_LOCK> inline bool
353 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (X *p) const
355 // A weak pointer must behave as though it is automatically set to null
356 // if the underlying object has been deleted.
357 if (COUNTER::object_was_deleted (this->counter_))
360 return this->ptr_ == p;
363 template <class X, class ACE_LOCK> inline bool
364 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
366 // A weak pointer must behave as though it is automatically set to null
367 // if the underlying object has been deleted.
368 if (COUNTER::object_was_deleted (this->counter_))
371 return this->ptr_ != r.ptr_;
374 template <class X, class ACE_LOCK> inline bool
375 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
377 // A weak pointer must behave as though it is automatically set to null
378 // if the underlying object has been deleted.
379 if (COUNTER::object_was_deleted (this->counter_))
382 return this->ptr_ != r.ptr_;
385 template <class X, class ACE_LOCK> inline bool
386 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (X *p) const
388 // A weak pointer must behave as though it is automatically set to null
389 // if the underlying object has been deleted.
390 if (COUNTER::object_was_deleted (this->counter_))
393 return this->ptr_ != p;
396 template <class X, class ACE_LOCK> inline ACE_Strong_Bound_Ptr<X, ACE_LOCK>
397 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator-> () const
399 return ACE_Strong_Bound_Ptr<X, ACE_LOCK> (*this);
402 template <class X, class ACE_LOCK> inline ACE_Strong_Bound_Ptr<X, ACE_LOCK>
403 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::strong () const
405 return ACE_Strong_Bound_Ptr<X, ACE_LOCK> (*this);
408 template <class X, class ACE_LOCK> inline X*
409 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::unsafe_get () const
411 // We do not check if the object has been deleted, since this operation
412 // is defined to be unsafe!
416 template <class X, class ACE_LOCK> inline bool
417 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::null () const
419 // A weak pointer must behave as though it is automatically set to null
420 // if the underlying object has been deleted.
421 if (COUNTER::object_was_deleted (this->counter_))
424 return this->ptr_ == 0;
427 template<class X, class ACE_LOCK> inline void
428 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::reset (X *p)
430 COUNTER *old_counter = this->counter_;
431 this->counter_ = COUNTER::create_weak ();
433 COUNTER::detach_weak (old_counter);
436 template<class X, class ACE_LOCK> inline long
437 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::add_ref ()
439 return COUNTER::attach_strong (counter_);
442 template<class X, class ACE_LOCK> inline long
443 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::remove_ref ()
445 long new_obj_ref_count = COUNTER::detach_strong (counter_);
446 if (new_obj_ref_count == 0)
451 return new_obj_ref_count;
454 ACE_END_VERSIONED_NAMESPACE_DECL