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
211 /**
212 * Task that initiates locking operation and handles completion result.
213 */
214 private class LockTask<A> implements Runnable, Iocp.ResultHandler {
215 private final long position;
216 private final FileLockImpl fli;
217 private final PendingFuture<FileLock,A> result;
218
219 LockTask(long position,
220 FileLockImpl fli,
221 PendingFuture<FileLock,A> result)
222 {
223 this.position = position;
224 this.fli = fli;
225 this.result = result;
226 }
227
228 @Override
229 public void run() {
230 long overlapped = 0L;
231 boolean pending = false;
232 try {
233 begin();
234
235 // allocate OVERLAPPED structure
236 overlapped = ioCache.add(result);
237
238 // synchronize on result to avoid race with handler thread
239 // when lock is acquired immediately.
240 synchronized (result) {
241 int n = lockFile(handle, position, fli.size(), fli.isShared(),
242 overlapped);
243 if (n == IOStatus.UNAVAILABLE) {
244 // I/O is pending
245 pending = true;
246 return;
247 }
248 // acquired lock immediately
249 result.setResult(fli);
250 }
251
252 } catch (Throwable x) {
253 // lock failed or channel closed
254 removeFromFileLockTable(fli);
255 result.setFailure(toIOException(x));
256 } finally {
257 if (!pending && overlapped != 0L)
258 ioCache.remove(overlapped);
259 end();
260 }
261
262 // invoke completion handler
263 Invoker.invoke(result);
264 }
265
266 @Override
267 public void completed(int bytesTransferred, boolean canInvokeDirect) {
268 // release waiters and invoke completion handler
269 result.setResult(fli);
270 if (canInvokeDirect) {
271 Invoker.invokeUnchecked(result);
272 } else {
273 Invoker.invoke(result);
274 }
275 }
276
277 @Override
278 public void failed(int error, IOException x) {
431 begin();
432
433 // allocate OVERLAPPED
434 overlapped = ioCache.add(result);
435
436 // initiate read
437 n = readFile(handle, address, rem, position, overlapped);
438 if (n == IOStatus.UNAVAILABLE) {
439 // I/O is pending
440 pending = true;
441 return;
442 } else if (n == IOStatus.EOF) {
443 result.setResult(n);
444 } else {
445 throw new InternalError("Unexpected result: " + n);
446 }
447
448 } catch (Throwable x) {
449 // failed to initiate read
450 result.setFailure(toIOException(x));
451 } finally {
452 if (!pending) {
453 // release resources
454 if (overlapped != 0L)
455 ioCache.remove(overlapped);
456 releaseBufferIfSubstituted();
457 }
458 end();
459 }
460
461 // invoke completion handler
462 Invoker.invoke(result);
463 }
464
465 /**
466 * Executed when the I/O has completed
467 */
468 @Override
469 public void completed(int bytesTransferred, boolean canInvokeDirect) {
470 updatePosition(bytesTransferred);
471
472 // return direct buffer to cache if substituted
473 releaseBufferIfSubstituted();
474
475 // release waiters and invoke completion handler
476 result.setResult(bytesTransferred);
477 if (canInvokeDirect) {
611 try {
612 begin();
613
614 // allocate an OVERLAPPED structure
615 overlapped = ioCache.add(result);
616
617 // initiate the write
618 n = writeFile(handle, address, rem, position, overlapped);
619 if (n == IOStatus.UNAVAILABLE) {
620 // I/O is pending
621 return;
622 } else {
623 throw new InternalError("Unexpected result: " + n);
624 }
625
626 } catch (Throwable x) {
627 // failed to initiate read:
628 result.setFailure(toIOException(x));
629
630 // release resources
631 if (overlapped != 0L)
632 ioCache.remove(overlapped);
633 releaseBufferIfSubstituted();
634
635 } finally {
636 end();
637 }
638
639 // invoke completion handler
640 Invoker.invoke(result);
641 }
642
643 /**
644 * Executed when the I/O has completed
645 */
646 @Override
647 public void completed(int bytesTransferred, boolean canInvokeDirect) {
648 updatePosition(bytesTransferred);
649
650 // return direct buffer to cache if substituted
651 releaseBufferIfSubstituted();
652
653 // release waiters and invoke completion handler
|
1 /*
2 * Copyright (c) 2008, 2019, 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
211 /**
212 * Task that initiates locking operation and handles completion result.
213 */
214 private class LockTask<A> implements Runnable, Iocp.ResultHandler {
215 private final long position;
216 private final FileLockImpl fli;
217 private final PendingFuture<FileLock,A> result;
218
219 LockTask(long position,
220 FileLockImpl fli,
221 PendingFuture<FileLock,A> result)
222 {
223 this.position = position;
224 this.fli = fli;
225 this.result = result;
226 }
227
228 @Override
229 public void run() {
230 long overlapped = 0L;
231 try {
232 begin();
233
234 // allocate OVERLAPPED structure
235 overlapped = ioCache.add(result);
236
237 // synchronize on result to avoid race with handler thread
238 // when lock is acquired immediately.
239 synchronized (result) {
240 int n = lockFile(handle, position, fli.size(), fli.isShared(),
241 overlapped);
242 if (n == IOStatus.UNAVAILABLE) {
243 // I/O is pending
244 return;
245 }
246 // acquired lock immediately
247 result.setResult(fli);
248 }
249
250 } catch (Throwable x) {
251 // lock failed or channel closed
252 removeFromFileLockTable(fli);
253 result.setFailure(toIOException(x));
254 if (overlapped != 0L)
255 ioCache.remove(overlapped);
256 } finally {
257 end();
258 }
259
260 // invoke completion handler
261 Invoker.invoke(result);
262 }
263
264 @Override
265 public void completed(int bytesTransferred, boolean canInvokeDirect) {
266 // release waiters and invoke completion handler
267 result.setResult(fli);
268 if (canInvokeDirect) {
269 Invoker.invokeUnchecked(result);
270 } else {
271 Invoker.invoke(result);
272 }
273 }
274
275 @Override
276 public void failed(int error, IOException x) {
429 begin();
430
431 // allocate OVERLAPPED
432 overlapped = ioCache.add(result);
433
434 // initiate read
435 n = readFile(handle, address, rem, position, overlapped);
436 if (n == IOStatus.UNAVAILABLE) {
437 // I/O is pending
438 pending = true;
439 return;
440 } else if (n == IOStatus.EOF) {
441 result.setResult(n);
442 } else {
443 throw new InternalError("Unexpected result: " + n);
444 }
445
446 } catch (Throwable x) {
447 // failed to initiate read
448 result.setFailure(toIOException(x));
449 if (overlapped != 0L)
450 ioCache.remove(overlapped);
451 } finally {
452 if (!pending)
453 // release resources
454 releaseBufferIfSubstituted();
455 end();
456 }
457
458 // invoke completion handler
459 Invoker.invoke(result);
460 }
461
462 /**
463 * Executed when the I/O has completed
464 */
465 @Override
466 public void completed(int bytesTransferred, boolean canInvokeDirect) {
467 updatePosition(bytesTransferred);
468
469 // return direct buffer to cache if substituted
470 releaseBufferIfSubstituted();
471
472 // release waiters and invoke completion handler
473 result.setResult(bytesTransferred);
474 if (canInvokeDirect) {
608 try {
609 begin();
610
611 // allocate an OVERLAPPED structure
612 overlapped = ioCache.add(result);
613
614 // initiate the write
615 n = writeFile(handle, address, rem, position, overlapped);
616 if (n == IOStatus.UNAVAILABLE) {
617 // I/O is pending
618 return;
619 } else {
620 throw new InternalError("Unexpected result: " + n);
621 }
622
623 } catch (Throwable x) {
624 // failed to initiate read:
625 result.setFailure(toIOException(x));
626
627 // release resources
628 releaseBufferIfSubstituted();
629 if (overlapped != 0L)
630 ioCache.remove(overlapped);
631
632 } finally {
633 end();
634 }
635
636 // invoke completion handler
637 Invoker.invoke(result);
638 }
639
640 /**
641 * Executed when the I/O has completed
642 */
643 @Override
644 public void completed(int bytesTransferred, boolean canInvokeDirect) {
645 updatePosition(bytesTransferred);
646
647 // return direct buffer to cache if substituted
648 releaseBufferIfSubstituted();
649
650 // release waiters and invoke completion handler
|