Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/jdk/internal/ref/PhantomCleanable.java
41159 views
1
/*
2
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package jdk.internal.ref;
27
28
import java.lang.ref.Cleaner;
29
import java.lang.ref.Reference;
30
import java.lang.ref.PhantomReference;
31
import java.util.Objects;
32
33
/**
34
* PhantomCleanable subclasses efficiently encapsulate cleanup state and
35
* the cleaning action.
36
* Subclasses implement the abstract {@link #performCleanup()} method
37
* to provide the cleaning action.
38
* When constructed, the object reference and the {@link Cleaner.Cleanable Cleanable}
39
* are registered with the {@link Cleaner}.
40
* The Cleaner invokes {@link Cleaner.Cleanable#clean() clean} after the
41
* referent becomes phantom reachable.
42
*/
43
public abstract class PhantomCleanable<T> extends PhantomReference<T>
44
implements Cleaner.Cleanable {
45
46
/**
47
* Links to previous and next in a doubly-linked list.
48
*/
49
PhantomCleanable<?> prev = this, next = this;
50
51
/**
52
* The list of PhantomCleanable; synchronizes insert and remove.
53
*/
54
private final PhantomCleanable<?> list;
55
56
/**
57
* Constructs new {@code PhantomCleanable} with
58
* {@code non-null referent} and {@code non-null cleaner}.
59
* The {@code cleaner} is not retained; it is only used to
60
* register the newly constructed {@link Cleaner.Cleanable Cleanable}.
61
*
62
* @param referent the referent to track
63
* @param cleaner the {@code Cleaner} to register with
64
*/
65
public PhantomCleanable(T referent, Cleaner cleaner) {
66
super(Objects.requireNonNull(referent), CleanerImpl.getCleanerImpl(cleaner).queue);
67
this.list = CleanerImpl.getCleanerImpl(cleaner).phantomCleanableList;
68
insert();
69
70
// Ensure referent and cleaner remain accessible
71
Reference.reachabilityFence(referent);
72
Reference.reachabilityFence(cleaner);
73
}
74
75
/**
76
* Construct a new root of the list; not inserted.
77
*/
78
PhantomCleanable() {
79
super(null, null);
80
this.list = this;
81
}
82
83
/**
84
* Insert this PhantomCleanable after the list head.
85
*/
86
private void insert() {
87
synchronized (list) {
88
prev = list;
89
next = list.next;
90
next.prev = this;
91
list.next = this;
92
}
93
}
94
95
/**
96
* Remove this PhantomCleanable from the list.
97
*
98
* @return true if Cleanable was removed or false if not because
99
* it had already been removed before
100
*/
101
private boolean remove() {
102
synchronized (list) {
103
if (next != this) {
104
next.prev = prev;
105
prev.next = next;
106
prev = this;
107
next = this;
108
return true;
109
}
110
return false;
111
}
112
}
113
114
/**
115
* Returns true if the list's next reference refers to itself.
116
*
117
* @return true if the list is empty
118
*/
119
boolean isListEmpty() {
120
synchronized (list) {
121
return list == list.next;
122
}
123
}
124
125
/**
126
* Unregister this PhantomCleanable and invoke {@link #performCleanup()},
127
* ensuring at-most-once semantics.
128
*/
129
@Override
130
public final void clean() {
131
if (remove()) {
132
super.clear();
133
performCleanup();
134
}
135
}
136
137
/**
138
* Unregister this PhantomCleanable and clear the reference.
139
* Due to inherent concurrency, {@link #performCleanup()} may still be invoked.
140
*/
141
@Override
142
public void clear() {
143
if (remove()) {
144
super.clear();
145
}
146
}
147
148
/**
149
* The {@code performCleanup} abstract method is overridden
150
* to implement the cleaning logic.
151
* The {@code performCleanup} method should not be called except
152
* by the {@link #clean} method which ensures at most once semantics.
153
*/
154
protected abstract void performCleanup();
155
156
/**
157
* This method always throws {@link UnsupportedOperationException}.
158
* Enqueuing details of {@link Cleaner.Cleanable}
159
* are a private implementation detail.
160
*
161
* @throws UnsupportedOperationException always
162
*/
163
@SuppressWarnings("deprecation")
164
@Override
165
public final boolean isEnqueued() {
166
throw new UnsupportedOperationException("isEnqueued");
167
}
168
169
/**
170
* This method always throws {@link UnsupportedOperationException}.
171
* Enqueuing details of {@link Cleaner.Cleanable}
172
* are a private implementation detail.
173
*
174
* @throws UnsupportedOperationException always
175
*/
176
@Override
177
public final boolean enqueue() {
178
throw new UnsupportedOperationException("enqueue");
179
}
180
}
181
182