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