Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
third_party
dart-lang
sdk
runtime
bin
reference_counting.h
Go to the documentation of this file.
1
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2
// for details. All rights reserved. Use of this source code is governed by a
3
// BSD-style license that can be found in the LICENSE file.
4
5
#ifndef RUNTIME_BIN_REFERENCE_COUNTING_H_
6
#define RUNTIME_BIN_REFERENCE_COUNTING_H_
7
8
#include <atomic>
9
10
#include "
platform/assert.h
"
11
12
namespace
dart
{
13
namespace
bin {
14
15
// Forward declaration.
16
template
<
class
Target>
17
class
RefCntReleaseScope;
18
19
// Inherit from this class where instances of the derived class should be
20
// reference counted. Reference counts on instances are incremented and
21
// decremented explicitly with calls to Retain() and Release(). E.g.:
22
//
23
// class Foo : public ReferenceCounted<Foo> {
24
// public:
25
// Foo() : ReferenceCounted() {}
26
// ...
27
// };
28
//
29
// void DoStuffWithAFoo() {
30
// Foo* foo = new Foo(); // Reference count starts at 1, so no explicit
31
// // call to Retain is needed after allocation.
32
// ...
33
// foo->Release();
34
// }
35
template
<
class
Derived>
36
class
ReferenceCounted
{
37
public
:
38
ReferenceCounted
() : ref_count_(1) {
39
#if defined(DEBUG)
40
instances_.fetch_add(1u, std::memory_order_relaxed);
41
#endif
// defined(DEBUG)
42
}
43
44
virtual
~ReferenceCounted
() {
45
ASSERT
(ref_count_ == 0);
46
#if defined(DEBUG)
47
instances_.fetch_sub(1u, std::memory_order_relaxed);
48
#endif
// defined(DEBUG)
49
}
50
51
void
Retain
() {
52
intptr_t old = ref_count_.fetch_add(1u, std::memory_order_relaxed);
53
ASSERT
(old > 0);
54
}
55
56
void
Release
() {
57
intptr_t old = ref_count_.fetch_sub(1u, std::memory_order_acq_rel);
58
ASSERT
(old > 0);
59
if
(old == 1) {
60
delete
static_cast<
Derived*
>
(
this
);
61
}
62
}
63
64
#if defined(DEBUG)
65
static
intptr_t instances() {
66
return
instances_.load(std::memory_order_relaxed);
67
}
68
#endif
// defined(DEBUG)
69
70
private
:
71
#if defined(DEBUG)
72
static
std::atomic<intptr_t> instances_;
73
#endif
// defined(DEBUG)
74
75
std::atomic<intptr_t> ref_count_;
76
77
// These are used only in the ASSERT below in RefCntReleaseScope.
78
intptr_t ref_count()
const
{
79
return
ref_count_.load(std::memory_order_relaxed);
80
}
81
friend
class
RefCntReleaseScope
<Derived>;
82
DISALLOW_COPY_AND_ASSIGN
(
ReferenceCounted
);
83
};
84
85
#if defined(DEBUG)
86
template
<
class
Derived>
87
std::atomic<intptr_t> ReferenceCounted<Derived>::instances_ = {0};
88
#endif
89
90
// Creates a scope at the end of which a reference counted object is
91
// Released. This is useful for reference counted objects received by the IO
92
// Service, which have already been Retained E.g.:
93
//
94
// CObject* Foo::FooRequest(const CObjectArray& request) {
95
// Foo* foo = CObjectToFoo(request[0]);
96
// RefCntReleaseScope<Foo> rs(foo);
97
// ...
98
// }
99
template
<
class
Target>
100
class
RefCntReleaseScope
{
101
public
:
102
explicit
RefCntReleaseScope
(
ReferenceCounted<Target>
* t) : target_(t) {
103
ASSERT
(target_ !=
nullptr
);
104
ASSERT
(target_->ref_count() > 0);
105
}
106
~RefCntReleaseScope
() { target_->
Release
(); }
107
108
private
:
109
ReferenceCounted<Target>
* target_;
110
111
DISALLOW_ALLOCATION();
112
DISALLOW_COPY_AND_ASSIGN
(
RefCntReleaseScope
);
113
};
114
115
// Instances of RetainedPointer manage Retaining and Releasing reference counted
116
// objects. There are two ways to use it. First, it can be used as a field in
117
// a class, e.g.:
118
//
119
// class Foo {
120
// private:
121
// RetainedPointer<Bar> bar_;
122
// public:
123
// explicit Foo(Bar* b) : bar_(b) {}
124
// }
125
//
126
// In this case, b will be Retained in Foo's constructor, and Released
127
// automatically during Foo's destructor.
128
//
129
// RetainedPointer can also be used as a scope, as with RefCntReleaseScope,
130
// with the difference that entering the scope also Retains the pointer, e.g.:
131
//
132
// void RetainAndDoStuffWithFoo(Foo* foo) {
133
// RetainedPointer<Foo> retained(foo);
134
// ..
135
// }
136
//
137
// This Retains foo on entry and Releases foo at every exit from the scope.
138
//
139
// The underlying pointer can be accessed with the get() and set() methods.
140
// Overwriting a non-null pointer with set causes that pointer to be Released.
141
template
<
class
Target>
142
class
RetainedPointer
{
143
public
:
144
RetainedPointer
() : target_(nullptr) {}
145
146
explicit
RetainedPointer
(
ReferenceCounted<Target>
* t) : target_(t) {
147
if
(target_ !=
nullptr
) {
148
target_->
Retain
();
149
}
150
}
151
152
~RetainedPointer
() {
153
if
(target_ !=
nullptr
) {
154
target_->
Release
();
155
}
156
}
157
158
void
set
(
ReferenceCounted<Target>
* t) {
159
if
(target_ !=
nullptr
) {
160
target_->
Release
();
161
}
162
target_ = t;
163
if
(target_ !=
nullptr
) {
164
target_->
Retain
();
165
}
166
}
167
168
Target
*
get
()
const
{
return
static_cast<
Target
*
>
(target_); }
169
170
private
:
171
ReferenceCounted<Target>
* target_;
172
173
DISALLOW_ALLOCATION();
174
DISALLOW_COPY_AND_ASSIGN
(
RetainedPointer
);
175
};
176
177
}
// namespace bin
178
}
// namespace dart
179
180
#endif
// RUNTIME_BIN_REFERENCE_COUNTING_H_
assert.h
dart::bin::RefCntReleaseScope
Definition
reference_counting.h:100
dart::bin::RefCntReleaseScope::~RefCntReleaseScope
~RefCntReleaseScope()
Definition
reference_counting.h:106
dart::bin::RefCntReleaseScope::RefCntReleaseScope
RefCntReleaseScope(ReferenceCounted< Target > *t)
Definition
reference_counting.h:102
dart::bin::ReferenceCounted
Definition
reference_counting.h:36
dart::bin::ReferenceCounted::Retain
void Retain()
Definition
reference_counting.h:51
dart::bin::ReferenceCounted::Release
void Release()
Definition
reference_counting.h:56
dart::bin::ReferenceCounted::ReferenceCounted
ReferenceCounted()
Definition
reference_counting.h:38
dart::bin::ReferenceCounted::~ReferenceCounted
virtual ~ReferenceCounted()
Definition
reference_counting.h:44
dart::bin::RetainedPointer
Definition
reference_counting.h:142
dart::bin::RetainedPointer::get
Target * get() const
Definition
reference_counting.h:168
dart::bin::RetainedPointer::RetainedPointer
RetainedPointer(ReferenceCounted< Target > *t)
Definition
reference_counting.h:146
dart::bin::RetainedPointer::~RetainedPointer
~RetainedPointer()
Definition
reference_counting.h:152
dart::bin::RetainedPointer::RetainedPointer
RetainedPointer()
Definition
reference_counting.h:144
dart::bin::RetainedPointer::set
void set(ReferenceCounted< Target > *t)
Definition
reference_counting.h:158
ASSERT
#define ASSERT(E)
Definition
entrypoints_verification_test.cc:25
dart
Definition
dart_vm.cc:33
DISALLOW_COPY_AND_ASSIGN
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition
globals.h:581
Target
Definition
nanobench.h:36
Generated on Fri Apr 26 2024 06:14:43 for Flutter Engine by
1.9.8