1/* 2 * Copyright 2009, Axel D��rfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include <WeakReferenceable.h> 8 9#include <stdio.h> 10#include <OS.h> 11 12 13namespace BPrivate { 14 15 16WeakPointer::WeakPointer(BWeakReferenceable* object) 17 : 18 fUseCount(1), 19 fObject(object) 20{ 21} 22 23 24WeakPointer::~WeakPointer() 25{ 26} 27 28 29BWeakReferenceable* 30WeakPointer::Get() 31{ 32 int32 count = -11; 33 34 do { 35 count = atomic_get(&fUseCount); 36 if (count == 0) 37 return NULL; 38 } while (atomic_test_and_set(&fUseCount, count + 1, count) != count); 39 40 return fObject; 41} 42 43 44bool 45WeakPointer::Put() 46{ 47 if (atomic_add(&fUseCount, -1) == 1) { 48 delete fObject; 49 return true; 50 } 51 52 return false; 53} 54 55 56int32 57WeakPointer::UseCount() const 58{ 59 return fUseCount; 60} 61 62 63void 64WeakPointer::GetUnchecked() 65{ 66 atomic_add(&fUseCount, 1); 67} 68 69 70// #pragma - 71 72 73BWeakReferenceable::BWeakReferenceable() 74 : 75 fPointer(new(std::nothrow) WeakPointer(this)) 76{ 77} 78 79 80BWeakReferenceable::~BWeakReferenceable() 81{ 82 if (fPointer->UseCount() == 1) 83 atomic_test_and_set(&fPointer->fUseCount, 0, 1); 84 85 if (fPointer->UseCount() != 0) { 86 char message[256]; 87 snprintf(message, sizeof(message), "deleting referenceable object %p with " 88 "reference count (%" B_PRId32 ")", this, fPointer->UseCount()); 89 debugger(message); 90 } 91 92 fPointer->ReleaseReference(); 93} 94 95 96status_t 97BWeakReferenceable::InitCheck() 98{ 99 if (fPointer == NULL) 100 return B_NO_MEMORY; 101 return B_OK; 102} 103 104 105WeakPointer* 106BWeakReferenceable::GetWeakPointer() 107{ 108 fPointer->AcquireReference(); 109 return fPointer; 110} 111 112 113} // namespace BPrivate 114