Bound_Ptr.inl

Go to the documentation of this file.
00001 /* -*- C++ -*- */
00002 // $Id: Bound_Ptr.inl 80826 2008-03-04 14:51:23Z wotte $
00003 
00004 // Bound_Ptr.i
00005 
00006 #include "ace/Guard_T.h"
00007 #if !defined (ACE_NEW_THROWS_EXCEPTIONS)
00008 #  include "ace/Log_Msg.h"
00009 #endif /* ACE_NEW_THROWS_EXCEPTIONS */
00010 
00011 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00012 
00013 template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
00014 ACE_Bound_Ptr_Counter<ACE_LOCK>::internal_create (long init_obj_ref_count)
00015 {
00016   ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = 0;
00017   ACE_NEW_RETURN (temp,
00018                   ACE_Bound_Ptr_Counter<ACE_LOCK> (init_obj_ref_count),
00019                   0);
00020   return temp;
00021 }
00022 
00023 template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
00024 ACE_Bound_Ptr_Counter<ACE_LOCK>::create_strong (void)
00025 {
00026   // Set initial object reference count to 1.
00027   ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = internal_create (1);
00028 #if defined (ACE_NEW_THROWS_EXCEPTIONS)
00029   if (temp == 0)
00030     ACE_throw_bad_alloc;
00031 #else
00032   ACE_ASSERT (temp != 0);
00033 #endif /* ACE_NEW_THROWS_EXCEPTIONS */
00034   return temp;
00035 }
00036 
00037 
00038 
00039 template <class ACE_LOCK> inline long
00040 ACE_Bound_Ptr_Counter<ACE_LOCK>::attach_strong (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
00041 {
00042   ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, -1);
00043 
00044   // Can't attach a strong pointer to an object that has already been deleted.
00045   if (counter->obj_ref_count_ == -1)
00046     return -1;
00047 
00048   long new_obj_ref_count = ++counter->obj_ref_count_;
00049   ++counter->self_ref_count_;
00050 
00051   return new_obj_ref_count;
00052 }
00053 
00054 template <class ACE_LOCK> inline long
00055 ACE_Bound_Ptr_Counter<ACE_LOCK>::detach_strong (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
00056 {
00057   ACE_Bound_Ptr_Counter<ACE_LOCK> *counter_del = 0;
00058   long new_obj_ref_count;
00059 
00060   {
00061     ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, -1);
00062 
00063     if ((new_obj_ref_count = --counter->obj_ref_count_) == 0)
00064       // Change the object reference count to -1 to indicate that the
00065       // object has been deleted, as opposed to a weak pointer that
00066       // simply hasn't had any strong pointers created from it yet.
00067       counter->obj_ref_count_ = -1;
00068 
00069     if (--counter->self_ref_count_ == 0)
00070       // Since counter contains the lock held by the ACE_Guard, the
00071       // guard needs to be released before freeing the memory holding
00072       // the lock. So save the pointer to free, then release, then
00073       // free.
00074       counter_del = counter;
00075 
00076   }  // Release the lock
00077 
00078   delete counter_del;
00079 
00080   return new_obj_ref_count;
00081 }
00082 
00083 template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
00084 ACE_Bound_Ptr_Counter<ACE_LOCK>::create_weak (void)
00085 {
00086   // Set initial object reference count to 0.
00087 
00088   ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = internal_create (0);
00089 #if defined (ACE_NEW_THROWS_EXCEPTIONS)
00090   if (temp == 0)
00091     ACE_throw_bad_alloc;
00092 #else
00093   ACE_ASSERT (temp != 0);
00094 #endif /* ACE_NEW_THROWS_EXCEPTIONS */
00095   return temp;
00096 }
00097 
00098 template <class ACE_LOCK> inline void
00099 ACE_Bound_Ptr_Counter<ACE_LOCK>::attach_weak (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
00100 {
00101   ACE_GUARD (ACE_LOCK, guard, counter->lock_);
00102 
00103   ++counter->self_ref_count_;
00104 }
00105 
00106 template <class ACE_LOCK> inline void
00107 ACE_Bound_Ptr_Counter<ACE_LOCK>::detach_weak (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
00108 {
00109   ACE_Bound_Ptr_Counter<ACE_LOCK> *counter_del = 0;
00110 
00111   {
00112     ACE_GUARD (ACE_LOCK, guard, counter->lock_);
00113 
00114     if (--counter->self_ref_count_ == 0)
00115       // Since counter contains the lock held by the ACE_Guard, the
00116       // guard needs to be released before freeing the memory holding
00117       // the lock. So save the pointer to free, then release, then
00118       // free.
00119       counter_del = counter;
00120 
00121   }  // Release the lock
00122 
00123   delete counter_del;
00124 }
00125 
00126 template <class ACE_LOCK> inline bool
00127 ACE_Bound_Ptr_Counter<ACE_LOCK>::object_was_deleted (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter)
00128 {
00129   ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, 0);
00130 
00131   return counter->obj_ref_count_ == -1;
00132 }
00133 
00134 template <class ACE_LOCK> inline
00135 ACE_Bound_Ptr_Counter<ACE_LOCK>::ACE_Bound_Ptr_Counter (long init_obj_ref_count)
00136   : obj_ref_count_ (init_obj_ref_count),
00137     self_ref_count_ (1)
00138 {
00139 }
00140 
00141 template <class ACE_LOCK> inline
00142 ACE_Bound_Ptr_Counter<ACE_LOCK>::~ACE_Bound_Ptr_Counter (void)
00143 {
00144 }
00145 
00146 template <class X, class ACE_LOCK> inline
00147 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (X *p)
00148   : counter_ (COUNTER::create_strong ()),
00149     ptr_ (p)
00150 {
00151 }
00152 
00153 template <class X, class ACE_LOCK> inline
00154 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (auto_ptr<X> p)
00155   : counter_ (COUNTER::create_strong ()),
00156     ptr_ (p.release())
00157 {
00158 }
00159 
00160 template <class X, class ACE_LOCK> inline
00161 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r)
00162   : counter_ (r.counter_),
00163     ptr_ (r.ptr_)
00164 {
00165   COUNTER::attach_strong (this->counter_);
00166 }
00167 
00168 template <class X, class ACE_LOCK> inline
00169 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r)
00170   : counter_ (r.counter_),
00171     ptr_ (r.ptr_)
00172 {
00173   // When creating a strong pointer from a weak one we can't assume that the
00174   // underlying object still exists. Therefore we must check for a return value
00175   // of -1, which indicates that the object has been destroyed.
00176   if (COUNTER::attach_strong (this->counter_) == -1)
00177     {
00178       // Underlying object has already been deleted, so set this pointer to null.
00179       this->counter_ = COUNTER::create_strong ();
00180       this->ptr_ = 0;
00181     }
00182 }
00183 
00184 template <class X, class ACE_LOCK> inline
00185 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::~ACE_Strong_Bound_Ptr (void)
00186 {
00187   if (COUNTER::detach_strong (this->counter_) == 0)
00188     delete this->ptr_;
00189 }
00190 
00191 template <class X, class ACE_LOCK> inline void
00192 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &rhs)
00193 {
00194   // This will work if &r == this, by first increasing the ref count, but
00195   // why go through all that?
00196   if (&rhs == this)
00197     return;
00198 
00199   COUNTER *new_counter = rhs.counter_;
00200   X_t *new_ptr = rhs.ptr_;
00201   COUNTER::attach_strong (new_counter);
00202   if (COUNTER::detach_strong (this->counter_) == 0)
00203     delete this->ptr_;
00204   this->counter_ = new_counter;
00205   this->ptr_ = new_ptr;
00206 }
00207 
00208 template <class X, class ACE_LOCK> inline void
00209 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &rhs)
00210 {
00211   // This will work if &r == this, by first increasing the ref count, but
00212   // why go through all that?
00213   if (&rhs == this)
00214     return;
00215 
00216   COUNTER *new_counter = rhs.counter_;
00217   X_t *new_ptr = rhs.ptr_;
00218 
00219   // When creating a strong pointer from a weak one we can't assume that the
00220   // underlying object still exists. Therefore we must check for a return value
00221   // of -1, which indicates that the object has been destroyed.
00222   if (COUNTER::attach_strong (new_counter) == -1)
00223     {
00224       // Underlying object has already been deleted, so set this pointer to null.
00225       new_counter = COUNTER::create_strong ();
00226       new_ptr = 0;
00227     }
00228 
00229   if (COUNTER::detach_strong (this->counter_) == 0)
00230     delete this->ptr_;
00231   this->counter_ = new_counter;
00232   this->ptr_ = new_ptr;
00233 }
00234 
00235 template <class X, class ACE_LOCK> inline bool
00236 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
00237 {
00238   return this->ptr_ == r.ptr_;
00239 }
00240 
00241 template <class X, class ACE_LOCK> inline bool
00242 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
00243 {
00244   // Use the weak pointer's operator== since it will check for null.
00245   return r == *this;
00246 }
00247 
00248 template <class X, class ACE_LOCK> inline bool
00249 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (X *p) const
00250 {
00251   return this->ptr_ == p;
00252 }
00253 
00254 template <class X, class ACE_LOCK> inline bool
00255 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
00256 {
00257   return this->ptr_ != r.ptr_;
00258 }
00259 
00260 template <class X, class ACE_LOCK> inline bool
00261 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
00262 {
00263   // Use the weak pointer's operator!= since it will check for null.
00264   return r != *this;
00265 }
00266 
00267 template <class X, class ACE_LOCK> inline bool
00268 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (X *p) const
00269 {
00270   return this->ptr_ != p;
00271 }
00272 
00273 template <class X, class ACE_LOCK> inline X *
00274 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator-> (void) const
00275 {
00276   return this->ptr_;
00277 }
00278 
00279 template<class X, class ACE_LOCK> inline X &
00280 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator *() const
00281 {
00282   return *this->ptr_;
00283 }
00284 
00285 template <class X, class ACE_LOCK> inline X*
00286 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::get (void) const
00287 {
00288   return this->ptr_;
00289 }
00290 
00291 template <class X, class ACE_LOCK> inline int
00292 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::null (void) const
00293 {
00294   return this->ptr_ == 0;
00295 }
00296 
00297 template<class X, class ACE_LOCK> inline void
00298 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::reset (X *p)
00299 {
00300   COUNTER *old_counter = this->counter_;
00301   X_t *old_ptr = this->ptr_;
00302   this->counter_ = COUNTER::create_strong ();
00303   this->ptr_ = p;
00304   if (COUNTER::detach_strong (old_counter) == 0)
00305     delete old_ptr;
00306 }
00307 
00308 template<class X, class ACE_LOCK> inline void
00309 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::reset (auto_ptr<X> p)
00310 {
00311   COUNTER *old_counter = this->counter_;
00312   X_t *old_ptr = this->ptr_;
00313   this->counter_ = COUNTER::create_strong ();
00314   this->ptr_ = p.release ();
00315   if (COUNTER::detach_strong (old_counter) == 0)
00316     delete old_ptr;
00317 }
00318 
00319 template <class X, class ACE_LOCK> inline
00320 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (X *p)
00321   : counter_ (COUNTER::create_weak ()),
00322     ptr_ (p)
00323 {
00324 }
00325 
00326 template <class X, class ACE_LOCK> inline
00327 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r)
00328   : counter_ (r.counter_),
00329     ptr_ (r.ptr_)
00330 {
00331   COUNTER::attach_weak (this->counter_);
00332 }
00333 
00334 template <class X, class ACE_LOCK> inline
00335 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r)
00336   : counter_ (r.counter_),
00337     ptr_ (r.ptr_)
00338 {
00339   COUNTER::attach_weak (this->counter_);
00340 }
00341 
00342 template <class X, class ACE_LOCK> inline
00343 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::~ACE_Weak_Bound_Ptr (void)
00344 {
00345   COUNTER::detach_weak (this->counter_);
00346 }
00347 
00348 template <class X, class ACE_LOCK> inline void
00349 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &rhs)
00350 {
00351   // This will work if &rhs == this, by first increasing the ref count
00352   COUNTER *new_counter = rhs.counter_;
00353   COUNTER::attach_weak (new_counter);
00354   COUNTER::detach_weak (this->counter_);
00355   this->counter_ = new_counter;
00356   this->ptr_ = rhs.ptr_;
00357 }
00358 
00359 template <class X, class ACE_LOCK> inline void
00360 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &rhs)
00361 {
00362   // This will work if &rhs == this, by first increasing the ref count
00363   COUNTER *new_counter = rhs.counter_;
00364   COUNTER::attach_weak (new_counter);
00365   COUNTER::detach_weak (this->counter_);
00366   this->counter_ = new_counter;
00367   this->ptr_ = rhs.ptr_;
00368 }
00369 
00370 template <class X, class ACE_LOCK> inline bool
00371 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
00372 {
00373   // A weak pointer must behave as though it is automatically set to null
00374   // if the underlying object has been deleted.
00375   if (COUNTER::object_was_deleted (this->counter_))
00376     return r.ptr_ == 0;
00377 
00378   return this->ptr_ == r.ptr_;
00379 }
00380 
00381 template <class X, class ACE_LOCK> inline bool
00382 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
00383 {
00384   // A weak pointer must behave as though it is automatically set to null
00385   // if the underlying object has been deleted.
00386   if (COUNTER::object_was_deleted (this->counter_))
00387     return r.ptr_ == 0;
00388 
00389   return this->ptr_ == r.ptr_;
00390 }
00391 
00392 template <class X, class ACE_LOCK> inline bool
00393 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (X *p) const
00394 {
00395   // A weak pointer must behave as though it is automatically set to null
00396   // if the underlying object has been deleted.
00397   if (COUNTER::object_was_deleted (this->counter_))
00398     return p == 0;
00399 
00400   return this->ptr_ == p;
00401 }
00402 
00403 template <class X, class ACE_LOCK> inline bool
00404 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
00405 {
00406   // A weak pointer must behave as though it is automatically set to null
00407   // if the underlying object has been deleted.
00408   if (COUNTER::object_was_deleted (this->counter_))
00409     return r.ptr_ != 0;
00410 
00411   return this->ptr_ != r.ptr_;
00412 }
00413 
00414 template <class X, class ACE_LOCK> inline bool
00415 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
00416 {
00417   // A weak pointer must behave as though it is automatically set to null
00418   // if the underlying object has been deleted.
00419   if (COUNTER::object_was_deleted (this->counter_))
00420     return r.ptr_ != 0;
00421 
00422   return this->ptr_ != r.ptr_;
00423 }
00424 
00425 template <class X, class ACE_LOCK> inline bool
00426 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (X *p) const
00427 {
00428   // A weak pointer must behave as though it is automatically set to null
00429   // if the underlying object has been deleted.
00430   if (COUNTER::object_was_deleted (this->counter_))
00431     return p != 0;
00432 
00433   return this->ptr_ != p;
00434 }
00435 
00436 template <class X, class ACE_LOCK> inline ACE_Strong_Bound_Ptr<X, ACE_LOCK>
00437 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator-> (void) const
00438 {
00439   return ACE_Strong_Bound_Ptr<X, ACE_LOCK> (*this);
00440 }
00441 
00442 template <class X, class ACE_LOCK> inline ACE_Strong_Bound_Ptr<X, ACE_LOCK>
00443 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::strong (void) const
00444 {
00445   return ACE_Strong_Bound_Ptr<X, ACE_LOCK> (*this);
00446 }
00447 
00448 template <class X, class ACE_LOCK> inline X*
00449 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::unsafe_get (void) const
00450 {
00451   // We do not check if the object has been deleted, since this operation
00452   // is defined to be unsafe!
00453   return this->ptr_;
00454 }
00455 
00456 template <class X, class ACE_LOCK> inline int
00457 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::null (void) const
00458 {
00459   // A weak pointer must behave as though it is automatically set to null
00460   // if the underlying object has been deleted.
00461   if (COUNTER::object_was_deleted (this->counter_))
00462     return 1;
00463 
00464   return this->ptr_ == 0;
00465 }
00466 
00467 template<class X, class ACE_LOCK> inline void
00468 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::reset (X *p)
00469 {
00470   COUNTER *old_counter = this->counter_;
00471   this->counter_ = COUNTER::create_weak ();
00472   this->ptr_ = p;
00473   COUNTER::detach_weak (old_counter);
00474 }
00475 
00476 template<class X, class ACE_LOCK> inline long
00477 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::add_ref ()
00478 {
00479   return COUNTER::attach_strong (counter_);
00480 }
00481 
00482 template<class X, class ACE_LOCK> inline long
00483 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::remove_ref ()
00484 {
00485   long new_obj_ref_count = COUNTER::detach_strong (counter_);
00486   if (new_obj_ref_count == 0)
00487     {
00488       delete this->ptr_;
00489       this->ptr_ = 0;
00490     }
00491   return new_obj_ref_count;
00492 }
00493 
00494 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:18:38 2010 for ACE by  doxygen 1.4.7