1 /* 2 * Copyright 2005-2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <Referenceable.h> 8 9 #include <stdio.h> 10 #include <OS.h> 11 12 //#define TRACE_REFERENCEABLE 13 #if defined(TRACE_REFERENCEABLE) && defined(_KERNEL_MODE) 14 # include <tracing.h> 15 # define TRACE(x, ...) ktrace_printf(x, __VA_ARGS__); 16 #else 17 # define TRACE(x, ...) 18 #endif 19 20 21 BReferenceable::BReferenceable() 22 : 23 fReferenceCount(1) 24 { 25 } 26 27 28 BReferenceable::~BReferenceable() 29 { 30 #if !defined(_BOOT_MODE) 31 if (fReferenceCount != 0 && fReferenceCount != 1) { 32 char message[256]; 33 snprintf(message, sizeof(message), "deleting referenceable object %p with " 34 "reference count (%" B_PRId32 ")", this, fReferenceCount); 35 debugger(message); 36 } 37 #endif 38 } 39 40 41 int32 42 BReferenceable::AcquireReference() 43 { 44 const int32 previousReferenceCount = atomic_add(&fReferenceCount, 1); 45 if (previousReferenceCount == 0) 46 FirstReferenceAcquired(); 47 #if !defined(_BOOT_MODE) 48 if (previousReferenceCount < 0) 49 debugger("reference count is/was negative"); 50 #endif 51 52 TRACE("%p: acquire %ld\n", this, fReferenceCount); 53 54 return previousReferenceCount; 55 } 56 57 58 int32 59 BReferenceable::ReleaseReference() 60 { 61 const int32 previousReferenceCount = atomic_add(&fReferenceCount, -1); 62 TRACE("%p: release %ld\n", this, fReferenceCount); 63 if (previousReferenceCount == 1) 64 LastReferenceReleased(); 65 #if !defined(_BOOT_MODE) 66 if (previousReferenceCount <= 0) 67 debugger("reference count is negative"); 68 #endif 69 return previousReferenceCount; 70 } 71 72 73 void 74 BReferenceable::FirstReferenceAcquired() 75 { 76 } 77 78 79 void 80 BReferenceable::LastReferenceReleased() 81 { 82 delete this; 83 } 84