Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/nio/channels/AsynchronousFileChannel/Basic.java
41153 views
1
/*
2
* Copyright (c) 2008, 2010, 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.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
/* @test
25
* @bug 4607272 6822643 6830721 6842687
26
* @summary Unit test for AsynchronousFileChannel
27
* @key randomness
28
*/
29
30
import java.nio.file.*;
31
import java.nio.channels.*;
32
import java.nio.ByteBuffer;
33
import java.io.File;
34
import java.io.IOException;
35
import java.util.*;
36
import java.util.concurrent.*;
37
import java.util.concurrent.atomic.AtomicReference;
38
import static java.nio.file.StandardOpenOption.*;
39
40
public class Basic {
41
42
private static final Random rand = new Random();
43
44
public static void main(String[] args) throws IOException {
45
// create temporary file
46
File blah = File.createTempFile("blah", null);
47
blah.deleteOnExit();
48
49
AsynchronousFileChannel ch = AsynchronousFileChannel
50
.open(blah.toPath(), READ, WRITE);
51
try {
52
// run tests
53
testUsingCompletionHandlers(ch);
54
testUsingWaitOnResult(ch);
55
testInterruptHandlerThread(ch);
56
} finally {
57
ch.close();
58
}
59
60
// run test that expects channel to be closed
61
testClosedChannel(ch);
62
63
// these tests open the file themselves
64
testLocking(blah.toPath());
65
testCustomThreadPool(blah.toPath());
66
testAsynchronousClose(blah.toPath());
67
testCancel(blah.toPath());
68
testTruncate(blah.toPath());
69
70
// eagerly clean-up
71
blah.delete();
72
}
73
74
/*
75
* Generate buffer with random contents
76
* Writes buffer to file using a CompletionHandler to consume the result
77
* of each write operation
78
* Reads file to EOF to a new buffer using a CompletionHandler to consume
79
* the result of each read operation
80
* Compares buffer contents
81
*/
82
static void testUsingCompletionHandlers(AsynchronousFileChannel ch)
83
throws IOException
84
{
85
System.out.println("testUsingCompletionHandlers");
86
87
ch.truncate(0L);
88
89
// generate buffer with random elements and write it to file
90
ByteBuffer src = genBuffer();
91
writeFully(ch, src, 0L);
92
93
// read to EOF or buffer is full
94
ByteBuffer dst = (rand.nextBoolean()) ?
95
ByteBuffer.allocateDirect(src.capacity()) :
96
ByteBuffer.allocate(src.capacity());
97
readAll(ch, dst, 0L);
98
99
// check buffers are the same
100
src.flip();
101
dst.flip();
102
if (!src.equals(dst)) {
103
throw new RuntimeException("Contents differ");
104
}
105
}
106
107
/*
108
* Generate buffer with random contents
109
* Writes buffer to file, invoking the Future's get method to wait for
110
* each write operation to complete
111
* Reads file to EOF to a new buffer, invoking the Future's get method to
112
* wait for each write operation to complete
113
* Compares buffer contents
114
*/
115
static void testUsingWaitOnResult(AsynchronousFileChannel ch)
116
throws IOException
117
{
118
System.out.println("testUsingWaitOnResult");
119
120
ch.truncate(0L);
121
122
// generate buffer
123
ByteBuffer src = genBuffer();
124
125
// write buffer completely to file
126
long position = 0L;
127
while (src.hasRemaining()) {
128
Future<Integer> result = ch.write(src, position);
129
try {
130
int n = result.get();
131
// update position
132
position += n;
133
} catch (ExecutionException x) {
134
throw new RuntimeException(x.getCause());
135
} catch (InterruptedException x) {
136
throw new RuntimeException(x);
137
}
138
}
139
140
// read file into new buffer
141
ByteBuffer dst = (rand.nextBoolean()) ?
142
ByteBuffer.allocateDirect(src.capacity()) :
143
ByteBuffer.allocate(src.capacity());
144
position = 0L;
145
int n;
146
do {
147
Future<Integer> result = ch.read(dst, position);
148
try {
149
n = result.get();
150
151
// update position
152
if (n > 0) position += n;
153
} catch (ExecutionException x) {
154
throw new RuntimeException(x.getCause());
155
} catch (InterruptedException x) {
156
throw new RuntimeException(x);
157
}
158
} while (n > 0);
159
160
// check buffers are the same
161
src.flip();
162
dst.flip();
163
if (!src.equals(dst)) {
164
throw new RuntimeException("Contents differ");
165
}
166
}
167
168
// exercise lock methods
169
static void testLocking(Path file) throws IOException {
170
System.out.println("testLocking");
171
172
AsynchronousFileChannel ch = AsynchronousFileChannel
173
.open(file, READ, WRITE);
174
FileLock fl;
175
try {
176
// test 1 - acquire lock and check that tryLock throws
177
// OverlappingFileLockException
178
try {
179
fl = ch.lock().get();
180
} catch (ExecutionException x) {
181
throw new RuntimeException(x);
182
} catch (InterruptedException x) {
183
throw new RuntimeException("Should not be interrupted");
184
}
185
if (!fl.acquiredBy().equals(ch))
186
throw new RuntimeException("FileLock#acquiredBy returned incorrect channel");
187
try {
188
ch.tryLock();
189
throw new RuntimeException("OverlappingFileLockException expected");
190
} catch (OverlappingFileLockException x) {
191
}
192
fl.release();
193
194
// test 2 - acquire try and check that lock throws OverlappingFileLockException
195
fl = ch.tryLock();
196
if (fl == null)
197
throw new RuntimeException("Unable to acquire lock");
198
try {
199
ch.lock((Void)null, new CompletionHandler<FileLock,Void> () {
200
public void completed(FileLock result, Void att) {
201
}
202
public void failed(Throwable exc, Void att) {
203
}
204
});
205
throw new RuntimeException("OverlappingFileLockException expected");
206
} catch (OverlappingFileLockException x) {
207
}
208
} finally {
209
ch.close();
210
}
211
212
// test 3 - channel is closed so FileLock should no longer be valid
213
if (fl.isValid())
214
throw new RuntimeException("FileLock expected to be invalid");
215
}
216
217
// interrupt should not close channel
218
static void testInterruptHandlerThread(final AsynchronousFileChannel ch) {
219
System.out.println("testInterruptHandlerThread");
220
221
ByteBuffer buf = ByteBuffer.allocateDirect(100);
222
final CountDownLatch latch = new CountDownLatch(1);
223
224
ch.read(buf, 0L, (Void)null, new CompletionHandler<Integer,Void>() {
225
public void completed(Integer result, Void att) {
226
try {
227
Thread.currentThread().interrupt();
228
long size = ch.size();
229
latch.countDown();
230
} catch (IOException x) {
231
x.printStackTrace();
232
}
233
}
234
public void failed(Throwable exc, Void att) {
235
}
236
});
237
238
// wait for handler to complete
239
await(latch);
240
}
241
242
// invoke method on closed channel
243
static void testClosedChannel(AsynchronousFileChannel ch) {
244
System.out.println("testClosedChannel");
245
246
if (ch.isOpen())
247
throw new RuntimeException("Channel should be closed");
248
249
ByteBuffer buf = ByteBuffer.allocateDirect(100);
250
251
// check read fails with ClosedChannelException
252
try {
253
ch.read(buf, 0L).get();
254
throw new RuntimeException("ExecutionException expected");
255
} catch (ExecutionException x) {
256
if (!(x.getCause() instanceof ClosedChannelException))
257
throw new RuntimeException("Cause of ClosedChannelException expected");
258
} catch (InterruptedException x) {
259
}
260
261
// check write fails with ClosedChannelException
262
try {
263
ch.write(buf, 0L).get();
264
throw new RuntimeException("ExecutionException expected");
265
} catch (ExecutionException x) {
266
if (!(x.getCause() instanceof ClosedChannelException))
267
throw new RuntimeException("Cause of ClosedChannelException expected");
268
} catch (InterruptedException x) {
269
}
270
271
// check lock fails with ClosedChannelException
272
try {
273
ch.lock().get();
274
throw new RuntimeException("ExecutionException expected");
275
} catch (ExecutionException x) {
276
if (!(x.getCause() instanceof ClosedChannelException))
277
throw new RuntimeException("Cause of ClosedChannelException expected");
278
} catch (InterruptedException x) {
279
}
280
}
281
282
283
// exercise custom thread pool
284
static void testCustomThreadPool(Path file) throws IOException {
285
System.out.println("testCustomThreadPool");
286
287
// records threads that are created
288
final List<Thread> threads = new ArrayList<Thread>();
289
290
ThreadFactory threadFactory = new ThreadFactory() {
291
@Override
292
public Thread newThread(Runnable r) {
293
Thread t = new Thread(r);
294
t.setDaemon(true);
295
synchronized (threads) {
296
threads.add(t);
297
}
298
return t;
299
}
300
};
301
302
// exercise tests with varied number of threads
303
for (int nThreads=1; nThreads<=5; nThreads++) {
304
synchronized (threads) {
305
threads.clear();
306
}
307
ExecutorService executor = Executors.newFixedThreadPool(nThreads, threadFactory);
308
Set<StandardOpenOption> opts = EnumSet.of(WRITE);
309
AsynchronousFileChannel ch = AsynchronousFileChannel.open(file, opts, executor);
310
try {
311
for (int i=0; i<10; i++) {
312
// do I/O operation to see which thread invokes the completion handler
313
final AtomicReference<Thread> invoker = new AtomicReference<Thread>();
314
final CountDownLatch latch = new CountDownLatch(1);
315
316
ch.write(genBuffer(), 0L, (Void)null, new CompletionHandler<Integer,Void>() {
317
public void completed(Integer result, Void att) {
318
invoker.set(Thread.currentThread());
319
latch.countDown();
320
}
321
public void failed(Throwable exc, Void att) {
322
}
323
});
324
await(latch);
325
326
// check invoker
327
boolean found = false;
328
synchronized (threads) {
329
for (Thread t: threads) {
330
if (t == invoker.get()) {
331
found = true;
332
break;
333
}
334
}
335
}
336
if (!found)
337
throw new RuntimeException("Invoker thread not found");
338
}
339
} finally {
340
ch.close();
341
executor.shutdown();
342
}
343
}
344
345
346
// test sharing a thread pool between many channels
347
ExecutorService executor = Executors
348
.newFixedThreadPool(1+rand.nextInt(10), threadFactory);
349
final int n = 50 + rand.nextInt(50);
350
AsynchronousFileChannel[] channels = new AsynchronousFileChannel[n];
351
try {
352
for (int i=0; i<n; i++) {
353
Set<StandardOpenOption> opts = EnumSet.of(WRITE);
354
channels[i] = AsynchronousFileChannel.open(file, opts, executor);
355
final CountDownLatch latch = new CountDownLatch(1);
356
channels[i].write(genBuffer(), 0L, (Void)null, new CompletionHandler<Integer,Void>() {
357
public void completed(Integer result, Void att) {
358
latch.countDown();
359
}
360
public void failed(Throwable exc, Void att) {
361
}
362
});
363
await(latch);
364
365
// close ~half the channels
366
if (rand.nextBoolean())
367
channels[i].close();
368
}
369
} finally {
370
// close remaining channels
371
for (int i=0; i<n; i++) {
372
if (channels[i] != null) channels[i].close();
373
}
374
executor.shutdown();
375
}
376
}
377
378
// exercise asynchronous close
379
static void testAsynchronousClose(Path file) throws IOException {
380
System.out.println("testAsynchronousClose");
381
382
// create file
383
AsynchronousFileChannel ch = AsynchronousFileChannel
384
.open(file, WRITE, TRUNCATE_EXISTING);
385
long size = 0L;
386
do {
387
ByteBuffer buf = genBuffer();
388
int n = buf.remaining();
389
writeFully(ch, buf, size);
390
size += n;
391
} while (size < (50L * 1024L * 1024L));
392
393
ch.close();
394
395
ch = AsynchronousFileChannel.open(file, WRITE, SYNC);
396
397
// randomize number of writers, buffer size, and positions
398
399
int nwriters = 1 + rand.nextInt(8);
400
ByteBuffer[] buf = new ByteBuffer[nwriters];
401
long[] position = new long[nwriters];
402
for (int i=0; i<nwriters; i++) {
403
buf[i] = genBuffer();
404
position[i] = rand.nextInt((int)size);
405
}
406
407
// initiate I/O
408
Future[] result = new Future[nwriters];
409
for (int i=0; i<nwriters; i++) {
410
result[i] = ch.write(buf[i], position[i]);
411
}
412
413
// close file
414
ch.close();
415
416
// write operations should complete or fail with AsynchronousCloseException
417
for (int i=0; i<nwriters; i++) {
418
try {
419
result[i].get();
420
} catch (ExecutionException x) {
421
Throwable cause = x.getCause();
422
if (!(cause instanceof AsynchronousCloseException))
423
throw new RuntimeException(cause);
424
} catch (CancellationException x) {
425
throw new RuntimeException(x); // should not happen
426
} catch (InterruptedException x) {
427
throw new RuntimeException(x); // should not happen
428
}
429
}
430
}
431
432
// exercise cancel method
433
static void testCancel(Path file) throws IOException {
434
System.out.println("testCancel");
435
436
for (int i=0; i<2; i++) {
437
boolean mayInterruptIfRunning = (i == 0) ? false : true;
438
439
// open with SYNC option to improve chances that write will not
440
// complete immediately
441
AsynchronousFileChannel ch = AsynchronousFileChannel
442
.open(file, WRITE, SYNC);
443
444
// start write operation
445
Future<Integer> res = ch.write(genBuffer(), 0L);
446
447
// cancel operation
448
boolean cancelled = res.cancel(mayInterruptIfRunning);
449
450
// check post-conditions
451
if (!res.isDone())
452
throw new RuntimeException("isDone should return true");
453
if (res.isCancelled() != cancelled)
454
throw new RuntimeException("isCancelled not consistent");
455
try {
456
res.get();
457
if (cancelled)
458
throw new RuntimeException("CancellationException expected");
459
} catch (CancellationException x) {
460
if (!cancelled)
461
throw new RuntimeException("CancellationException not expected");
462
} catch (ExecutionException x) {
463
throw new RuntimeException(x);
464
} catch (InterruptedException x) {
465
throw new RuntimeException(x);
466
}
467
try {
468
res.get(1, TimeUnit.SECONDS);
469
if (cancelled)
470
throw new RuntimeException("CancellationException expected");
471
} catch (CancellationException x) {
472
if (!cancelled)
473
throw new RuntimeException("CancellationException not expected");
474
} catch (ExecutionException x) {
475
throw new RuntimeException(x);
476
} catch (TimeoutException x) {
477
throw new RuntimeException(x);
478
} catch (InterruptedException x) {
479
throw new RuntimeException(x);
480
}
481
482
ch.close();
483
}
484
}
485
486
// exercise truncate method
487
static void testTruncate(Path file) throws IOException {
488
System.out.println("testTruncate");
489
490
// basic tests
491
AsynchronousFileChannel ch = AsynchronousFileChannel
492
.open(file, CREATE, WRITE, TRUNCATE_EXISTING);
493
try {
494
writeFully(ch, genBuffer(), 0L);
495
long size = ch.size();
496
497
// attempt to truncate to a size greater than the current size
498
if (ch.truncate(size + 1L).size() != size)
499
throw new RuntimeException("Unexpected size after truncation");
500
501
// truncate file
502
if (ch.truncate(size - 1L).size() != (size - 1L))
503
throw new RuntimeException("Unexpected size after truncation");
504
505
// invalid size
506
try {
507
ch.truncate(-1L);
508
throw new RuntimeException("IllegalArgumentException expected");
509
} catch (IllegalArgumentException e) { }
510
511
} finally {
512
ch.close();
513
}
514
515
// channel is closed
516
try {
517
ch.truncate(0L);
518
throw new RuntimeException("ClosedChannelException expected");
519
} catch (ClosedChannelException e) { }
520
521
// channel is read-only
522
ch = AsynchronousFileChannel.open(file, READ);
523
try {
524
try {
525
ch.truncate(0L);
526
throw new RuntimeException("NonWritableChannelException expected");
527
} catch (NonWritableChannelException e) { }
528
} finally {
529
ch.close();
530
}
531
}
532
533
// returns ByteBuffer with random bytes
534
static ByteBuffer genBuffer() {
535
int size = 1024 + rand.nextInt(16000);
536
byte[] buf = new byte[size];
537
boolean useDirect = rand.nextBoolean();
538
if (useDirect) {
539
ByteBuffer bb = ByteBuffer.allocateDirect(buf.length);
540
bb.put(buf);
541
bb.flip();
542
return bb;
543
} else {
544
return ByteBuffer.wrap(buf);
545
}
546
}
547
548
// writes all remaining bytes in the buffer to the given channel at the
549
// given position
550
static void writeFully(final AsynchronousFileChannel ch,
551
final ByteBuffer src,
552
long position)
553
{
554
final CountDownLatch latch = new CountDownLatch(1);
555
556
// use position as attachment
557
ch.write(src, position, position, new CompletionHandler<Integer,Long>() {
558
public void completed(Integer result, Long position) {
559
int n = result;
560
if (src.hasRemaining()) {
561
long p = position + n;
562
ch.write(src, p, p, this);
563
} else {
564
latch.countDown();
565
}
566
}
567
public void failed(Throwable exc, Long position) {
568
}
569
});
570
571
// wait for writes to complete
572
await(latch);
573
}
574
575
static void readAll(final AsynchronousFileChannel ch,
576
final ByteBuffer dst,
577
long position)
578
{
579
final CountDownLatch latch = new CountDownLatch(1);
580
581
// use position as attachment
582
ch.read(dst, position, position, new CompletionHandler<Integer,Long>() {
583
public void completed(Integer result, Long position) {
584
int n = result;
585
if (n > 0) {
586
long p = position + n;
587
ch.read(dst, p, p, this);
588
} else {
589
latch.countDown();
590
}
591
}
592
public void failed(Throwable exc, Long position) {
593
}
594
});
595
596
// wait for reads to complete
597
await(latch);
598
}
599
600
static void await(CountDownLatch latch) {
601
// wait until done
602
boolean done = false;
603
while (!done) {
604
try {
605
latch.await();
606
done = true;
607
} catch (InterruptedException x) { }
608
}
609
}
610
}
611
612