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