/* -*- C++ -*- */ #include "ace/Guard_T.h" ACE_BEGIN_VERSIONED_NAMESPACE_DECL template inline ACE_Bound_Ptr_Counter * ACE_Bound_Ptr_Counter::internal_create (long init_obj_ref_count) { ACE_Bound_Ptr_Counter *temp = 0; ACE_NEW_RETURN (temp, ACE_Bound_Ptr_Counter (init_obj_ref_count), 0); return temp; } template inline ACE_Bound_Ptr_Counter * ACE_Bound_Ptr_Counter::create_strong () { // Set initial object reference count to 1. ACE_Bound_Ptr_Counter *temp = internal_create (1); if (!temp) throw std::bad_alloc (); return temp; } template inline long ACE_Bound_Ptr_Counter::attach_strong (ACE_Bound_Ptr_Counter* 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 const new_obj_ref_count = ++counter->obj_ref_count_; ++counter->self_ref_count_; return new_obj_ref_count; } template inline long ACE_Bound_Ptr_Counter::detach_strong (ACE_Bound_Ptr_Counter* counter) { ACE_Bound_Ptr_Counter *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 inline ACE_Bound_Ptr_Counter * ACE_Bound_Ptr_Counter::create_weak () { // Set initial object reference count to 0. ACE_Bound_Ptr_Counter *temp = internal_create (0); if (!temp) throw std::bad_alloc (); return temp; } template inline void ACE_Bound_Ptr_Counter::attach_weak (ACE_Bound_Ptr_Counter* counter) { ACE_GUARD (ACE_LOCK, guard, counter->lock_); ++counter->self_ref_count_; } template inline void ACE_Bound_Ptr_Counter::detach_weak (ACE_Bound_Ptr_Counter* counter) { ACE_Bound_Ptr_Counter *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 inline bool ACE_Bound_Ptr_Counter::object_was_deleted (ACE_Bound_Ptr_Counter *counter) { ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, 0); return counter->obj_ref_count_ == -1; } template inline ACE_Bound_Ptr_Counter::ACE_Bound_Ptr_Counter (long init_obj_ref_count) : obj_ref_count_ (init_obj_ref_count), self_ref_count_ (1) { } template inline ACE_Strong_Bound_Ptr::ACE_Strong_Bound_Ptr (X *p) : counter_ (COUNTER::create_strong ()), ptr_ (p) { } template inline ACE_Strong_Bound_Ptr::ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr &r) : counter_ (r.counter_), ptr_ (r.ptr_) { COUNTER::attach_strong (this->counter_); } template inline ACE_Strong_Bound_Ptr::ACE_Strong_Bound_Ptr (const ACE_Weak_Bound_Ptr &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 inline ACE_Strong_Bound_Ptr::~ACE_Strong_Bound_Ptr () { if (COUNTER::detach_strong (this->counter_) == 0) delete this->ptr_; } template inline void ACE_Strong_Bound_Ptr::operator = (const ACE_Strong_Bound_Ptr &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 *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 inline void ACE_Strong_Bound_Ptr::operator = (const ACE_Weak_Bound_Ptr &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 *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 inline bool ACE_Strong_Bound_Ptr::operator== (const ACE_Strong_Bound_Ptr &r) const { return this->ptr_ == r.ptr_; } template inline bool ACE_Strong_Bound_Ptr::operator== (const ACE_Weak_Bound_Ptr &r) const { // Use the weak pointer's operator== since it will check for null. return r == *this; } template inline bool ACE_Strong_Bound_Ptr::operator== (X *p) const { return this->ptr_ == p; } template inline bool ACE_Strong_Bound_Ptr::operator!= (const ACE_Strong_Bound_Ptr &r) const { return this->ptr_ != r.ptr_; } template inline bool ACE_Strong_Bound_Ptr::operator!= (const ACE_Weak_Bound_Ptr &r) const { // Use the weak pointer's operator!= since it will check for null. return r != *this; } template inline bool ACE_Strong_Bound_Ptr::operator!= (X *p) const { return this->ptr_ != p; } template inline X * ACE_Strong_Bound_Ptr::operator-> () const { return this->ptr_; } template inline X & ACE_Strong_Bound_Ptr::operator *() const { return *this->ptr_; } template inline X* ACE_Strong_Bound_Ptr::get () const { return this->ptr_; } template inline bool ACE_Strong_Bound_Ptr::null () const { return this->ptr_ == 0; } template inline void ACE_Strong_Bound_Ptr::reset (X *p) { COUNTER *old_counter = this->counter_; X *old_ptr = this->ptr_; this->counter_ = COUNTER::create_strong (); this->ptr_ = p; if (COUNTER::detach_strong (old_counter) == 0) delete old_ptr; } template inline ACE_Weak_Bound_Ptr::ACE_Weak_Bound_Ptr (X *p) : counter_ (COUNTER::create_weak ()), ptr_ (p) { } template inline ACE_Weak_Bound_Ptr::ACE_Weak_Bound_Ptr (const ACE_Weak_Bound_Ptr &r) : counter_ (r.counter_), ptr_ (r.ptr_) { COUNTER::attach_weak (this->counter_); } template inline ACE_Weak_Bound_Ptr::ACE_Weak_Bound_Ptr (const ACE_Strong_Bound_Ptr &r) : counter_ (r.counter_), ptr_ (r.ptr_) { COUNTER::attach_weak (this->counter_); } template inline ACE_Weak_Bound_Ptr::~ACE_Weak_Bound_Ptr () { COUNTER::detach_weak (this->counter_); } template inline void ACE_Weak_Bound_Ptr::operator = (const ACE_Weak_Bound_Ptr &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 inline void ACE_Weak_Bound_Ptr::operator = (const ACE_Strong_Bound_Ptr &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 inline bool ACE_Weak_Bound_Ptr::operator== (const ACE_Weak_Bound_Ptr &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 inline bool ACE_Weak_Bound_Ptr::operator== (const ACE_Strong_Bound_Ptr &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 inline bool ACE_Weak_Bound_Ptr::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 inline bool ACE_Weak_Bound_Ptr::operator!= (const ACE_Weak_Bound_Ptr &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 inline bool ACE_Weak_Bound_Ptr::operator!= (const ACE_Strong_Bound_Ptr &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 inline bool ACE_Weak_Bound_Ptr::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 inline ACE_Strong_Bound_Ptr ACE_Weak_Bound_Ptr::operator-> () const { return ACE_Strong_Bound_Ptr (*this); } template inline ACE_Strong_Bound_Ptr ACE_Weak_Bound_Ptr::strong () const { return ACE_Strong_Bound_Ptr (*this); } template inline X* ACE_Weak_Bound_Ptr::unsafe_get () const { // We do not check if the object has been deleted, since this operation // is defined to be unsafe! return this->ptr_; } template inline bool ACE_Weak_Bound_Ptr::null () 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 inline void ACE_Weak_Bound_Ptr::reset (X *p) { COUNTER *old_counter = this->counter_; this->counter_ = COUNTER::create_weak (); this->ptr_ = p; COUNTER::detach_weak (old_counter); } template inline long ACE_Weak_Bound_Ptr::add_ref () { return COUNTER::attach_strong (counter_); } template inline long ACE_Weak_Bound_Ptr::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