mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 04:37:00 +00:00
(based on zergtmn's repo commit 3a8c259) (based on zergtmn's repo commit 946c1a8) Signed-off-by: VladimirMangos <vladimir@getmangos.com>
494 lines
14 KiB
C++
494 lines
14 KiB
C++
/* -*- C++ -*- */
|
|
// $Id: Bound_Ptr.inl 91626 2010-09-07 10:59:20Z johnnyw $
|
|
|
|
// Bound_Ptr.i
|
|
|
|
#include "ace/Guard_T.h"
|
|
#if !defined (ACE_NEW_THROWS_EXCEPTIONS)
|
|
# include "ace/Log_Msg.h"
|
|
#endif /* ACE_NEW_THROWS_EXCEPTIONS */
|
|
|
|
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
|
|
|
template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
|
|
ACE_Bound_Ptr_Counter<ACE_LOCK>::internal_create (long init_obj_ref_count)
|
|
{
|
|
ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = 0;
|
|
ACE_NEW_RETURN (temp,
|
|
ACE_Bound_Ptr_Counter<ACE_LOCK> (init_obj_ref_count),
|
|
0);
|
|
return temp;
|
|
}
|
|
|
|
template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
|
|
ACE_Bound_Ptr_Counter<ACE_LOCK>::create_strong (void)
|
|
{
|
|
// Set initial object reference count to 1.
|
|
ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = internal_create (1);
|
|
#if defined (ACE_NEW_THROWS_EXCEPTIONS)
|
|
if (temp == 0)
|
|
ACE_throw_bad_alloc;
|
|
#else
|
|
ACE_ASSERT (temp != 0);
|
|
#endif /* ACE_NEW_THROWS_EXCEPTIONS */
|
|
return temp;
|
|
}
|
|
|
|
|
|
|
|
template <class ACE_LOCK> inline long
|
|
ACE_Bound_Ptr_Counter<ACE_LOCK>::attach_strong (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
|
|
{
|
|
ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, -1);
|
|
|
|
// Can't attach a strong pointer to an object that has already been deleted.
|
|
if (counter->obj_ref_count_ == -1)
|
|
return -1;
|
|
|
|
long new_obj_ref_count = ++counter->obj_ref_count_;
|
|
++counter->self_ref_count_;
|
|
|
|
return new_obj_ref_count;
|
|
}
|
|
|
|
template <class ACE_LOCK> inline long
|
|
ACE_Bound_Ptr_Counter<ACE_LOCK>::detach_strong (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
|
|
{
|
|
ACE_Bound_Ptr_Counter<ACE_LOCK> *counter_del = 0;
|
|
long new_obj_ref_count;
|
|
|
|
{
|
|
ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, -1);
|
|
|
|
if ((new_obj_ref_count = --counter->obj_ref_count_) == 0)
|
|
// Change the object reference count to -1 to indicate that the
|
|
// object has been deleted, as opposed to a weak pointer that
|
|
// simply hasn't had any strong pointers created from it yet.
|
|
counter->obj_ref_count_ = -1;
|
|
|
|
if (--counter->self_ref_count_ == 0)
|
|
// Since counter contains the lock held by the guard, the
|
|
// guard needs to be released before freeing the memory holding
|
|
// the lock. So save the pointer to free, then release, then
|
|
// free.
|
|
counter_del = counter;
|
|
|
|
} // Release the lock
|
|
|
|
delete counter_del;
|
|
|
|
return new_obj_ref_count;
|
|
}
|
|
|
|
template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
|
|
ACE_Bound_Ptr_Counter<ACE_LOCK>::create_weak (void)
|
|
{
|
|
// Set initial object reference count to 0.
|
|
|
|
ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = internal_create (0);
|
|
#if defined (ACE_NEW_THROWS_EXCEPTIONS)
|
|
if (temp == 0)
|
|
ACE_throw_bad_alloc;
|
|
#else
|
|
ACE_ASSERT (temp != 0);
|
|
#endif /* ACE_NEW_THROWS_EXCEPTIONS */
|
|
return temp;
|
|
}
|
|
|
|
template <class ACE_LOCK> inline void
|
|
ACE_Bound_Ptr_Counter<ACE_LOCK>::attach_weak (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
|
|
{
|
|
ACE_GUARD (ACE_LOCK, guard, counter->lock_);
|
|
|
|
++counter->self_ref_count_;
|
|
}
|
|
|
|
template <class ACE_LOCK> inline void
|
|
ACE_Bound_Ptr_Counter<ACE_LOCK>::detach_weak (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
|
|
{
|
|
ACE_Bound_Ptr_Counter<ACE_LOCK> *counter_del = 0;
|
|
|
|
{
|
|
ACE_GUARD (ACE_LOCK, guard, counter->lock_);
|
|
|
|
if (--counter->self_ref_count_ == 0)
|
|
// Since counter contains the lock held by the guard, the
|
|
// guard needs to be released before freeing the memory holding
|
|
// the lock. So save the pointer to free, then release, then
|
|
// free.
|
|
counter_del = counter;
|
|
|
|
} // Release the lock
|
|
|
|
delete counter_del;
|
|
}
|
|
|
|
template <class ACE_LOCK> inline bool
|
|
ACE_Bound_Ptr_Counter<ACE_LOCK>::object_was_deleted (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter)
|
|
{
|
|
ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, 0);
|
|
|
|
return counter->obj_ref_count_ == -1;
|
|
}
|
|
|
|
template <class ACE_LOCK> inline
|
|
ACE_Bound_Ptr_Counter<ACE_LOCK>::ACE_Bound_Ptr_Counter (long init_obj_ref_count)
|
|
: obj_ref_count_ (init_obj_ref_count),
|
|
self_ref_count_ (1)
|
|
{
|
|
}
|
|
|
|
template <class ACE_LOCK> inline
|
|
ACE_Bound_Ptr_Counter<ACE_LOCK>::~ACE_Bound_Ptr_Counter (void)
|
|
{
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline
|
|
ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (X *p)
|
|
: counter_ (COUNTER::create_strong ()),
|
|
ptr_ (p)
|
|
{
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline
|
|
ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (auto_ptr<X> p)
|
|
: counter_ (COUNTER::create_strong ()),
|
|
ptr_ (p.release())
|
|
{
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline
|
|
ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r)
|
|
: counter_ (r.counter_),
|
|
ptr_ (r.ptr_)
|
|
{
|
|
COUNTER::attach_strong (this->counter_);
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline
|
|
ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r)
|
|
: counter_ (r.counter_),
|
|
ptr_ (r.ptr_)
|
|
{
|
|
// When creating a strong pointer from a weak one we can't assume that the
|
|
// underlying object still exists. Therefore we must check for a return value
|
|
// of -1, which indicates that the object has been destroyed.
|
|
if (COUNTER::attach_strong (this->counter_) == -1)
|
|
{
|
|
// Underlying object has already been deleted, so set this pointer to null.
|
|
this->counter_ = COUNTER::create_strong ();
|
|
this->ptr_ = 0;
|
|
}
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline
|
|
ACE_Strong_Bound_Ptr<X, ACE_LOCK>::~ACE_Strong_Bound_Ptr (void)
|
|
{
|
|
if (COUNTER::detach_strong (this->counter_) == 0)
|
|
delete this->ptr_;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline void
|
|
ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &rhs)
|
|
{
|
|
// This will work if &r == this, by first increasing the ref count, but
|
|
// why go through all that?
|
|
if (&rhs == this)
|
|
return;
|
|
|
|
COUNTER *new_counter = rhs.counter_;
|
|
X_t *new_ptr = rhs.ptr_;
|
|
COUNTER::attach_strong (new_counter);
|
|
if (COUNTER::detach_strong (this->counter_) == 0)
|
|
delete this->ptr_;
|
|
this->counter_ = new_counter;
|
|
this->ptr_ = new_ptr;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline void
|
|
ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &rhs)
|
|
{
|
|
// This will work if &r == this, by first increasing the ref count, but
|
|
// why go through all that?
|
|
if (&rhs == this)
|
|
return;
|
|
|
|
COUNTER *new_counter = rhs.counter_;
|
|
X_t *new_ptr = rhs.ptr_;
|
|
|
|
// When creating a strong pointer from a weak one we can't assume that the
|
|
// underlying object still exists. Therefore we must check for a return value
|
|
// of -1, which indicates that the object has been destroyed.
|
|
if (COUNTER::attach_strong (new_counter) == -1)
|
|
{
|
|
// Underlying object has already been deleted, so set this pointer to null.
|
|
new_counter = COUNTER::create_strong ();
|
|
new_ptr = 0;
|
|
}
|
|
|
|
if (COUNTER::detach_strong (this->counter_) == 0)
|
|
delete this->ptr_;
|
|
this->counter_ = new_counter;
|
|
this->ptr_ = new_ptr;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline bool
|
|
ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
|
|
{
|
|
return this->ptr_ == r.ptr_;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline bool
|
|
ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
|
|
{
|
|
// Use the weak pointer's operator== since it will check for null.
|
|
return r == *this;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline bool
|
|
ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (X *p) const
|
|
{
|
|
return this->ptr_ == p;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline bool
|
|
ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
|
|
{
|
|
return this->ptr_ != r.ptr_;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline bool
|
|
ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
|
|
{
|
|
// Use the weak pointer's operator!= since it will check for null.
|
|
return r != *this;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline bool
|
|
ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (X *p) const
|
|
{
|
|
return this->ptr_ != p;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline X *
|
|
ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator-> (void) const
|
|
{
|
|
return this->ptr_;
|
|
}
|
|
|
|
template<class X, class ACE_LOCK> inline X &
|
|
ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator *() const
|
|
{
|
|
return *this->ptr_;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline X*
|
|
ACE_Strong_Bound_Ptr<X, ACE_LOCK>::get (void) const
|
|
{
|
|
return this->ptr_;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline bool
|
|
ACE_Strong_Bound_Ptr<X, ACE_LOCK>::null (void) const
|
|
{
|
|
return this->ptr_ == 0;
|
|
}
|
|
|
|
template<class X, class ACE_LOCK> inline void
|
|
ACE_Strong_Bound_Ptr<X, ACE_LOCK>::reset (X *p)
|
|
{
|
|
COUNTER *old_counter = this->counter_;
|
|
X_t *old_ptr = this->ptr_;
|
|
this->counter_ = COUNTER::create_strong ();
|
|
this->ptr_ = p;
|
|
if (COUNTER::detach_strong (old_counter) == 0)
|
|
delete old_ptr;
|
|
}
|
|
|
|
template<class X, class ACE_LOCK> inline void
|
|
ACE_Strong_Bound_Ptr<X, ACE_LOCK>::reset (auto_ptr<X> p)
|
|
{
|
|
COUNTER *old_counter = this->counter_;
|
|
X_t *old_ptr = this->ptr_;
|
|
this->counter_ = COUNTER::create_strong ();
|
|
this->ptr_ = p.release ();
|
|
if (COUNTER::detach_strong (old_counter) == 0)
|
|
delete old_ptr;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline
|
|
ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (X *p)
|
|
: counter_ (COUNTER::create_weak ()),
|
|
ptr_ (p)
|
|
{
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline
|
|
ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r)
|
|
: counter_ (r.counter_),
|
|
ptr_ (r.ptr_)
|
|
{
|
|
COUNTER::attach_weak (this->counter_);
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline
|
|
ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r)
|
|
: counter_ (r.counter_),
|
|
ptr_ (r.ptr_)
|
|
{
|
|
COUNTER::attach_weak (this->counter_);
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline
|
|
ACE_Weak_Bound_Ptr<X, ACE_LOCK>::~ACE_Weak_Bound_Ptr (void)
|
|
{
|
|
COUNTER::detach_weak (this->counter_);
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline void
|
|
ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &rhs)
|
|
{
|
|
// This will work if &rhs == this, by first increasing the ref count
|
|
COUNTER *new_counter = rhs.counter_;
|
|
COUNTER::attach_weak (new_counter);
|
|
COUNTER::detach_weak (this->counter_);
|
|
this->counter_ = new_counter;
|
|
this->ptr_ = rhs.ptr_;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline void
|
|
ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &rhs)
|
|
{
|
|
// This will work if &rhs == this, by first increasing the ref count
|
|
COUNTER *new_counter = rhs.counter_;
|
|
COUNTER::attach_weak (new_counter);
|
|
COUNTER::detach_weak (this->counter_);
|
|
this->counter_ = new_counter;
|
|
this->ptr_ = rhs.ptr_;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline bool
|
|
ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
|
|
{
|
|
// A weak pointer must behave as though it is automatically set to null
|
|
// if the underlying object has been deleted.
|
|
if (COUNTER::object_was_deleted (this->counter_))
|
|
return r.ptr_ == 0;
|
|
|
|
return this->ptr_ == r.ptr_;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline bool
|
|
ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
|
|
{
|
|
// A weak pointer must behave as though it is automatically set to null
|
|
// if the underlying object has been deleted.
|
|
if (COUNTER::object_was_deleted (this->counter_))
|
|
return r.ptr_ == 0;
|
|
|
|
return this->ptr_ == r.ptr_;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline bool
|
|
ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (X *p) const
|
|
{
|
|
// A weak pointer must behave as though it is automatically set to null
|
|
// if the underlying object has been deleted.
|
|
if (COUNTER::object_was_deleted (this->counter_))
|
|
return p == 0;
|
|
|
|
return this->ptr_ == p;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline bool
|
|
ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
|
|
{
|
|
// A weak pointer must behave as though it is automatically set to null
|
|
// if the underlying object has been deleted.
|
|
if (COUNTER::object_was_deleted (this->counter_))
|
|
return r.ptr_ != 0;
|
|
|
|
return this->ptr_ != r.ptr_;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline bool
|
|
ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
|
|
{
|
|
// A weak pointer must behave as though it is automatically set to null
|
|
// if the underlying object has been deleted.
|
|
if (COUNTER::object_was_deleted (this->counter_))
|
|
return r.ptr_ != 0;
|
|
|
|
return this->ptr_ != r.ptr_;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline bool
|
|
ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (X *p) const
|
|
{
|
|
// A weak pointer must behave as though it is automatically set to null
|
|
// if the underlying object has been deleted.
|
|
if (COUNTER::object_was_deleted (this->counter_))
|
|
return p != 0;
|
|
|
|
return this->ptr_ != p;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline ACE_Strong_Bound_Ptr<X, ACE_LOCK>
|
|
ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator-> (void) const
|
|
{
|
|
return ACE_Strong_Bound_Ptr<X, ACE_LOCK> (*this);
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline ACE_Strong_Bound_Ptr<X, ACE_LOCK>
|
|
ACE_Weak_Bound_Ptr<X, ACE_LOCK>::strong (void) const
|
|
{
|
|
return ACE_Strong_Bound_Ptr<X, ACE_LOCK> (*this);
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline X*
|
|
ACE_Weak_Bound_Ptr<X, ACE_LOCK>::unsafe_get (void) const
|
|
{
|
|
// We do not check if the object has been deleted, since this operation
|
|
// is defined to be unsafe!
|
|
return this->ptr_;
|
|
}
|
|
|
|
template <class X, class ACE_LOCK> inline bool
|
|
ACE_Weak_Bound_Ptr<X, ACE_LOCK>::null (void) const
|
|
{
|
|
// A weak pointer must behave as though it is automatically set to null
|
|
// if the underlying object has been deleted.
|
|
if (COUNTER::object_was_deleted (this->counter_))
|
|
return true;
|
|
|
|
return this->ptr_ == 0;
|
|
}
|
|
|
|
template<class X, class ACE_LOCK> inline void
|
|
ACE_Weak_Bound_Ptr<X, ACE_LOCK>::reset (X *p)
|
|
{
|
|
COUNTER *old_counter = this->counter_;
|
|
this->counter_ = COUNTER::create_weak ();
|
|
this->ptr_ = p;
|
|
COUNTER::detach_weak (old_counter);
|
|
}
|
|
|
|
template<class X, class ACE_LOCK> inline long
|
|
ACE_Weak_Bound_Ptr<X, ACE_LOCK>::add_ref ()
|
|
{
|
|
return COUNTER::attach_strong (counter_);
|
|
}
|
|
|
|
template<class X, class ACE_LOCK> inline long
|
|
ACE_Weak_Bound_Ptr<X, ACE_LOCK>::remove_ref ()
|
|
{
|
|
long new_obj_ref_count = COUNTER::detach_strong (counter_);
|
|
if (new_obj_ref_count == 0)
|
|
{
|
|
delete this->ptr_;
|
|
this->ptr_ = 0;
|
|
}
|
|
return new_obj_ref_count;
|
|
}
|
|
|
|
ACE_END_VERSIONED_NAMESPACE_DECL
|