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/SimpleAsynchronousFileChannelImpl.java
41159 views
1
/*
2
* Copyright (c) 2008, 2013, 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.nio.ByteBuffer;
31
import java.security.AccessController;
32
import java.security.PrivilegedAction;
33
import java.io.FileDescriptor;
34
import java.io.IOException;
35
36
/**
37
* "Portable" implementation of AsynchronousFileChannel for use on operating
38
* systems that don't support asynchronous file I/O.
39
*/
40
41
public class SimpleAsynchronousFileChannelImpl
42
extends AsynchronousFileChannelImpl
43
{
44
// lazy initialization of default thread pool for file I/O
45
private static class DefaultExecutorHolder {
46
static final ExecutorService defaultExecutor =
47
ThreadPool.createDefault().executor();
48
}
49
50
// Used to make native read and write calls
51
private static final FileDispatcher nd = new FileDispatcherImpl();
52
53
// Thread-safe set of IDs of native threads, for signalling
54
private final NativeThreadSet threads = new NativeThreadSet(2);
55
56
57
SimpleAsynchronousFileChannelImpl(FileDescriptor fdObj,
58
boolean reading,
59
boolean writing,
60
ExecutorService executor)
61
{
62
super(fdObj, reading, writing, executor);
63
}
64
65
public static AsynchronousFileChannel open(FileDescriptor fdo,
66
boolean reading,
67
boolean writing,
68
ThreadPool pool)
69
{
70
// Executor is either default or based on pool parameters
71
ExecutorService executor = (pool == null) ?
72
DefaultExecutorHolder.defaultExecutor : pool.executor();
73
return new SimpleAsynchronousFileChannelImpl(fdo, reading, writing, executor);
74
}
75
76
@Override
77
public void close() throws IOException {
78
// mark channel as closed
79
synchronized (fdObj) {
80
if (closed)
81
return; // already closed
82
closed = true;
83
// from this point on, if another thread invokes the begin() method
84
// then it will throw ClosedChannelException
85
}
86
87
// Invalidate and release any locks that we still hold
88
invalidateAllLocks();
89
90
// signal any threads blocked on this channel
91
threads.signalAndWait();
92
93
// wait until all async I/O operations have completely gracefully
94
closeLock.writeLock().lock();
95
try {
96
// do nothing
97
} finally {
98
closeLock.writeLock().unlock();
99
}
100
101
// close file
102
nd.close(fdObj);
103
}
104
105
@Override
106
public long size() throws IOException {
107
int ti = threads.add();
108
try {
109
long n = 0L;
110
try {
111
begin();
112
do {
113
n = nd.size(fdObj);
114
} while ((n == IOStatus.INTERRUPTED) && isOpen());
115
return n;
116
} finally {
117
end(n >= 0L);
118
}
119
} finally {
120
threads.remove(ti);
121
}
122
}
123
124
@Override
125
public AsynchronousFileChannel truncate(long size) throws IOException {
126
if (size < 0L)
127
throw new IllegalArgumentException("Negative size");
128
if (!writing)
129
throw new NonWritableChannelException();
130
int ti = threads.add();
131
try {
132
long n = 0L;
133
try {
134
begin();
135
do {
136
n = nd.size(fdObj);
137
} while ((n == IOStatus.INTERRUPTED) && isOpen());
138
139
// truncate file if 'size' less than current size
140
if (size < n && isOpen()) {
141
do {
142
n = nd.truncate(fdObj, size);
143
} while ((n == IOStatus.INTERRUPTED) && isOpen());
144
}
145
return this;
146
} finally {
147
end(n > 0);
148
}
149
} finally {
150
threads.remove(ti);
151
}
152
}
153
154
@Override
155
public void force(boolean metaData) throws IOException {
156
int ti = threads.add();
157
try {
158
int n = 0;
159
try {
160
begin();
161
do {
162
n = nd.force(fdObj, metaData);
163
} while ((n == IOStatus.INTERRUPTED) && isOpen());
164
} finally {
165
end(n >= 0);
166
}
167
} finally {
168
threads.remove(ti);
169
}
170
}
171
172
@Override
173
<A> Future<FileLock> implLock(final long position,
174
final long size,
175
final boolean shared,
176
final A attachment,
177
final CompletionHandler<FileLock,? super A> handler)
178
{
179
if (shared && !reading)
180
throw new NonReadableChannelException();
181
if (!shared && !writing)
182
throw new NonWritableChannelException();
183
184
// add to lock table
185
final FileLockImpl fli = addToFileLockTable(position, size, shared);
186
if (fli == null) {
187
Throwable exc = new ClosedChannelException();
188
if (handler == null)
189
return CompletedFuture.withFailure(exc);
190
Invoker.invokeIndirectly(handler, attachment, null, exc, executor);
191
return null;
192
}
193
194
final PendingFuture<FileLock,A> result = (handler == null) ?
195
new PendingFuture<FileLock,A>(this) : null;
196
Runnable task = new Runnable() {
197
public void run() {
198
Throwable exc = null;
199
200
int ti = threads.add();
201
try {
202
int n;
203
try {
204
begin();
205
do {
206
n = nd.lock(fdObj, true, position, size, shared);
207
} while ((n == FileDispatcher.INTERRUPTED) && isOpen());
208
if (n != FileDispatcher.LOCKED || !isOpen()) {
209
throw new AsynchronousCloseException();
210
}
211
} catch (IOException x) {
212
removeFromFileLockTable(fli);
213
if (!isOpen())
214
x = new AsynchronousCloseException();
215
exc = x;
216
} finally {
217
end();
218
}
219
} finally {
220
threads.remove(ti);
221
}
222
if (handler == null) {
223
result.setResult(fli, exc);
224
} else {
225
Invoker.invokeUnchecked(handler, attachment, fli, exc);
226
}
227
}
228
};
229
boolean executed = false;
230
try {
231
executor.execute(task);
232
executed = true;
233
} finally {
234
if (!executed) {
235
// rollback
236
removeFromFileLockTable(fli);
237
}
238
}
239
return result;
240
}
241
242
@Override
243
public FileLock tryLock(long position, long size, boolean shared)
244
throws IOException
245
{
246
if (shared && !reading)
247
throw new NonReadableChannelException();
248
if (!shared && !writing)
249
throw new NonWritableChannelException();
250
251
// add to lock table
252
FileLockImpl fli = addToFileLockTable(position, size, shared);
253
if (fli == null)
254
throw new ClosedChannelException();
255
256
int ti = threads.add();
257
boolean gotLock = false;
258
try {
259
begin();
260
int n;
261
do {
262
n = nd.lock(fdObj, false, position, size, shared);
263
} while ((n == FileDispatcher.INTERRUPTED) && isOpen());
264
if (n == FileDispatcher.LOCKED && isOpen()) {
265
gotLock = true;
266
return fli; // lock acquired
267
}
268
if (n == FileDispatcher.NO_LOCK)
269
return null; // locked by someone else
270
if (n == FileDispatcher.INTERRUPTED)
271
throw new AsynchronousCloseException();
272
// should not get here
273
throw new AssertionError();
274
} finally {
275
if (!gotLock)
276
removeFromFileLockTable(fli);
277
end();
278
threads.remove(ti);
279
}
280
}
281
282
@Override
283
protected void implRelease(FileLockImpl fli) throws IOException {
284
nd.release(fdObj, fli.position(), fli.size());
285
}
286
287
@Override
288
<A> Future<Integer> implRead(final ByteBuffer dst,
289
final long position,
290
final A attachment,
291
final CompletionHandler<Integer,? super A> handler)
292
{
293
if (position < 0)
294
throw new IllegalArgumentException("Negative position");
295
if (!reading)
296
throw new NonReadableChannelException();
297
if (dst.isReadOnly())
298
throw new IllegalArgumentException("Read-only buffer");
299
300
// complete immediately if channel closed or no space remaining
301
if (!isOpen() || (dst.remaining() == 0)) {
302
Throwable exc = (isOpen()) ? null : new ClosedChannelException();
303
if (handler == null)
304
return CompletedFuture.withResult(0, exc);
305
Invoker.invokeIndirectly(handler, attachment, 0, exc, executor);
306
return null;
307
}
308
309
final PendingFuture<Integer,A> result = (handler == null) ?
310
new PendingFuture<Integer,A>(this) : null;
311
Runnable task = new Runnable() {
312
public void run() {
313
int n = 0;
314
Throwable exc = null;
315
316
int ti = threads.add();
317
try {
318
begin();
319
do {
320
n = IOUtil.read(fdObj, dst, position, nd);
321
} while ((n == IOStatus.INTERRUPTED) && isOpen());
322
if (n < 0 && !isOpen())
323
throw new AsynchronousCloseException();
324
} catch (IOException x) {
325
if (!isOpen())
326
x = new AsynchronousCloseException();
327
exc = x;
328
} finally {
329
end();
330
threads.remove(ti);
331
}
332
if (handler == null) {
333
result.setResult(n, exc);
334
} else {
335
Invoker.invokeUnchecked(handler, attachment, n, exc);
336
}
337
}
338
};
339
executor.execute(task);
340
return result;
341
}
342
343
@Override
344
<A> Future<Integer> implWrite(final ByteBuffer src,
345
final long position,
346
final A attachment,
347
final CompletionHandler<Integer,? super A> handler)
348
{
349
if (position < 0)
350
throw new IllegalArgumentException("Negative position");
351
if (!writing)
352
throw new NonWritableChannelException();
353
354
// complete immediately if channel is closed or no bytes remaining
355
if (!isOpen() || (src.remaining() == 0)) {
356
Throwable exc = (isOpen()) ? null : new ClosedChannelException();
357
if (handler == null)
358
return CompletedFuture.withResult(0, exc);
359
Invoker.invokeIndirectly(handler, attachment, 0, exc, executor);
360
return null;
361
}
362
363
final PendingFuture<Integer,A> result = (handler == null) ?
364
new PendingFuture<Integer,A>(this) : null;
365
Runnable task = new Runnable() {
366
public void run() {
367
int n = 0;
368
Throwable exc = null;
369
370
int ti = threads.add();
371
try {
372
begin();
373
do {
374
n = IOUtil.write(fdObj, src, position, nd);
375
} while ((n == IOStatus.INTERRUPTED) && isOpen());
376
if (n < 0 && !isOpen())
377
throw new AsynchronousCloseException();
378
} catch (IOException x) {
379
if (!isOpen())
380
x = new AsynchronousCloseException();
381
exc = x;
382
} finally {
383
end();
384
threads.remove(ti);
385
}
386
if (handler == null) {
387
result.setResult(n, exc);
388
} else {
389
Invoker.invokeUnchecked(handler, attachment, n, exc);
390
}
391
}
392
};
393
executor.execute(task);
394
return result;
395
}
396
}
397
398