Bound_Ptr.inl

Go to the documentation of this file.
00001 /* -*- C++ -*- */
00002 // Bound_Ptr.inl,v 4.2 2005/10/28 16:14:51 ossama Exp
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 (int 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 int
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   int 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 int
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   int 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 int
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 (int 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
00195 
00196   COUNTER *new_counter = rhs.counter_;
00197   X* new_ptr = rhs.ptr_;
00198   COUNTER::attach_strong (new_counter);
00199   if (COUNTER::detach_strong (this->counter_) == 0)
00200     delete this->ptr_;
00201   this->counter_ = new_counter;
00202   this->ptr_ = new_ptr;
00203 }
00204 
00205 template <class X, class ACE_LOCK> inline void
00206 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &rhs)
00207 {
00208   // This will work if &r == this, by first increasing the ref count
00209 
00210   COUNTER *new_counter = rhs.counter_;
00211   X* new_ptr = rhs.ptr_;
00212 
00213   // When creating a strong pointer from a weak one we can't assume that the
00214   // underlying object still exists. Therefore we must check for a return value
00215   // of -1, which indicates that the object has been destroyed.
00216   if (COUNTER::attach_strong (new_counter) == -1)
00217     {
00218       // Underlying object has already been deleted, so set this pointer to null.
00219       new_counter = COUNTER::create_strong ();
00220       new_ptr = 0;
00221     }
00222 
00223   if (COUNTER::detach_strong (this->counter_) == 0)
00224     delete this->ptr_;
00225   this->counter_ = new_counter;
00226   this->ptr_ = new_ptr;
00227 }
00228 
00229 template <class X, class ACE_LOCK> inline bool
00230 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
00231 {
00232   return this->ptr_ == r.ptr_;
00233 }
00234 
00235 template <class X, class ACE_LOCK> inline bool
00236 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
00237 {
00238   // Use the weak pointer's operator== since it will check for null.
00239   return r == *this;
00240 }
00241 
00242 template <class X, class ACE_LOCK> inline bool
00243 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (X *p) const
00244 {
00245   return this->ptr_ == p;
00246 }
00247 
00248 template <class X, class ACE_LOCK> inline bool
00249 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
00250 {
00251   return this->ptr_ != r.ptr_;
00252 }
00253 
00254 template <class X, class ACE_LOCK> inline bool
00255 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
00256 {
00257   // Use the weak pointer's operator!= since it will check for null.
00258   return r != *this;
00259 }
00260 
00261 template <class X, class ACE_LOCK> inline bool
00262 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (X *p) const
00263 {
00264   return this->ptr_ != p;
00265 }
00266 
00267 template <class X, class ACE_LOCK> inline X *
00268 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator-> (void) const
00269 {
00270   return this->ptr_;
00271 }
00272 
00273 template<class X, class ACE_LOCK> inline X &
00274 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator *() 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>::get (void) const
00281 {
00282   return this->ptr_;
00283 }
00284 
00285 template <class X, class ACE_LOCK> inline int
00286 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::null (void) const
00287 {
00288   return this->ptr_ == 0;
00289 }
00290 
00291 template<class X, class ACE_LOCK> inline void
00292 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::reset (X *p)
00293 {
00294   COUNTER *old_counter = this->counter_;
00295   X* old_ptr = this->ptr_;
00296   this->counter_ = COUNTER::create_strong ();
00297   this->ptr_ = p;
00298   if (COUNTER::detach_strong (old_counter) == 0)
00299     delete old_ptr;
00300 }
00301 
00302 template<class X, class ACE_LOCK> inline void
00303 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::reset (auto_ptr<X> p)
00304 {
00305   COUNTER *old_counter = this->counter_;
00306   X* old_ptr = this->ptr_;
00307   this->counter_ = COUNTER::create_strong ();
00308   this->ptr_ = p.release ();
00309   if (COUNTER::detach_strong (old_counter) == 0)
00310     delete old_ptr;
00311 }
00312 
00313 template <class X, class ACE_LOCK> inline
00314 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (X *p)
00315   : counter_ (COUNTER::create_weak ()),
00316     ptr_ (p)
00317 {
00318 }
00319 
00320 template <class X, class ACE_LOCK> inline
00321 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r)
00322   : counter_ (r.counter_),
00323     ptr_ (r.ptr_)
00324 {
00325   COUNTER::attach_weak (this->counter_);
00326 }
00327 
00328 template <class X, class ACE_LOCK> inline
00329 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r)
00330   : counter_ (r.counter_),
00331     ptr_ (r.ptr_)
00332 {
00333   COUNTER::attach_weak (this->counter_);
00334 }
00335 
00336 template <class X, class ACE_LOCK> inline
00337 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::~ACE_Weak_Bound_Ptr (void)
00338 {
00339   COUNTER::detach_weak (this->counter_);
00340 }
00341 
00342 template <class X, class ACE_LOCK> inline void
00343 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &rhs)
00344 {
00345   // This will work if &rhs == this, by first increasing the ref count
00346   COUNTER *new_counter = rhs.counter_;
00347   COUNTER::attach_weak (new_counter);
00348   COUNTER::detach_weak (this->counter_);
00349   this->counter_ = new_counter;
00350   this->ptr_ = rhs.ptr_;
00351 }
00352 
00353 template <class X, class ACE_LOCK> inline void
00354 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &rhs)
00355 {
00356   // This will work if &rhs == this, by first increasing the ref count
00357   COUNTER *new_counter = rhs.counter_;
00358   COUNTER::attach_weak (new_counter);
00359   COUNTER::detach_weak (this->counter_);
00360   this->counter_ = new_counter;
00361   this->ptr_ = rhs.ptr_;
00362 }
00363 
00364 template <class X, class ACE_LOCK> inline bool
00365 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
00366 {
00367   // A weak pointer must behave as though it is automatically set to null
00368   // if the underlying object has been deleted.
00369   if (COUNTER::object_was_deleted (this->counter_))
00370     return r.ptr_ == 0;
00371 
00372   return this->ptr_ == r.ptr_;
00373 }
00374 
00375 template <class X, class ACE_LOCK> inline bool
00376 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
00377 {
00378   // A weak pointer must behave as though it is automatically set to null
00379   // if the underlying object has been deleted.
00380   if (COUNTER::object_was_deleted (this->counter_))
00381     return r.ptr_ == 0;
00382 
00383   return this->ptr_ == r.ptr_;
00384 }
00385 
00386 template <class X, class ACE_LOCK> inline bool
00387 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (X *p) const
00388 {
00389   // A weak pointer must behave as though it is automatically set to null
00390   // if the underlying object has been deleted.
00391   if (COUNTER::object_was_deleted (this->counter_))
00392     return p == 0;
00393 
00394   return this->ptr_ == p;
00395 }
00396 
00397 template <class X, class ACE_LOCK> inline bool
00398 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
00399 {
00400   // A weak pointer must behave as though it is automatically set to null
00401   // if the underlying object has been deleted.
00402   if (COUNTER::object_was_deleted (this->counter_))
00403     return r.ptr_ != 0;
00404 
00405   return this->ptr_ != r.ptr_;
00406 }
00407 
00408 template <class X, class ACE_LOCK> inline bool
00409 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
00410 {
00411   // A weak pointer must behave as though it is automatically set to null
00412   // if the underlying object has been deleted.
00413   if (COUNTER::object_was_deleted (this->counter_))
00414     return r.ptr_ != 0;
00415 
00416   return this->ptr_ != r.ptr_;
00417 }
00418 
00419 template <class X, class ACE_LOCK> inline bool
00420 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (X *p) const
00421 {
00422   // A weak pointer must behave as though it is automatically set to null
00423   // if the underlying object has been deleted.
00424   if (COUNTER::object_was_deleted (this->counter_))
00425     return p != 0;
00426 
00427   return this->ptr_ != p;
00428 }
00429 
00430 template <class X, class ACE_LOCK> inline ACE_Strong_Bound_Ptr<X, ACE_LOCK>
00431 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator-> (void) const
00432 {
00433   return ACE_Strong_Bound_Ptr<X, ACE_LOCK> (*this);
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>::strong (void) const
00438 {
00439   return ACE_Strong_Bound_Ptr<X, ACE_LOCK> (*this);
00440 }
00441 
00442 template <class X, class ACE_LOCK> inline X*
00443 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::unsafe_get (void) const
00444 {
00445   // We do not check if the object has been deleted, since this operation
00446   // is defined to be unsafe!
00447   return this->ptr_;
00448 }
00449 
00450 template <class X, class ACE_LOCK> inline int
00451 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::null (void) const
00452 {
00453   // A weak pointer must behave as though it is automatically set to null
00454   // if the underlying object has been deleted.
00455   if (COUNTER::object_was_deleted (this->counter_))
00456     return 1;
00457 
00458   return this->ptr_ == 0;
00459 }
00460 
00461 template<class X, class ACE_LOCK> inline void
00462 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::reset (X *p)
00463 {
00464   COUNTER *old_counter = this->counter_;
00465   this->counter_ = COUNTER::create_weak ();
00466   this->ptr_ = p;
00467   COUNTER::detach_weak (old_counter);
00468 }
00469 
00470 template<class X, class ACE_LOCK> inline int
00471 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::add_ref ()
00472 {
00473   return COUNTER::attach_strong (counter_);
00474 }
00475 
00476 template<class X, class ACE_LOCK> inline int
00477 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::remove_ref ()
00478 {
00479   int new_obj_ref_count = COUNTER::detach_strong (counter_);
00480   if (new_obj_ref_count == 0)
00481     {
00482       delete this->ptr_;
00483       this->ptr_ = 0;
00484     }
00485   return new_obj_ref_count;
00486 }
00487 
00488 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 09:41:47 2006 for ACE by doxygen 1.3.6