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
21BReferenceable::BReferenceable()
22	:
23	fReferenceCount(1)
24{
25}
26
27
28BReferenceable::~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
41int32
42BReferenceable::AcquireReference()
43{
44	int32 previousReferenceCount = atomic_add(&fReferenceCount, 1);
45	if (previousReferenceCount == 0)
46		FirstReferenceAcquired();
47
48	TRACE("%p: acquire %ld\n", this, fReferenceCount);
49
50	return previousReferenceCount;
51}
52
53
54int32
55BReferenceable::ReleaseReference()
56{
57	int32 previousReferenceCount = atomic_add(&fReferenceCount, -1);
58	TRACE("%p: release %ld\n", this, fReferenceCount);
59	if (previousReferenceCount == 1)
60		LastReferenceReleased();
61	return previousReferenceCount;
62}
63
64
65void
66BReferenceable::FirstReferenceAcquired()
67{
68}
69
70
71void
72BReferenceable::LastReferenceReleased()
73{
74	delete this;
75}
76