Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/jcl/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java
12520 views
1
/*[INCLUDE-IF Sidecar16]*/
2
package java.lang.ref;
3
4
/*[IF Sidecar19-SE]
5
import jdk.internal.ref.Cleaner;
6
/*[ELSE]*/
7
import sun.misc.Cleaner;
8
/*[ENDIF]*/
9
10
/*******************************************************************************
11
* Copyright (c) 1998, 2017 IBM Corp. and others
12
*
13
* This program and the accompanying materials are made available under
14
* the terms of the Eclipse Public License 2.0 which accompanies this
15
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
16
* or the Apache License, Version 2.0 which accompanies this distribution and
17
* is available at https://www.apache.org/licenses/LICENSE-2.0.
18
*
19
* This Source Code may also be made available under the following
20
* Secondary Licenses when the conditions for such availability set
21
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
22
* General Public License, version 2 with the GNU Classpath
23
* Exception [1] and GNU General Public License, version 2 with the
24
* OpenJDK Assembly Exception [2].
25
*
26
* [1] https://www.gnu.org/software/classpath/license.html
27
* [2] http://openjdk.java.net/legal/assembly-exception.html
28
*
29
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
30
*******************************************************************************/
31
32
/**
33
* ReferenceQueue is the container on which reference objects
34
* are enqueued when their reachability type is detected for
35
* the referent.
36
*
37
* @author OTI
38
* @version initial
39
* @since 1.2
40
*/
41
42
public class ReferenceQueue<T> extends Object {
43
private Reference[] references;
44
private int head, tail;
45
private boolean empty;
46
47
static private final int DEFAULT_QUEUE_SIZE = 128;
48
49
private static final Class reflectRefClass;
50
51
private static final Class classNameLockRefClass;
52
53
static {
54
/*[PR CMVC 114480] deadlock loading sun.misc.Cleaner */
55
// cause sun.misc.Cleaner to be loaded
56
Class cl = Cleaner.class;
57
/*[PR 125873] Improve reflection cache */
58
Class tmpClass = null;
59
try {
60
tmpClass = Class.forName("java.lang.Class$ReflectRef"); //$NON-NLS-1$
61
} catch (ClassNotFoundException e) {}
62
reflectRefClass = tmpClass;
63
64
Class tmpClass2 = null;
65
try {
66
tmpClass2 = Class.forName("java.lang.ClassLoader$ClassNameLockRef"); //$NON-NLS-1$
67
} catch (ClassNotFoundException e) {}
68
classNameLockRefClass = tmpClass2;
69
}
70
71
/**
72
* Returns the next available reference from the queue
73
* if one is enqueued, null otherwise. Does not wait
74
* for a reference to become available.
75
*
76
* @return Reference
77
* next available Reference or NULL.
78
*/
79
public Reference<? extends T> poll () {
80
Reference ref;
81
82
/* Optimization to return immediately and not synchronize if there is nothing in the queue */
83
if(empty) {
84
return null;
85
}
86
synchronized(this) {
87
if(empty) {
88
return null;
89
}
90
ref = references[head];
91
/*[PR 115652] null References when removed */
92
references[head++] = null;
93
ref.dequeue();
94
if(head == references.length) {
95
head = 0;
96
}
97
if(head == tail) {
98
empty = true;
99
}
100
}
101
return ref;
102
}
103
104
/**
105
* Return the next available enqueued reference on the queue, blocking
106
* indefinitely until one is available.
107
*
108
* @author OTI
109
* @version initial
110
*
111
* @return Reference
112
* a Reference object if one is available,
113
* null otherwise.
114
* @exception InterruptedException
115
* to interrupt the wait.
116
*/
117
public Reference<? extends T> remove() throws InterruptedException {
118
return remove(0L);
119
}
120
121
/**
122
* Return the next available enqueued reference on the queue, blocking
123
* up to the time given until one is available. Return null if no
124
* reference became available.
125
*
126
* @author OTI
127
* @version initial
128
*
129
* @param timeout
130
* maximum time spent waiting for a reference object
131
* to become available.
132
* @return Reference
133
* a Reference object if one is available,
134
* null otherwise.
135
* @exception IllegalArgumentException
136
* if the wait period is negative.
137
* @exception InterruptedException
138
* to interrupt the wait.
139
*/
140
public Reference<? extends T> remove(long timeout) throws IllegalArgumentException, InterruptedException {
141
if (timeout < 0) throw new IllegalArgumentException();
142
143
Reference ref;
144
synchronized(this) {
145
if(empty) {
146
wait(timeout);
147
if(empty) return null;
148
}
149
ref = references[head];
150
/*[PR 115652] null References when removed */
151
references[head++] = null;
152
ref.dequeue();
153
if(head == references.length) {
154
head = 0;
155
}
156
if(head == tail) {
157
empty = true;
158
} else {
159
notifyAll();
160
}
161
}
162
return ref;
163
}
164
165
/**
166
* Enqueue the reference object on the receiver.
167
*
168
* @param reference
169
* reference object to be enqueued.
170
* @return boolean
171
* true if reference is enqueued.
172
* false if reference failed to enqueue.
173
*/
174
boolean enqueue (Reference reference) {
175
/*[PR CMVC 96472] deadlock loading sun.misc.Cleaner */
176
/*[PR 102259] call Cleaner.clean(), do not enqueue */
177
if (reference instanceof Cleaner) {
178
reference.dequeue();
179
((Cleaner)reference).clean();
180
return true;
181
}
182
/*[PR 125873] Improve reflection cache */
183
Class refClass = reference.getClass();
184
if (refClass == reflectRefClass
185
|| refClass == classNameLockRefClass
186
) {
187
reference.dequeue();
188
((Runnable)reference).run();
189
return true;
190
}
191
synchronized(this) {
192
/*[PR CMVC 181985] Perf: zWAS ftprint regressed 6% Java7 vs 626FP1 -ReferenceQueue */
193
if ( references == null) {
194
references = new Reference[DEFAULT_QUEUE_SIZE];
195
} else if(!empty && head == tail) {
196
/* Queue is full - grow */
197
int newQueueSize = (int)(references.length * 1.10);
198
Reference newQueue[] = new Reference[newQueueSize];
199
System.arraycopy(references, head, newQueue, 0, references.length - head);
200
if(tail > 0) {
201
System.arraycopy(references, 0, newQueue, references.length - head, tail);
202
}
203
head = 0;
204
tail = references.length;
205
references = newQueue;
206
}
207
references[tail++] = reference;
208
if(tail == references.length) {
209
tail = 0;
210
}
211
empty = false;
212
notifyAll();
213
}
214
return true;
215
}
216
217
void forEach(java.util.function.Consumer<? super Reference<? extends T>> consumer) {
218
}
219
220
/**
221
* Constructs a new instance of this class.
222
*/
223
public ReferenceQueue() {
224
head = 0;
225
tail = 0;
226
empty = true;
227
}
228
}
229
230