src/java.base/share/classes/sun/nio/ch/SelectorImpl.java
changeset 58439 b25362cec8ce
parent 50602 ed8de3d0cd28
child 58496 7f34de3cdfe9
equal deleted inserted replaced
58438:1181f58f30e2 58439:b25362cec8ce
     1 /*
     1 /*
     2  * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    31 import java.nio.channels.SelectableChannel;
    31 import java.nio.channels.SelectableChannel;
    32 import java.nio.channels.SelectionKey;
    32 import java.nio.channels.SelectionKey;
    33 import java.nio.channels.spi.AbstractSelectableChannel;
    33 import java.nio.channels.spi.AbstractSelectableChannel;
    34 import java.nio.channels.spi.AbstractSelector;
    34 import java.nio.channels.spi.AbstractSelector;
    35 import java.nio.channels.spi.SelectorProvider;
    35 import java.nio.channels.spi.SelectorProvider;
       
    36 import java.util.ArrayDeque;
    36 import java.util.Collections;
    37 import java.util.Collections;
       
    38 import java.util.Deque;
    37 import java.util.HashSet;
    39 import java.util.HashSet;
    38 import java.util.Iterator;
    40 import java.util.Iterator;
    39 import java.util.Objects;
    41 import java.util.Objects;
    40 import java.util.Set;
    42 import java.util.Set;
    41 import java.util.concurrent.ConcurrentHashMap;
    43 import java.util.concurrent.ConcurrentHashMap;
    44 
    46 
    45 /**
    47 /**
    46  * Base Selector implementation class.
    48  * Base Selector implementation class.
    47  */
    49  */
    48 
    50 
    49 abstract class SelectorImpl
    51 public abstract class SelectorImpl
    50     extends AbstractSelector
    52     extends AbstractSelector
    51 {
    53 {
    52     // The set of keys registered with this Selector
    54     // The set of keys registered with this Selector
    53     private final Set<SelectionKey> keys;
    55     private final Set<SelectionKey> keys;
    54 
    56 
    56     private final Set<SelectionKey> selectedKeys;
    58     private final Set<SelectionKey> selectedKeys;
    57 
    59 
    58     // Public views of the key sets
    60     // Public views of the key sets
    59     private final Set<SelectionKey> publicKeys;             // Immutable
    61     private final Set<SelectionKey> publicKeys;             // Immutable
    60     private final Set<SelectionKey> publicSelectedKeys;     // Removal allowed, but not addition
    62     private final Set<SelectionKey> publicSelectedKeys;     // Removal allowed, but not addition
       
    63 
       
    64     // pending cancelled keys for deregistration
       
    65     private final Deque<SelectionKeyImpl> cancelledKeys = new ArrayDeque<>();
    61 
    66 
    62     // used to check for reentrancy
    67     // used to check for reentrancy
    63     private boolean inSelect;
    68     private boolean inSelect;
    64 
    69 
    65     protected SelectorImpl(SelectorProvider sp) {
    70     protected SelectorImpl(SelectorProvider sp) {
   237      * Removes the key from the selector
   242      * Removes the key from the selector
   238      */
   243      */
   239     protected abstract void implDereg(SelectionKeyImpl ski) throws IOException;
   244     protected abstract void implDereg(SelectionKeyImpl ski) throws IOException;
   240 
   245 
   241     /**
   246     /**
   242      * Invoked by selection operations to process the cancelled-key set
   247      * Queue a cancelled key for the next selection operation
       
   248      */
       
   249     public void cancel(SelectionKeyImpl ski) {
       
   250         synchronized (cancelledKeys) {
       
   251             cancelledKeys.addLast(ski);
       
   252         }
       
   253     }
       
   254 
       
   255     /**
       
   256      * Invoked by selection operations to process the cancelled keys
   243      */
   257      */
   244     protected final void processDeregisterQueue() throws IOException {
   258     protected final void processDeregisterQueue() throws IOException {
   245         assert Thread.holdsLock(this);
   259         assert Thread.holdsLock(this);
   246         assert Thread.holdsLock(publicSelectedKeys);
   260         assert Thread.holdsLock(publicSelectedKeys);
   247 
   261 
   248         Set<SelectionKey> cks = cancelledKeys();
   262         synchronized (cancelledKeys) {
   249         synchronized (cks) {
   263             SelectionKeyImpl ski;
   250             if (!cks.isEmpty()) {
   264             while ((ski = cancelledKeys.pollFirst()) != null) {
   251                 Iterator<SelectionKey> i = cks.iterator();
   265                 // remove the key from the selector
   252                 while (i.hasNext()) {
   266                 implDereg(ski);
   253                     SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
   267 
   254                     i.remove();
   268                 selectedKeys.remove(ski);
   255 
   269                 keys.remove(ski);
   256                     // remove the key from the selector
   270 
   257                     implDereg(ski);
   271                 // remove from channel's key set
   258 
   272                 deregister(ski);
   259                     selectedKeys.remove(ski);
   273 
   260                     keys.remove(ski);
   274                 SelectableChannel ch = ski.channel();
   261 
   275                 if (!ch.isOpen() && !ch.isRegistered())
   262                     // remove from channel's key set
   276                     ((SelChImpl)ch).kill();
   263                     deregister(ski);
       
   264 
       
   265                     SelectableChannel ch = ski.channel();
       
   266                     if (!ch.isOpen() && !ch.isRegistered())
       
   267                         ((SelChImpl)ch).kill();
       
   268                 }
       
   269             }
   277             }
   270         }
   278         }
   271     }
   279     }
   272 
   280 
   273     /**
   281     /**