src/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java

Print this page




  71  * channel then that operation will immediately return, either by throwing an
  72  * exception or by returning normally.  If a thread is interrupted or the
  73  * channel upon which it is blocked is asynchronously closed then the channel's
  74  * {@link #end end} method will throw the appropriate exception.
  75  *
  76  * <p> This class performs the synchronization required to implement the {@link
  77  * java.nio.channels.Channel} specification.  Implementations of the {@link
  78  * #implCloseChannel implCloseChannel} method need not synchronize against
  79  * other threads that might be attempting to close the channel.  </p>
  80  *
  81  *
  82  * @author Mark Reinhold
  83  * @author JSR-51 Expert Group
  84  * @since 1.4
  85  */
  86 
  87 public abstract class AbstractInterruptibleChannel
  88     implements Channel, InterruptibleChannel
  89 {
  90 
  91     private Object closeLock = new Object();
  92     private volatile boolean open = true;
  93 
  94     /**
  95      * Initializes a new instance of this class.
  96      */
  97     protected AbstractInterruptibleChannel() { }
  98 
  99     /**
 100      * Closes this channel.
 101      *
 102      * <p> If the channel has already been closed then this method returns
 103      * immediately.  Otherwise it marks the channel as closed and then invokes
 104      * the {@link #implCloseChannel implCloseChannel} method in order to
 105      * complete the close operation.  </p>
 106      *
 107      * @throws  IOException
 108      *          If an I/O error occurs
 109      */
 110     public final void close() throws IOException {
 111         synchronized (closeLock) {


 125      * more than once.
 126      *
 127      * <p> An implementation of this method must arrange for any other thread
 128      * that is blocked in an I/O operation upon this channel to return
 129      * immediately, either by throwing an exception or by returning normally.
 130      * </p>
 131      *
 132      * @throws  IOException
 133      *          If an I/O error occurs while closing the channel
 134      */
 135     protected abstract void implCloseChannel() throws IOException;
 136 
 137     public final boolean isOpen() {
 138         return open;
 139     }
 140 
 141 
 142     // -- Interruption machinery --
 143 
 144     private Interruptible interruptor;
 145     private volatile boolean interrupted = false;
 146 
 147     /**
 148      * Marks the beginning of an I/O operation that might block indefinitely.
 149      *
 150      * <p> This method should be invoked in tandem with the {@link #end end}
 151      * method, using a <tt>try</tt>&nbsp;...&nbsp;<tt>finally</tt> block as
 152      * shown <a href="#be">above</a>, in order to implement asynchronous
 153      * closing and interruption for this channel.  </p>
 154      */
 155     protected final void begin() {
 156         if (interruptor == null) {
 157             interruptor = new Interruptible() {
 158                     public void interrupt() {
 159                         synchronized (closeLock) {
 160                             if (!open)
 161                                 return;
 162                             interrupted = true;
 163                             open = false;

 164                             try {
 165                                 AbstractInterruptibleChannel.this.implCloseChannel();
 166                             } catch (IOException x) { }
 167                         }
 168                     }};
 169         }
 170         blockedOn(interruptor);
 171         if (Thread.currentThread().isInterrupted())
 172             interruptor.interrupt();

 173     }
 174 
 175     /**
 176      * Marks the end of an I/O operation that might block indefinitely.
 177      *
 178      * <p> This method should be invoked in tandem with the {@link #begin
 179      * begin} method, using a <tt>try</tt>&nbsp;...&nbsp;<tt>finally</tt> block
 180      * as shown <a href="#be">above</a>, in order to implement asynchronous
 181      * closing and interruption for this channel.  </p>
 182      *
 183      * @param  completed
 184      *         <tt>true</tt> if, and only if, the I/O operation completed
 185      *         successfully, that is, had some effect that would be visible to
 186      *         the operation's invoker
 187      *
 188      * @throws  AsynchronousCloseException
 189      *          If the channel was asynchronously closed
 190      *
 191      * @throws  ClosedByInterruptException
 192      *          If the thread blocked in the I/O operation was interrupted
 193      */
 194     protected final void end(boolean completed)
 195         throws AsynchronousCloseException
 196     {
 197         blockedOn(null);
 198         if (completed) {
 199             interrupted = false;
 200             return;

 201         }
 202         if (interrupted) throw new ClosedByInterruptException();
 203         if (!open) throw new AsynchronousCloseException();
 204     }
 205 
 206 
 207     // -- sun.misc.SharedSecrets --
 208     static void blockedOn(Interruptible intr) {         // package-private
 209         sun.misc.SharedSecrets.getJavaLangAccess().blockedOn(Thread.currentThread(),
 210                                                              intr);
 211     }
 212 }


  71  * channel then that operation will immediately return, either by throwing an
  72  * exception or by returning normally.  If a thread is interrupted or the
  73  * channel upon which it is blocked is asynchronously closed then the channel's
  74  * {@link #end end} method will throw the appropriate exception.
  75  *
  76  * <p> This class performs the synchronization required to implement the {@link
  77  * java.nio.channels.Channel} specification.  Implementations of the {@link
  78  * #implCloseChannel implCloseChannel} method need not synchronize against
  79  * other threads that might be attempting to close the channel.  </p>
  80  *
  81  *
  82  * @author Mark Reinhold
  83  * @author JSR-51 Expert Group
  84  * @since 1.4
  85  */
  86 
  87 public abstract class AbstractInterruptibleChannel
  88     implements Channel, InterruptibleChannel
  89 {
  90 
  91     private final Object closeLock = new Object();
  92     private volatile boolean open = true;
  93 
  94     /**
  95      * Initializes a new instance of this class.
  96      */
  97     protected AbstractInterruptibleChannel() { }
  98 
  99     /**
 100      * Closes this channel.
 101      *
 102      * <p> If the channel has already been closed then this method returns
 103      * immediately.  Otherwise it marks the channel as closed and then invokes
 104      * the {@link #implCloseChannel implCloseChannel} method in order to
 105      * complete the close operation.  </p>
 106      *
 107      * @throws  IOException
 108      *          If an I/O error occurs
 109      */
 110     public final void close() throws IOException {
 111         synchronized (closeLock) {


 125      * more than once.
 126      *
 127      * <p> An implementation of this method must arrange for any other thread
 128      * that is blocked in an I/O operation upon this channel to return
 129      * immediately, either by throwing an exception or by returning normally.
 130      * </p>
 131      *
 132      * @throws  IOException
 133      *          If an I/O error occurs while closing the channel
 134      */
 135     protected abstract void implCloseChannel() throws IOException;
 136 
 137     public final boolean isOpen() {
 138         return open;
 139     }
 140 
 141 
 142     // -- Interruption machinery --
 143 
 144     private Interruptible interruptor;
 145     private volatile Thread interrupted;
 146 
 147     /**
 148      * Marks the beginning of an I/O operation that might block indefinitely.
 149      *
 150      * <p> This method should be invoked in tandem with the {@link #end end}
 151      * method, using a <tt>try</tt>&nbsp;...&nbsp;<tt>finally</tt> block as
 152      * shown <a href="#be">above</a>, in order to implement asynchronous
 153      * closing and interruption for this channel.  </p>
 154      */
 155     protected final void begin() {
 156         if (interruptor == null) {
 157             interruptor = new Interruptible() {
 158                     public void interrupt(Thread target) {
 159                         synchronized (closeLock) {
 160                             if (!open)
 161                                 return;

 162                             open = false;
 163                             interrupted = target;
 164                             try {
 165                                 AbstractInterruptibleChannel.this.implCloseChannel();
 166                             } catch (IOException x) { }
 167                         }
 168                     }};
 169         }
 170         blockedOn(interruptor);
 171         Thread me = Thread.currentThread();
 172         if (me.isInterrupted())
 173             interruptor.interrupt(me);
 174     }
 175 
 176     /**
 177      * Marks the end of an I/O operation that might block indefinitely.
 178      *
 179      * <p> This method should be invoked in tandem with the {@link #begin
 180      * begin} method, using a <tt>try</tt>&nbsp;...&nbsp;<tt>finally</tt> block
 181      * as shown <a href="#be">above</a>, in order to implement asynchronous
 182      * closing and interruption for this channel.  </p>
 183      *
 184      * @param  completed
 185      *         <tt>true</tt> if, and only if, the I/O operation completed
 186      *         successfully, that is, had some effect that would be visible to
 187      *         the operation's invoker
 188      *
 189      * @throws  AsynchronousCloseException
 190      *          If the channel was asynchronously closed
 191      *
 192      * @throws  ClosedByInterruptException
 193      *          If the thread blocked in the I/O operation was interrupted
 194      */
 195     protected final void end(boolean completed)
 196         throws AsynchronousCloseException
 197     {
 198         blockedOn(null);
 199         Thread interrupted = this.interrupted;
 200         if (interrupted != null && interrupted == Thread.currentThread()) {
 201             interrupted = null;
 202             throw new ClosedByInterruptException();
 203         }
 204         if (!completed && !open)
 205             throw new AsynchronousCloseException();
 206     }
 207 
 208 
 209     // -- sun.misc.SharedSecrets --
 210     static void blockedOn(Interruptible intr) {         // package-private
 211         sun.misc.SharedSecrets.getJavaLangAccess().blockedOn(Thread.currentThread(),
 212                                                              intr);
 213     }
 214 }