< prev index next >

src/java.base/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java

Print this page
rev 48757 : [mq]: nio-cleanup
   1 /*
   2  * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.nio.channels.spi;
  27 
  28 import java.io.IOException;
  29 import java.nio.channels.*;







  30 
  31 
  32 /**
  33  * Base implementation class for selectable channels.
  34  *
  35  * <p> This class defines methods that handle the mechanics of channel
  36  * registration, deregistration, and closing.  It maintains the current
  37  * blocking mode of this channel as well as its current set of selection keys.
  38  * It performs all of the synchronization required to implement the {@link
  39  * java.nio.channels.SelectableChannel} specification.  Implementations of the
  40  * abstract protected methods defined in this class need not synchronize
  41  * against other threads that might be engaged in the same operations.  </p>
  42  *
  43  *
  44  * @author Mark Reinhold
  45  * @author Mike McCloskey
  46  * @author JSR-51 Expert Group
  47  * @since 1.4
  48  */
  49 
  50 public abstract class AbstractSelectableChannel
  51     extends SelectableChannel
  52 {
  53 
  54     // The provider that created this channel
  55     private final SelectorProvider provider;
  56 
  57     // Keys that have been created by registering this channel with selectors.
  58     // They are saved because if this channel is closed the keys must be
  59     // deregistered.  Protected by keyLock.
  60     //
  61     private SelectionKey[] keys = null;
  62     private int keyCount = 0;
  63 
  64     // Lock for key set and count
  65     private final Object keyLock = new Object();
  66 
  67     // Lock for registration and configureBlocking operations
  68     private final Object regLock = new Object();
  69 
  70     // Blocking mode, protected by regLock
  71     boolean blocking = true;
  72 
  73     /**
  74      * Initializes a new instance of this class.
  75      *
  76      * @param  provider
  77      *         The provider that created this channel
  78      */
  79     protected AbstractSelectableChannel(SelectorProvider provider) {
  80         this.provider = provider;
  81     }
  82 
  83     /**
  84      * Returns the provider that created this channel.
  85      *
  86      * @return  The provider that created this channel
  87      */
  88     public final SelectorProvider provider() {
  89         return provider;
  90     }
  91 


 180      *
 181      * @throws  ClosedSelectorException {@inheritDoc}
 182      *
 183      * @throws  IllegalBlockingModeException {@inheritDoc}
 184      *
 185      * @throws  IllegalSelectorException {@inheritDoc}
 186      *
 187      * @throws  CancelledKeyException {@inheritDoc}
 188      *
 189      * @throws  IllegalArgumentException {@inheritDoc}
 190      */
 191     public final SelectionKey register(Selector sel, int ops,
 192                                        Object att)
 193         throws ClosedChannelException
 194     {
 195         synchronized (regLock) {
 196             if (!isOpen())
 197                 throw new ClosedChannelException();
 198             if ((ops & ~validOps()) != 0)
 199                 throw new IllegalArgumentException();
 200             if (blocking)
 201                 throw new IllegalBlockingModeException();
 202             SelectionKey k = findKey(sel);
 203             if (k != null) {
 204                 k.interestOps(ops);
 205                 k.attach(att);
 206             }
 207             if (k == null) {
 208                 // New registration
 209                 synchronized (keyLock) {
 210                     if (!isOpen())
 211                         throw new ClosedChannelException();
 212                     k = ((AbstractSelector)sel).register(this, ops, att);
 213                     addKey(k);
 214                 }
 215             }
 216             return k;
 217         }
 218     }
 219 
 220 


 247      *
 248      * <p> This method is invoked by the {@link java.nio.channels.Channel#close
 249      * close} method in order to perform the actual work of closing the
 250      * channel.  This method is only invoked if the channel has not yet been
 251      * closed, and it is never invoked more than once.
 252      *
 253      * <p> An implementation of this method must arrange for any other thread
 254      * that is blocked in an I/O operation upon this channel to return
 255      * immediately, either by throwing an exception or by returning normally.
 256      * </p>
 257      *
 258      * @throws  IOException
 259      *          If an I/O error occurs
 260      */
 261     protected abstract void implCloseSelectableChannel() throws IOException;
 262 
 263 
 264     // -- Blocking --
 265 
 266     public final boolean isBlocking() {
 267         synchronized (regLock) {
 268             return blocking;
 269         }
 270     }
 271 
 272     public final Object blockingLock() {
 273         return regLock;
 274     }
 275 
 276     /**
 277      * Adjusts this channel's blocking mode.
 278      *
 279      * <p> If the given blocking mode is different from the current blocking
 280      * mode then this method invokes the {@link #implConfigureBlocking
 281      * implConfigureBlocking} method, while holding the appropriate locks, in
 282      * order to change the mode.  </p>
 283      */
 284     public final SelectableChannel configureBlocking(boolean block)
 285         throws IOException
 286     {
 287         synchronized (regLock) {
 288             if (!isOpen())
 289                 throw new ClosedChannelException();
 290             if (blocking == block)
 291                 return this;
 292             if (block && haveValidKeys())
 293                 throw new IllegalBlockingModeException();
 294             implConfigureBlocking(block);
 295             blocking = block;

 296         }
 297         return this;
 298     }
 299 
 300     /**
 301      * Adjusts this channel's blocking mode.
 302      *
 303      * <p> This method is invoked by the {@link #configureBlocking
 304      * configureBlocking} method in order to perform the actual work of
 305      * changing the blocking mode.  This method is only invoked if the new mode
 306      * is different from the current mode.  </p>
 307      *
 308      * @param  block  If {@code true} then this channel will be placed in
 309      *                blocking mode; if {@code false} then it will be placed
 310      *                non-blocking mode
 311      *
 312      * @throws IOException
 313      *         If an I/O error occurs
 314      */
 315     protected abstract void implConfigureBlocking(boolean block)
   1 /*
   2  * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.nio.channels.spi;
  27 
  28 import java.io.IOException;
  29 import java.nio.channels.CancelledKeyException;
  30 import java.nio.channels.ClosedChannelException;
  31 import java.nio.channels.ClosedSelectorException;
  32 import java.nio.channels.IllegalBlockingModeException;
  33 import java.nio.channels.IllegalSelectorException;
  34 import java.nio.channels.SelectableChannel;
  35 import java.nio.channels.SelectionKey;
  36 import java.nio.channels.Selector;
  37 
  38 
  39 /**
  40  * Base implementation class for selectable channels.
  41  *
  42  * <p> This class defines methods that handle the mechanics of channel
  43  * registration, deregistration, and closing.  It maintains the current
  44  * blocking mode of this channel as well as its current set of selection keys.
  45  * It performs all of the synchronization required to implement the {@link
  46  * java.nio.channels.SelectableChannel} specification.  Implementations of the
  47  * abstract protected methods defined in this class need not synchronize
  48  * against other threads that might be engaged in the same operations.  </p>
  49  *
  50  *
  51  * @author Mark Reinhold
  52  * @author Mike McCloskey
  53  * @author JSR-51 Expert Group
  54  * @since 1.4
  55  */
  56 
  57 public abstract class AbstractSelectableChannel
  58     extends SelectableChannel
  59 {
  60 
  61     // The provider that created this channel
  62     private final SelectorProvider provider;
  63 
  64     // Keys that have been created by registering this channel with selectors.
  65     // They are saved because if this channel is closed the keys must be
  66     // deregistered.  Protected by keyLock.
  67     //
  68     private SelectionKey[] keys = null;
  69     private int keyCount = 0;
  70 
  71     // Lock for key set and count
  72     private final Object keyLock = new Object();
  73 
  74     // Lock for registration and configureBlocking operations
  75     private final Object regLock = new Object();
  76 
  77     // Blocking mode, need regLock to change;
  78     private volatile boolean nonBlocking;
  79 
  80     /**
  81      * Initializes a new instance of this class.
  82      *
  83      * @param  provider
  84      *         The provider that created this channel
  85      */
  86     protected AbstractSelectableChannel(SelectorProvider provider) {
  87         this.provider = provider;
  88     }
  89 
  90     /**
  91      * Returns the provider that created this channel.
  92      *
  93      * @return  The provider that created this channel
  94      */
  95     public final SelectorProvider provider() {
  96         return provider;
  97     }
  98 


 187      *
 188      * @throws  ClosedSelectorException {@inheritDoc}
 189      *
 190      * @throws  IllegalBlockingModeException {@inheritDoc}
 191      *
 192      * @throws  IllegalSelectorException {@inheritDoc}
 193      *
 194      * @throws  CancelledKeyException {@inheritDoc}
 195      *
 196      * @throws  IllegalArgumentException {@inheritDoc}
 197      */
 198     public final SelectionKey register(Selector sel, int ops,
 199                                        Object att)
 200         throws ClosedChannelException
 201     {
 202         synchronized (regLock) {
 203             if (!isOpen())
 204                 throw new ClosedChannelException();
 205             if ((ops & ~validOps()) != 0)
 206                 throw new IllegalArgumentException();
 207             if (isBlocking())
 208                 throw new IllegalBlockingModeException();
 209             SelectionKey k = findKey(sel);
 210             if (k != null) {
 211                 k.interestOps(ops);
 212                 k.attach(att);
 213             }
 214             if (k == null) {
 215                 // New registration
 216                 synchronized (keyLock) {
 217                     if (!isOpen())
 218                         throw new ClosedChannelException();
 219                     k = ((AbstractSelector)sel).register(this, ops, att);
 220                     addKey(k);
 221                 }
 222             }
 223             return k;
 224         }
 225     }
 226 
 227 


 254      *
 255      * <p> This method is invoked by the {@link java.nio.channels.Channel#close
 256      * close} method in order to perform the actual work of closing the
 257      * channel.  This method is only invoked if the channel has not yet been
 258      * closed, and it is never invoked more than once.
 259      *
 260      * <p> An implementation of this method must arrange for any other thread
 261      * that is blocked in an I/O operation upon this channel to return
 262      * immediately, either by throwing an exception or by returning normally.
 263      * </p>
 264      *
 265      * @throws  IOException
 266      *          If an I/O error occurs
 267      */
 268     protected abstract void implCloseSelectableChannel() throws IOException;
 269 
 270 
 271     // -- Blocking --
 272 
 273     public final boolean isBlocking() {
 274         return !nonBlocking;


 275     }
 276 
 277     public final Object blockingLock() {
 278         return regLock;
 279     }
 280 
 281     /**
 282      * Adjusts this channel's blocking mode.
 283      *
 284      * <p> If the given blocking mode is different from the current blocking
 285      * mode then this method invokes the {@link #implConfigureBlocking
 286      * implConfigureBlocking} method, while holding the appropriate locks, in
 287      * order to change the mode.  </p>
 288      */
 289     public final SelectableChannel configureBlocking(boolean block)
 290         throws IOException
 291     {
 292         synchronized (regLock) {
 293             if (!isOpen())
 294                 throw new ClosedChannelException();
 295             boolean blocking = !nonBlocking;
 296             if (block != blocking) {
 297                 if (block && haveValidKeys())
 298                     throw new IllegalBlockingModeException();
 299                 implConfigureBlocking(block);
 300                 nonBlocking = !block;
 301             }
 302         }
 303         return this;
 304     }
 305 
 306     /**
 307      * Adjusts this channel's blocking mode.
 308      *
 309      * <p> This method is invoked by the {@link #configureBlocking
 310      * configureBlocking} method in order to perform the actual work of
 311      * changing the blocking mode.  This method is only invoked if the new mode
 312      * is different from the current mode.  </p>
 313      *
 314      * @param  block  If {@code true} then this channel will be placed in
 315      *                blocking mode; if {@code false} then it will be placed
 316      *                non-blocking mode
 317      *
 318      * @throws IOException
 319      *         If an I/O error occurs
 320      */
 321     protected abstract void implConfigureBlocking(boolean block)
< prev index next >