src/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java
Print this page
@@ -86,11 +86,11 @@
public abstract class AbstractInterruptibleChannel
implements Channel, InterruptibleChannel
{
- private Object closeLock = new Object();
+ private final Object closeLock = new Object();
private volatile boolean open = true;
/**
* Initializes a new instance of this class.
*/
@@ -140,11 +140,11 @@
// -- 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.
*
* <p> This method should be invoked in tandem with the {@link #end end}
@@ -153,25 +153,26 @@
* closing and interruption for this channel. </p>
*/
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) { }
}
}};
}
blockedOn(interruptor);
- if (Thread.currentThread().isInterrupted())
- interruptor.interrupt();
+ Thread me = Thread.currentThread();
+ if (me.isInterrupted())
+ interruptor.interrupt(me);
}
/**
* Marks the end of an I/O operation that might block indefinitely.
*
@@ -193,16 +194,17 @@
*/
protected final void end(boolean completed)
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();
}
// -- sun.misc.SharedSecrets --
static void blockedOn(Interruptible intr) { // package-private