jdk/src/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java
changeset 7177 0113db4feebc
parent 5506 202f599c92aa
child 7668 d4a77089c587
--- 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();
     }