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