/* * Copyright 2009, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ #include #include #include namespace BPrivate { WeakPointer::WeakPointer(BWeakReferenceable* object) : fUseCount(1), fObject(object) { } WeakPointer::~WeakPointer() { } BWeakReferenceable* WeakPointer::Get() { int32 count = -11; do { count = atomic_get(&fUseCount); if (count == 0) return NULL; } while (atomic_test_and_set(&fUseCount, count + 1, count) != count); return fObject; } bool WeakPointer::Put() { if (atomic_add(&fUseCount, -1) == 1) { delete fObject; return true; } return false; } int32 WeakPointer::UseCount() const { return fUseCount; } void WeakPointer::GetUnchecked() { atomic_add(&fUseCount, 1); } // #pragma - BWeakReferenceable::BWeakReferenceable() : fPointer(new(std::nothrow) WeakPointer(this)) { } BWeakReferenceable::~BWeakReferenceable() { if (fPointer->UseCount() == 1) atomic_test_and_set(&fPointer->fUseCount, 0, 1); if (fPointer->UseCount() != 0) { char message[256]; snprintf(message, sizeof(message), "deleting referenceable object %p with " "reference count (%" B_PRId32 ")", this, fPointer->UseCount()); debugger(message); } fPointer->ReleaseReference(); } status_t BWeakReferenceable::InitCheck() { if (fPointer == NULL) return B_NO_MEMORY; return B_OK; } WeakPointer* BWeakReferenceable::GetWeakPointer() { fPointer->AcquireReference(); return fPointer; } } // namespace BPrivate