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
BReferenceable()21 BReferenceable::BReferenceable()
22 :
23 fReferenceCount(1)
24 {
25 }
26
27
~BReferenceable()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
AcquireReference()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
ReleaseReference()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
FirstReferenceAcquired()74 BReferenceable::FirstReferenceAcquired()
75 {
76 }
77
78
79 void
LastReferenceReleased()80 BReferenceable::LastReferenceReleased()
81 {
82 delete this;
83 }
84