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 13 namespace BPrivate { 14 15 16 WeakPointer::WeakPointer(BWeakReferenceable* object) 17 : 18 fUseCount(1), 19 fObject(object) 20 { 21 } 22 23 24 WeakPointer::~WeakPointer() 25 { 26 } 27 28 29 BWeakReferenceable* 30 WeakPointer::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 44 bool 45 WeakPointer::Put() 46 { 47 if (atomic_add(&fUseCount, -1) == 1) { 48 delete fObject; 49 return true; 50 } 51 52 return false; 53 } 54 55 56 int32 57 WeakPointer::UseCount() const 58 { 59 return fUseCount; 60 } 61 62 63 void 64 WeakPointer::GetUnchecked() 65 { 66 atomic_add(&fUseCount, 1); 67 } 68 69 70 // #pragma - 71 72 73 BWeakReferenceable::BWeakReferenceable() 74 : 75 fPointer(new(std::nothrow) WeakPointer(this)) 76 { 77 } 78 79 80 BWeakReferenceable::~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 96 status_t 97 BWeakReferenceable::InitCheck() 98 { 99 if (fPointer == NULL) 100 return B_NO_MEMORY; 101 return B_OK; 102 } 103 104 105 WeakPointer* 106 BWeakReferenceable::GetWeakPointer() 107 { 108 fPointer->AcquireReference(); 109 return fPointer; 110 } 111 112 113 } // namespace BPrivate 114