Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Bound_Ptr.i

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

Generated on Mon Jun 16 11:19:13 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002