Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/nio/ch/PendingFuture.java
38918 views
1
/*
2
* Copyright (c) 2008, 2009, 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 sun.nio.ch;
27
28
import java.nio.channels.*;
29
import java.util.concurrent.*;
30
import java.io.IOException;
31
32
/**
33
* A Future for a pending I/O operation. A PendingFuture allows for the
34
* attachment of an additional arbitrary context object and a timer task.
35
*/
36
37
final class PendingFuture<V,A> implements Future<V> {
38
private static final CancellationException CANCELLED =
39
new CancellationException();
40
41
private final AsynchronousChannel channel;
42
private final CompletionHandler<V,? super A> handler;
43
private final A attachment;
44
45
// true if result (or exception) is available
46
private volatile boolean haveResult;
47
private volatile V result;
48
private volatile Throwable exc;
49
50
// latch for waiting (created lazily if needed)
51
private CountDownLatch latch;
52
53
// optional timer task that is cancelled when result becomes available
54
private Future<?> timeoutTask;
55
56
// optional context object
57
private volatile Object context;
58
59
PendingFuture(AsynchronousChannel channel,
60
CompletionHandler<V,? super A> handler,
61
A attachment,
62
Object context)
63
{
64
this.channel = channel;
65
this.handler = handler;
66
this.attachment = attachment;
67
this.context = context;
68
}
69
70
PendingFuture(AsynchronousChannel channel,
71
CompletionHandler<V,? super A> handler,
72
A attachment)
73
{
74
this.channel = channel;
75
this.handler = handler;
76
this.attachment = attachment;
77
}
78
79
PendingFuture(AsynchronousChannel channel) {
80
this(channel, null, null);
81
}
82
83
PendingFuture(AsynchronousChannel channel, Object context) {
84
this(channel, null, null, context);
85
}
86
87
AsynchronousChannel channel() {
88
return channel;
89
}
90
91
CompletionHandler<V,? super A> handler() {
92
return handler;
93
}
94
95
A attachment() {
96
return attachment;
97
}
98
99
void setContext(Object context) {
100
this.context = context;
101
}
102
103
Object getContext() {
104
return context;
105
}
106
107
void setTimeoutTask(Future<?> task) {
108
synchronized (this) {
109
if (haveResult) {
110
task.cancel(false);
111
} else {
112
this.timeoutTask = task;
113
}
114
}
115
}
116
117
// creates latch if required; return true if caller needs to wait
118
private boolean prepareForWait() {
119
synchronized (this) {
120
if (haveResult) {
121
return false;
122
} else {
123
if (latch == null)
124
latch = new CountDownLatch(1);
125
return true;
126
}
127
}
128
}
129
130
/**
131
* Sets the result, or a no-op if the result or exception is already set.
132
*/
133
void setResult(V res) {
134
synchronized (this) {
135
if (haveResult)
136
return;
137
result = res;
138
haveResult = true;
139
if (timeoutTask != null)
140
timeoutTask.cancel(false);
141
if (latch != null)
142
latch.countDown();
143
}
144
}
145
146
/**
147
* Sets the result, or a no-op if the result or exception is already set.
148
*/
149
void setFailure(Throwable x) {
150
if (!(x instanceof IOException) && !(x instanceof SecurityException))
151
x = new IOException(x);
152
synchronized (this) {
153
if (haveResult)
154
return;
155
exc = x;
156
haveResult = true;
157
if (timeoutTask != null)
158
timeoutTask.cancel(false);
159
if (latch != null)
160
latch.countDown();
161
}
162
}
163
164
/**
165
* Sets the result
166
*/
167
void setResult(V res, Throwable x) {
168
if (x == null) {
169
setResult(res);
170
} else {
171
setFailure(x);
172
}
173
}
174
175
@Override
176
public V get() throws ExecutionException, InterruptedException {
177
if (!haveResult) {
178
boolean needToWait = prepareForWait();
179
if (needToWait)
180
latch.await();
181
}
182
if (exc != null) {
183
if (exc == CANCELLED)
184
throw new CancellationException();
185
throw new ExecutionException(exc);
186
}
187
return result;
188
}
189
190
@Override
191
public V get(long timeout, TimeUnit unit)
192
throws ExecutionException, InterruptedException, TimeoutException
193
{
194
if (!haveResult) {
195
boolean needToWait = prepareForWait();
196
if (needToWait)
197
if (!latch.await(timeout, unit)) throw new TimeoutException();
198
}
199
if (exc != null) {
200
if (exc == CANCELLED)
201
throw new CancellationException();
202
throw new ExecutionException(exc);
203
}
204
return result;
205
}
206
207
Throwable exception() {
208
return (exc != CANCELLED) ? exc : null;
209
}
210
211
V value() {
212
return result;
213
}
214
215
@Override
216
public boolean isCancelled() {
217
return (exc == CANCELLED);
218
}
219
220
@Override
221
public boolean isDone() {
222
return haveResult;
223
}
224
225
@Override
226
public boolean cancel(boolean mayInterruptIfRunning) {
227
synchronized (this) {
228
if (haveResult)
229
return false; // already completed
230
231
// notify channel
232
if (channel() instanceof Cancellable)
233
((Cancellable)channel()).onCancel(this);
234
235
// set result and cancel timer
236
exc = CANCELLED;
237
haveResult = true;
238
if (timeoutTask != null)
239
timeoutTask.cancel(false);
240
}
241
242
// close channel if forceful cancel
243
if (mayInterruptIfRunning) {
244
try {
245
channel().close();
246
} catch (IOException ignore) { }
247
}
248
249
// release waiters
250
if (latch != null)
251
latch.countDown();
252
return true;
253
}
254
}
255
256