--- a/jdk/src/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java Sat Nov 06 09:11:18 2010 +0800
+++ b/jdk/src/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java Tue Nov 09 18:56:39 2010 +0000
@@ -88,7 +88,7 @@
implements Channel, InterruptibleChannel
{
- private Object closeLock = new Object();
+ private final Object closeLock = new Object();
private volatile boolean open = true;
/**
@@ -142,7 +142,7 @@
// -- Interruption machinery --
private Interruptible interruptor;
- private volatile boolean interrupted = false;
+ private volatile Thread interrupted;
/**
* Marks the beginning of an I/O operation that might block indefinitely.
@@ -155,12 +155,12 @@
protected final void begin() {
if (interruptor == null) {
interruptor = new Interruptible() {
- public void interrupt() {
+ public void interrupt(Thread target) {
synchronized (closeLock) {
if (!open)
return;
- interrupted = true;
open = false;
+ interrupted = target;
try {
AbstractInterruptibleChannel.this.implCloseChannel();
} catch (IOException x) { }
@@ -168,8 +168,9 @@
}};
}
blockedOn(interruptor);
- if (Thread.currentThread().isInterrupted())
- interruptor.interrupt();
+ Thread me = Thread.currentThread();
+ if (me.isInterrupted())
+ interruptor.interrupt(me);
}
/**
@@ -195,12 +196,13 @@
throws AsynchronousCloseException
{
blockedOn(null);
- if (completed) {
- interrupted = false;
- return;
+ Thread interrupted = this.interrupted;
+ if (interrupted != null && interrupted == Thread.currentThread()) {
+ interrupted = null;
+ throw new ClosedByInterruptException();
}
- if (interrupted) throw new ClosedByInterruptException();
- if (!open) throw new AsynchronousCloseException();
+ if (!completed && !open)
+ throw new AsynchronousCloseException();
}