src/java.base/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java
changeset 49802 8ac08fa69f00
parent 48761 74c1fa26435a
child 59146 455612b3161a
equal deleted inserted replaced
49801:466d4df248a6 49802:8ac08fa69f00
   106             // Find empty element of key array
   106             // Find empty element of key array
   107             for (i = 0; i < keys.length; i++)
   107             for (i = 0; i < keys.length; i++)
   108                 if (keys[i] == null)
   108                 if (keys[i] == null)
   109                     break;
   109                     break;
   110         } else if (keys == null) {
   110         } else if (keys == null) {
   111             keys =  new SelectionKey[3];
   111             keys = new SelectionKey[2];
   112         } else {
   112         } else {
   113             // Grow key array
   113             // Grow key array
   114             int n = keys.length * 2;
   114             int n = keys.length * 2;
   115             SelectionKey[] ks =  new SelectionKey[n];
   115             SelectionKey[] ks =  new SelectionKey[n];
   116             for (i = 0; i < keys.length; i++)
   116             for (i = 0; i < keys.length; i++)
   121         keys[i] = k;
   121         keys[i] = k;
   122         keyCount++;
   122         keyCount++;
   123     }
   123     }
   124 
   124 
   125     private SelectionKey findKey(Selector sel) {
   125     private SelectionKey findKey(Selector sel) {
   126         synchronized (keyLock) {
   126         assert Thread.holdsLock(keyLock);
   127             if (keys == null)
   127         if (keys == null)
   128                 return null;
       
   129             for (int i = 0; i < keys.length; i++)
       
   130                 if ((keys[i] != null) && (keys[i].selector() == sel))
       
   131                     return keys[i];
       
   132             return null;
   128             return null;
   133         }
   129         for (int i = 0; i < keys.length; i++)
       
   130             if ((keys[i] != null) && (keys[i].selector() == sel))
       
   131                 return keys[i];
       
   132         return null;
       
   133 
   134     }
   134     }
   135 
   135 
   136     void removeKey(SelectionKey k) {                    // package-private
   136     void removeKey(SelectionKey k) {                    // package-private
   137         synchronized (keyLock) {
   137         synchronized (keyLock) {
   138             for (int i = 0; i < keys.length; i++)
   138             for (int i = 0; i < keys.length; i++)
   164             return keyCount != 0;
   164             return keyCount != 0;
   165         }
   165         }
   166     }
   166     }
   167 
   167 
   168     public final SelectionKey keyFor(Selector sel) {
   168     public final SelectionKey keyFor(Selector sel) {
   169         return findKey(sel);
   169         synchronized (keyLock) {
       
   170             return findKey(sel);
       
   171         }
   170     }
   172     }
   171 
   173 
   172     /**
   174     /**
   173      * Registers this channel with the given selector, returning a selection key.
   175      * Registers this channel with the given selector, returning a selection key.
   174      *
   176      *
   193      *
   195      *
   194      * @throws  CancelledKeyException {@inheritDoc}
   196      * @throws  CancelledKeyException {@inheritDoc}
   195      *
   197      *
   196      * @throws  IllegalArgumentException {@inheritDoc}
   198      * @throws  IllegalArgumentException {@inheritDoc}
   197      */
   199      */
   198     public final SelectionKey register(Selector sel, int ops,
   200     public final SelectionKey register(Selector sel, int ops, Object att)
   199                                        Object att)
       
   200         throws ClosedChannelException
   201         throws ClosedChannelException
   201     {
   202     {
       
   203         if ((ops & ~validOps()) != 0)
       
   204             throw new IllegalArgumentException();
       
   205         if (!isOpen())
       
   206             throw new ClosedChannelException();
   202         synchronized (regLock) {
   207         synchronized (regLock) {
   203             if (!isOpen())
       
   204                 throw new ClosedChannelException();
       
   205             if ((ops & ~validOps()) != 0)
       
   206                 throw new IllegalArgumentException();
       
   207             if (isBlocking())
   208             if (isBlocking())
   208                 throw new IllegalBlockingModeException();
   209                 throw new IllegalBlockingModeException();
   209             SelectionKey k = findKey(sel);
   210             synchronized (keyLock) {
   210             if (k != null) {
   211                 // re-check if channel has been closed
   211                 k.interestOps(ops);
   212                 if (!isOpen())
   212                 k.attach(att);
   213                     throw new ClosedChannelException();
   213             }
   214                 SelectionKey k = findKey(sel);
   214             if (k == null) {
   215                 if (k != null) {
   215                 // New registration
   216                     k.attach(att);
   216                 synchronized (keyLock) {
   217                     k.interestOps(ops);
   217                     if (!isOpen())
   218                 } else {
   218                         throw new ClosedChannelException();
   219                     // New registration
   219                     k = ((AbstractSelector)sel).register(this, ops, att);
   220                     k = ((AbstractSelector)sel).register(this, ops, att);
   220                     addKey(k);
   221                     addKey(k);
   221                 }
   222                 }
   222             }
   223                 return k;
   223             return k;
   224             }
   224         }
   225         }
   225     }
   226     }
   226 
   227 
   227 
   228 
   228     // -- Closing --
   229     // -- Closing --
   237      * order to perform the actual work of closing this channel.  It then
   238      * order to perform the actual work of closing this channel.  It then
   238      * cancels all of this channel's keys.  </p>
   239      * cancels all of this channel's keys.  </p>
   239      */
   240      */
   240     protected final void implCloseChannel() throws IOException {
   241     protected final void implCloseChannel() throws IOException {
   241         implCloseSelectableChannel();
   242         implCloseSelectableChannel();
   242         synchronized (keyLock) {
   243 
   243             int count = (keys == null) ? 0 : keys.length;
   244         // clone keys to avoid calling cancel when holding keyLock
   244             for (int i = 0; i < count; i++) {
   245         SelectionKey[] copyOfKeys = null;
   245                 SelectionKey k = keys[i];
   246         synchronized (keyLock) {
   246                 if (k != null)
   247             if (keys != null) {
   247                     k.cancel();
   248                 copyOfKeys = keys.clone();
       
   249             }
       
   250         }
       
   251 
       
   252         if (copyOfKeys != null) {
       
   253             for (SelectionKey k : copyOfKeys) {
       
   254                 if (k != null) {
       
   255                     k.cancel();   // invalidate and adds key to cancelledKey set
       
   256                 }
   248             }
   257             }
   249         }
   258         }
   250     }
   259     }
   251 
   260 
   252     /**
   261     /**