summaryrefslogtreecommitdiff
path: root/ace
diff options
context:
space:
mode:
authorSteve Huston <shuston@riverace.com>2006-07-12 20:59:39 +0000
committerSteve Huston <shuston@riverace.com>2006-07-12 20:59:39 +0000
commit095a62e4f97f3611ef21d94ff547966f8560fca1 (patch)
treeee89402f3e81bf241d49ea6bc979d5e7727ec5e1 /ace
parentd038c9097e7e2120b0f695040385ef2759c772e9 (diff)
downloadATCD-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.h76
-rw-r--r--ace/Refcounted_Auto_Ptr.inl101
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