diff options
author | Steve Huston <shuston@riverace.com> | 2006-07-12 20:59:39 +0000 |
---|---|---|
committer | Steve Huston <shuston@riverace.com> | 2006-07-12 20:59:39 +0000 |
commit | 095a62e4f97f3611ef21d94ff547966f8560fca1 (patch) | |
tree | ee89402f3e81bf241d49ea6bc979d5e7727ec5e1 /ace | |
parent | d038c9097e7e2120b0f695040385ef2759c772e9 (diff) | |
download | ATCD-095a62e4f97f3611ef21d94ff547966f8560fca1.tar.gz |
ChangeLogTag:Thu Jul 6 20:45:15 UTC 2006 Steve Huston <shuston@riverace.com>
Diffstat (limited to 'ace')
-rw-r--r-- | ace/Refcounted_Auto_Ptr.h | 76 | ||||
-rw-r--r-- | ace/Refcounted_Auto_Ptr.inl | 101 |
2 files changed, 70 insertions, 107 deletions
diff --git a/ace/Refcounted_Auto_Ptr.h b/ace/Refcounted_Auto_Ptr.h index d480c125c68..b9c71318a0d 100644 --- a/ace/Refcounted_Auto_Ptr.h +++ b/ace/Refcounted_Auto_Ptr.h @@ -36,6 +36,11 @@ template <class X, class ACE_LOCK> class ACE_Refcounted_Auto_Ptr; * instance that references a ACE_Refcounted_Auto_Ptr instance is * destroyed or overwritten, it will invoke delete on its underlying * pointer. + * + * The ACE_Refcounted_Auto_Ptr works by maintaining a reference to a + * separate representation object, ACE_Refcounted_Auto_Ptr_Rep. That + * separate representation object contains the reference count and + * the actual pointer value. */ template <class X, class ACE_LOCK> class ACE_Refcounted_Auto_Ptr @@ -44,26 +49,28 @@ public: // = Initialization and termination methods. - /// Constructor that initializes an @c ACE_Refcounted_Auto_Ptr to - /// point to the result immediately. + /// Constructor that initializes an ACE_Refcounted_Auto_Ptr to + /// the specified pointer value. ACE_Refcounted_Auto_Ptr (X *p = 0); - /// Copy constructor binds the created object and @c r to the same - /// @c ACE_Refcounted_Auto_Ptr_Rep. An @c ACE_Refcounted_Auto_Ptr_Rep - /// is created if necessary. + /// Copy constructor binds the new ACE_Refcounted_Auto_Ptr to the + /// representation object referenced by @a r. + /// An ACE_Refcounted_Auto_Ptr_Rep is created if necessary. ACE_Refcounted_Auto_Ptr (const ACE_Refcounted_Auto_Ptr<X, ACE_LOCK> &r); - /// Destructor. + /// Destructor. Releases the reference to the underlying representation. + /// If the release of that reference causes its reference count to reach 0, + /// the representation object will also be destroyed. virtual ~ACE_Refcounted_Auto_Ptr (void); - /// Assignment operator that binds the current object and @c r to the same - /// @c ACE_Refcounted_Auto_Ptr_Rep. An @c ACE_Refcounted_Auto_Ptr_Rep + /// Assignment operator that binds the current object and @a r to the same + /// ACE_Refcounted_Auto_Ptr_Rep. An ACE_Refcounted_Auto_Ptr_Rep /// is created if necessary. void operator = (const ACE_Refcounted_Auto_Ptr<X, ACE_LOCK> &r); /// Equality operator that returns @c true if both - /// ACE_Refcounted_Auto_Ptr@<X, ACE_LOCK@> objects point to the same - /// ACE_Refcounted_Auto_Ptr_Rep@<X, ACE_LOCK@> object + /// ACE_Refcounted_Auto_Ptr objects point to the same underlying + /// representation. It does not compare the actual pointers. /** * @note It also returns @c true if both objects have just been * instantiated and not used yet. @@ -76,15 +83,15 @@ public: /// Redirection operator X *operator-> (void) const; - // = Accessor methods. - + /// Accessor method. X &operator *() const; - /// Sets the pointer value to 0 and returns its old value. + /// Releases the reference to the underlying representation object. + /// @retval The pointer value prior to releasing it. X *release (void); - /// Invokes delete on the previous pointer value and then sets the - /// pointer value to the specified value. + /// Releases the current pointer value and then sets a new + /// pointer value specified by @a p. void reset (X *p = 0); /// Get the pointer value. @@ -93,9 +100,7 @@ public: /// Get the reference count value. int count (void) const; - // = Utility method. - - /// Allows us to check for NULL on all ACE_Refcounted_Auto_Ptr objects. + /// Returns @c true if this object does not contain a valid pointer. int null (void) const; /// Declare the dynamic allocation hooks. @@ -112,10 +117,12 @@ protected: /** * @class ACE_Refcounted_Auto_Ptr_Rep * - * @brief An ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> object - * encapsulates a pointer to an object of type X. It is pointed to by - * ACE_Refcounted_Auto_Ptr<X, ACE_LOCK> object[s] and only accessible - * through them. + * @brief An ACE_Refcounted_Auto_Ptr_Rep object encapsulates a pointer + * to an object of type X. It uses a lock object of type ACE_LOCK to protect + * access to the reference count. + * + * @internal ACE_Refcounted_Auto_Ptr_Rep is used internally by the + * ACE_Refcounted_Auto_Ptr class and is only accessible through it. */ template <class X, class ACE_LOCK> class ACE_Refcounted_Auto_Ptr_Rep @@ -123,13 +130,6 @@ class ACE_Refcounted_Auto_Ptr_Rep private: friend class ACE_Refcounted_Auto_Ptr<X, ACE_LOCK>; - /// Sets the pointer value to 0 and returns its old value. - X *release (void); - - /// Invokes delete on the previous pointer value and then - /// sets the pointer value to the specified value. - void reset (X *p = 0); - /// Get the pointer value. X *get (void) const; @@ -151,10 +151,10 @@ private: /// the reference count. static ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *create (X *p); - /// Increase the reference count and return argument. Uses the - /// attribute "ace_lock_" to synchronize reference count updating. + /// Increase the reference count on @a rep. /// - /// Precondition (rep != 0). + /// @retval @a rep if success, 0 if there's an error obtaining the lock + /// on @a rep. static ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *attach (ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *&rep); /// Decreases the reference count and and deletes rep if there are no @@ -163,13 +163,6 @@ private: /// Precondition (rep != 0) static void detach (ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *&rep); - /// Decreases the rep's reference count and and deletes rep if there - /// are no more references to rep. Then assigns new_rep to rep. - /// - /// Precondition (rep != 0 && new_rep != 0) - static void assign (ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *&rep, - ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *new_rep); - /// Pointer to the result. ACE_Auto_Basic_Ptr<X> ptr_; @@ -178,13 +171,10 @@ private: // = Mutex variable to protect the <ptr_>. - /// Synchronization variable for the MT_SAFE <ACE_Hash_Map_Manager_Ex>. + /// Synchronization variable for serializing access to ref_count_ mutable ACE_LOCK lock_; private: - /// Allows us to check for NULL on all ACE_Refcounted_Auto_Ptr objects. - int null (void) const; - // = Constructor and destructor private. ACE_Refcounted_Auto_Ptr_Rep (X *p = 0); ~ACE_Refcounted_Auto_Ptr_Rep (void); diff --git a/ace/Refcounted_Auto_Ptr.inl b/ace/Refcounted_Auto_Ptr.inl index 3635393ecfa..44e5fd09cc4 100644 --- a/ace/Refcounted_Auto_Ptr.inl +++ b/ace/Refcounted_Auto_Ptr.inl @@ -10,7 +10,7 @@ ACE_BEGIN_VERSIONED_NAMESPACE_DECL template <class X, class ACE_LOCK> inline int ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK>::count (void) const { - ACE_GUARD_RETURN (ACE_LOCK, guard, this->lock_, 0); + ACE_READ_GUARD_RETURN (ACE_LOCK, guard, this->lock_, 0); return this->ref_count_; } @@ -21,17 +21,9 @@ ACE_Refcounted_Auto_Ptr<X, ACE_LOCK>::count (void) const } template <class X, class ACE_LOCK> inline int -ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK>::null (void) const -{ - ACE_GUARD_RETURN (ACE_LOCK, guard, this->lock_, 0); - - return this->ptr_.get () == 0; -} - -template <class X, class ACE_LOCK> inline int ACE_Refcounted_Auto_Ptr<X, ACE_LOCK>::null (void) const { - return this->rep_->null (); + return (this->rep_ == 0 || this->rep_->get () == 0); } template <class X, class ACE_LOCK> inline ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> * @@ -61,9 +53,10 @@ ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK>::create (X *p) template <class X, class ACE_LOCK> inline ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> * ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK>::attach (ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK>*& rep) { - ACE_ASSERT (rep != 0); + if (rep == 0) + return 0; - ACE_GUARD_RETURN (ACE_LOCK, guard, rep->lock_, rep); + ACE_WRITE_GUARD_RETURN (ACE_LOCK, guard, rep->lock_, 0); ++rep->ref_count_; @@ -73,11 +66,12 @@ ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK>::attach (ACE_Refcounted_Auto_Ptr_Rep<X, template <class X, class ACE_LOCK> inline void ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK>::detach (ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK>*& rep) { - ACE_ASSERT (rep != 0); - ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *rep_del = 0; + if (rep == 0) + return; + ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *rep_del = 0; { - ACE_GUARD (ACE_LOCK, guard, rep->lock_); + ACE_WRITE_GUARD (ACE_LOCK, guard, rep->lock_); if (rep->ref_count_-- == 0) // Since rep contains the lock held by the ACE_Guard, the guard @@ -89,28 +83,6 @@ ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK>::detach (ACE_Refcounted_Auto_Ptr_Rep<X, delete rep; } -template <class X, class ACE_LOCK> inline void -ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK>::assign (ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK>*& rep, - ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK>* new_rep) -{ - ACE_ASSERT (rep != 0); - ACE_ASSERT (new_rep != 0); - - ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *old = 0; - { - // detached old last for exception safety - ACE_GUARD (ACE_LOCK, guard, rep->lock_); - old = rep; - rep = new_rep; - - if (old->ref_count_-- > 0) - return; - - } // The lock is released before deleting old rep object below. - - delete old; -} - template <class X, class ACE_LOCK> inline ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK>::ACE_Refcounted_Auto_Ptr_Rep (X *p) : ptr_ (p), @@ -123,27 +95,9 @@ ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK>::~ACE_Refcounted_Auto_Ptr_Rep (void) { } -template<class X, class ACE_LOCK> inline X * -ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK>::release (void) -{ - ACE_GUARD_RETURN (ACE_LOCK, guard, this->lock_, 0); - - return this->ptr_.release (); -} - -template<class X, class ACE_LOCK> inline void -ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK>::reset (X *p) -{ - ACE_GUARD (ACE_LOCK, guard, this->lock_); - - this->ptr_.reset (p); -} - template <class X, class ACE_LOCK> inline X * ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK>::get (void) const { - ACE_GUARD_RETURN (ACE_LOCK, guard, this->lock_, 0); - return this->ptr_.get (); } @@ -193,26 +147,45 @@ ACE_Refcounted_Auto_Ptr<X, ACE_LOCK>::get (void) const template<class X, class ACE_LOCK> inline X * ACE_Refcounted_Auto_Ptr<X, ACE_LOCK>::release (void) { - return this->rep_->release (); + X *p = this->get (); + AUTO_REFCOUNTED_PTR_REP::detach (this->rep_); + this->rep_ = 0; + return p; } template<class X, class ACE_LOCK> inline void ACE_Refcounted_Auto_Ptr<X, ACE_LOCK>::reset (X *p) { - this->rep_->reset (p); + // Avoid deleting the underlying auto_ptr if assigning the same actual + // pointer value. + if (this->get () == p) + return; + + AUTO_REFCOUNTED_PTR_REP *old_rep = this->rep_; + if ((this->rep_ = AUTO_REFCOUNTED_PTR_REP::create (p)) != 0) + AUTO_REFCOUNTED_PTR_REP::detach (old_rep); + else + this->rep_ = old_rep; + return; } template <class X, class ACE_LOCK> inline void ACE_Refcounted_Auto_Ptr<X, ACE_LOCK>::operator = (const ACE_Refcounted_Auto_Ptr<X, ACE_LOCK> &rhs) { - // assignment: - // // bind <this> to the same <ACE_Refcounted_Auto_Ptr_Rep> as <r>. - - // This will work if &r == this, by first increasing the ref count - ACE_Refcounted_Auto_Ptr<X, ACE_LOCK> &r = (ACE_Refcounted_Auto_Ptr<X, ACE_LOCK> &) rhs; - AUTO_REFCOUNTED_PTR_REP::assign (this->rep_, - AUTO_REFCOUNTED_PTR_REP::attach (r.rep_)); + AUTO_REFCOUNTED_PTR_REP *old_rep = this->rep_; + if (rhs.rep_ != 0) + { + this->rep_ = AUTO_REFCOUNTED_PTR_REP::attach + (const_cast<ACE_Refcounted_Auto_Ptr<X, ACE_LOCK>& > (rhs).rep_); + if (this->rep_ != 0) + AUTO_REFCOUNTED_PTR_REP::detach (old_rep); + } + else // Assign a 0 rep to this + { + AUTO_REFCOUNTED_PTR_REP::detach (old_rep); + this->rep_ = 0; + } } ACE_END_VERSIONED_NAMESPACE_DECL |