< prev index next >

src/java.base/share/classes/sun/nio/ch/SelectorImpl.java

Print this page
rev 49242 : [mq]: selector-cleanup
   1 /*
   2  * Copyright (c) 2000, 2017, 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 sun.nio.ch;
  27 
  28 import java.io.IOException;
  29 import java.net.SocketException;
  30 import java.nio.channels.ClosedSelectorException;
  31 import java.nio.channels.IllegalSelectorException;
  32 import java.nio.channels.SelectionKey;
  33 import java.nio.channels.Selector;
  34 import java.nio.channels.spi.AbstractSelectableChannel;
  35 import java.nio.channels.spi.AbstractSelector;
  36 import java.nio.channels.spi.SelectorProvider;
  37 import java.util.Collections;
  38 import java.util.HashSet;
  39 import java.util.Iterator;
  40 import java.util.Set;
  41 
  42 
  43 /**
  44  * Base Selector implementation class.
  45  */
  46 
  47 public abstract class SelectorImpl
  48     extends AbstractSelector
  49 {


  50 
  51     // The set of keys with data ready for an operation
  52     protected Set<SelectionKey> selectedKeys;
  53 
  54     // The set of keys registered with this Selector
  55     protected HashSet<SelectionKey> keys;
  56 
  57     // Public views of the key sets
  58     private Set<SelectionKey> publicKeys;             // Immutable
  59     private Set<SelectionKey> publicSelectedKeys;     // Removal allowed, but not addition
  60 
  61     protected SelectorImpl(SelectorProvider sp) {
  62         super(sp);
  63         keys = new HashSet<>();
  64         selectedKeys = new HashSet<>();
  65         publicKeys = Collections.unmodifiableSet(keys);
  66         publicSelectedKeys = Util.ungrowableSet(selectedKeys);
  67     }
  68 
  69     public Set<SelectionKey> keys() {

  70         if (!isOpen())
  71             throw new ClosedSelectorException();
  72         return publicKeys;
  73     }
  74 
  75     public Set<SelectionKey> selectedKeys() {

  76         if (!isOpen())
  77             throw new ClosedSelectorException();
  78         return publicSelectedKeys;
  79     }
  80 
  81     protected abstract int doSelect(long timeout) throws IOException;
  82 
  83     private int lockAndDoSelect(long timeout) throws IOException {
  84         synchronized (this) {
  85             if (!isOpen())
  86                 throw new ClosedSelectorException();
  87             synchronized (publicKeys) {
  88                 synchronized (publicSelectedKeys) {
  89                     return doSelect(timeout);
  90                 }
  91             }
  92         }
  93     }
  94 
  95     public int select(long timeout)

  96         throws IOException
  97     {
  98         if (timeout < 0)
  99             throw new IllegalArgumentException("Negative timeout");
 100         return lockAndDoSelect((timeout == 0) ? -1 : timeout);
 101     }
 102 
 103     public int select() throws IOException {

 104         return select(0);
 105     }
 106 
 107     public int selectNow() throws IOException {

 108         return lockAndDoSelect(0);
 109     }
 110 
 111     public void implCloseSelector() throws IOException {

 112         wakeup();
 113         synchronized (this) {
 114             synchronized (publicKeys) {
 115                 synchronized (publicSelectedKeys) {
 116                     implClose();
 117                 }
 118             }
 119         }
 120     }
 121 
 122     protected abstract void implClose() throws IOException;
 123 
 124     public void putEventOps(SelectionKeyImpl sk, int ops) { }
 125 

 126     protected final SelectionKey register(AbstractSelectableChannel ch,
 127                                           int ops,
 128                                           Object attachment)
 129     {
 130         if (!(ch instanceof SelChImpl))
 131             throw new IllegalSelectorException();
 132         SelectionKeyImpl k = new SelectionKeyImpl((SelChImpl)ch, this);
 133         k.attach(attachment);
 134         synchronized (publicKeys) {
 135             implRegister(k);
 136         }
 137         k.interestOps(ops);
 138         return k;
 139     }
 140 
 141     protected abstract void implRegister(SelectionKeyImpl ski);
 142 
 143     void processDeregisterQueue() throws IOException {


 144         // Precondition: Synchronized on this, keys, and selectedKeys
 145         Set<SelectionKey> cks = cancelledKeys();
 146         synchronized (cks) {
 147             if (!cks.isEmpty()) {
 148                 Iterator<SelectionKey> i = cks.iterator();
 149                 while (i.hasNext()) {
 150                     SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
 151                     try {
 152                         implDereg(ski);
 153                     } catch (SocketException se) {
 154                         throw new IOException("Error deregistering key", se);
 155                     } finally {
 156                         i.remove();
 157                     }
 158                 }
 159             }
 160         }
 161     }
 162 
 163     protected abstract void implDereg(SelectionKeyImpl ski) throws IOException;
 164 
 165     public abstract Selector wakeup();
 166 
 167 }
   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 sun.nio.ch;
  27 
  28 import java.io.IOException;
  29 import java.net.SocketException;
  30 import java.nio.channels.ClosedSelectorException;
  31 import java.nio.channels.IllegalSelectorException;
  32 import java.nio.channels.SelectionKey;

  33 import java.nio.channels.spi.AbstractSelectableChannel;
  34 import java.nio.channels.spi.AbstractSelector;
  35 import java.nio.channels.spi.SelectorProvider;
  36 import java.util.Collections;
  37 import java.util.HashSet;
  38 import java.util.Iterator;
  39 import java.util.Set;
  40 
  41 
  42 /**
  43  * Base Selector implementation class.
  44  */
  45 
  46 public abstract class SelectorImpl
  47     extends AbstractSelector
  48 {
  49     // The set of keys registered with this Selector
  50     protected final HashSet<SelectionKey> keys;
  51 
  52     // The set of keys with data ready for an operation
  53     protected final Set<SelectionKey> selectedKeys;



  54 
  55     // Public views of the key sets
  56     private final Set<SelectionKey> publicKeys;             // Immutable
  57     private final Set<SelectionKey> publicSelectedKeys;     // Removal allowed, but not addition
  58 
  59     protected SelectorImpl(SelectorProvider sp) {
  60         super(sp);
  61         keys = new HashSet<>();
  62         selectedKeys = new HashSet<>();
  63         publicKeys = Collections.unmodifiableSet(keys);
  64         publicSelectedKeys = Util.ungrowableSet(selectedKeys);
  65     }
  66 
  67     @Override
  68     public final Set<SelectionKey> keys() {
  69         if (!isOpen())
  70             throw new ClosedSelectorException();
  71         return publicKeys;
  72     }
  73 
  74     @Override
  75     public final Set<SelectionKey> selectedKeys() {
  76         if (!isOpen())
  77             throw new ClosedSelectorException();
  78         return publicSelectedKeys;
  79     }
  80     
  81     protected abstract int doSelect(long timeout) throws IOException;
  82 
  83     private int lockAndDoSelect(long timeout) throws IOException {
  84         synchronized (this) {
  85             if (!isOpen())
  86                 throw new ClosedSelectorException();
  87             synchronized (publicKeys) {
  88                 synchronized (publicSelectedKeys) {
  89                     return doSelect(timeout);
  90                 }
  91             }
  92         }
  93     }
  94 
  95     @Override
  96     public final int select(long timeout)
  97         throws IOException
  98     {
  99         if (timeout < 0)
 100             throw new IllegalArgumentException("Negative timeout");
 101         return lockAndDoSelect((timeout == 0) ? -1 : timeout);
 102     }
 103 
 104     @Override
 105     public final int select() throws IOException {
 106         return select(0);
 107     }
 108 
 109     @Override
 110     public final int selectNow() throws IOException {
 111         return lockAndDoSelect(0);
 112     }
 113 
 114     @Override
 115     public final void implCloseSelector() throws IOException {
 116         wakeup();
 117         synchronized (this) {
 118             synchronized (publicKeys) {
 119                 synchronized (publicSelectedKeys) {
 120                     implClose();
 121                 }
 122             }
 123         }
 124     }
 125 
 126     protected abstract void implClose() throws IOException;
 127 
 128     public abstract void putEventOps(SelectionKeyImpl sk, int ops);
 129 
 130     @Override
 131     protected final SelectionKey register(AbstractSelectableChannel ch,
 132                                           int ops,
 133                                           Object attachment)
 134     {
 135         if (!(ch instanceof SelChImpl))
 136             throw new IllegalSelectorException();
 137         SelectionKeyImpl k = new SelectionKeyImpl((SelChImpl)ch, this);
 138         k.attach(attachment);
 139         synchronized (publicKeys) {
 140             implRegister(k);
 141         }
 142         k.interestOps(ops);
 143         return k;
 144     }
 145 
 146     protected abstract void implRegister(SelectionKeyImpl ski);
 147 
 148     protected abstract void implDereg(SelectionKeyImpl ski) throws IOException;
 149 
 150     protected final void processDeregisterQueue() throws IOException {
 151         // Precondition: Synchronized on this, keys, and selectedKeys
 152         Set<SelectionKey> cks = cancelledKeys();
 153         synchronized (cks) {
 154             if (!cks.isEmpty()) {
 155                 Iterator<SelectionKey> i = cks.iterator();
 156                 while (i.hasNext()) {
 157                     SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
 158                     try {
 159                         implDereg(ski);
 160                     } catch (SocketException se) {
 161                         throw new IOException("Error deregistering key", se);
 162                     } finally {
 163                         i.remove();
 164                     }
 165                 }
 166             }
 167         }
 168     }





 169 }
< prev index next >