< prev index next >

src/java.base/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java

Print this page


   1 /*
   2  * Copyright (c) 2011, 2015, 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 /*
  27  * KQueueSelectorImpl.java
  28  * Implementation of Selector using FreeBSD / Mac OS X kqueues
  29  * Derived from Sun's DevPollSelectorImpl
  30  */
  31 
  32 package sun.nio.ch;
  33 
  34 import java.io.IOException;
  35 import java.io.FileDescriptor;
  36 import java.nio.channels.*;
  37 import java.nio.channels.spi.*;
  38 import java.util.*;
  39 
  40 class KQueueSelectorImpl
  41     extends SelectorImpl
  42 {
  43     // File descriptors used for interrupt
  44     protected int fd0;
  45     protected int fd1;
  46 
  47     // The kqueue manipulator
  48     KQueueArrayWrapper kqueueWrapper;
  49 
  50     // Count of registered descriptors (including interrupt)
  51     private int totalChannels;
  52 
  53     // Map from a file descriptor to an entry containing the selection key
  54     private HashMap<Integer,MapEntry> fdMap;
  55 
  56     // True if this Selector has been closed
  57     private boolean closed = false;
  58 
  59     // Lock for interrupt triggering and clearing
  60     private Object interruptLock = new Object();
  61     private boolean interruptTriggered = false;
  62 
  63     // used by updateSelectedKeys to handle cases where the same file
  64     // descriptor is polled by more than one filter
  65     private long updateCount;
  66 
  67     // Used to map file descriptors to a selection key and "update count"
  68     // (see updateSelectedKeys for usage).
  69     private static class MapEntry {
  70         SelectionKeyImpl ski;
  71         long updateCount;
  72         MapEntry(SelectionKeyImpl ski) {
  73             this.ski = ski;
  74         }
  75     }
  76 
  77     /**
  78      * Package private constructor called by factory method in
  79      * the abstract superclass Selector.
  80      */
  81     KQueueSelectorImpl(SelectorProvider sp) {
  82         super(sp);
  83         long fds = IOUtil.makePipe(false);
  84         fd0 = (int)(fds >>> 32);
  85         fd1 = (int)fds;
  86         try {
  87             kqueueWrapper = new KQueueArrayWrapper();
  88             kqueueWrapper.initInterrupt(fd0, fd1);
  89             fdMap = new HashMap<>();
  90             totalChannels = 1;


 182             }
 183         }
 184         return numKeysUpdated;
 185     }
 186 
 187 
 188     protected void implClose() throws IOException {
 189         if (!closed) {
 190             closed = true;
 191 
 192             // prevent further wakeup
 193             synchronized (interruptLock) {
 194                 interruptTriggered = true;
 195             }
 196 
 197             FileDispatcherImpl.closeIntFD(fd0);
 198             FileDispatcherImpl.closeIntFD(fd1);
 199             if (kqueueWrapper != null) {
 200                 kqueueWrapper.close();
 201                 kqueueWrapper = null;
 202                 selectedKeys = null;
 203 
 204                 // Deregister channels
 205                 Iterator<SelectionKey> i = keys.iterator();
 206                 while (i.hasNext()) {
 207                     SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
 208                     deregister(ski);
 209                     SelectableChannel selch = ski.channel();
 210                     if (!selch.isOpen() && !selch.isRegistered())
 211                         ((SelChImpl)selch).kill();
 212                     i.remove();
 213                 }
 214                 totalChannels = 0;
 215             }
 216             fd0 = -1;
 217             fd1 = -1;
 218         }
 219     }
 220 
 221 
 222     protected void implRegister(SelectionKeyImpl ski) {
 223         if (closed)
 224             throw new ClosedSelectorException();
 225         int fd = IOUtil.fdVal(ski.channel.getFD());
 226         fdMap.put(Integer.valueOf(fd), new MapEntry(ski));
 227         totalChannels++;
 228         keys.add(ski);
 229     }
 230 
 231 
 232     protected void implDereg(SelectionKeyImpl ski) throws IOException {
 233         int fd = ski.channel.getFDVal();
 234         fdMap.remove(Integer.valueOf(fd));
 235         kqueueWrapper.release(ski.channel);
 236         totalChannels--;
 237         keys.remove(ski);
 238         selectedKeys.remove(ski);
 239         deregister((AbstractSelectionKey)ski);
 240         SelectableChannel selch = ski.channel();
 241         if (!selch.isOpen() && !selch.isRegistered())
 242             ((SelChImpl)selch).kill();
 243     }
 244 
 245 
 246     public void putEventOps(SelectionKeyImpl ski, int ops) {
 247         if (closed)
 248             throw new ClosedSelectorException();
 249         kqueueWrapper.setInterest(ski.channel, ops);
 250     }
 251 
 252 
 253     public Selector wakeup() {
 254         synchronized (interruptLock) {
 255             if (!interruptTriggered) {
 256                 kqueueWrapper.interrupt();
 257                 interruptTriggered = true;
 258             }
 259         }
   1 /*
   2  * Copyright (c) 2011, 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 /*
  27  * KQueueSelectorImpl.java
  28  * Implementation of Selector using FreeBSD / Mac OS X kqueues
  29  * Derived from Sun's DevPollSelectorImpl
  30  */
  31 
  32 package sun.nio.ch;
  33 
  34 import java.io.IOException;

  35 import java.nio.channels.*;
  36 import java.nio.channels.spi.*;
  37 import java.util.*;
  38 
  39 class KQueueSelectorImpl
  40     extends SelectorImpl
  41 {
  42     // File descriptors used for interrupt
  43     protected int fd0;
  44     protected int fd1;
  45 
  46     // The kqueue manipulator
  47     KQueueArrayWrapper kqueueWrapper;
  48 
  49     // Count of registered descriptors (including interrupt)
  50     private int totalChannels;
  51 
  52     // Map from a file descriptor to an entry containing the selection key
  53     private final HashMap<Integer,MapEntry> fdMap;
  54 
  55     // True if this Selector has been closed
  56     private boolean closed = false;
  57 
  58     // Lock for interrupt triggering and clearing
  59     private final Object interruptLock = new Object();
  60     private boolean interruptTriggered = false;
  61 
  62     // used by updateSelectedKeys to handle cases where the same file
  63     // descriptor is polled by more than one filter
  64     private long updateCount;
  65 
  66     // Used to map file descriptors to a selection key and "update count"
  67     // (see updateSelectedKeys for usage).
  68     private static class MapEntry {
  69         final SelectionKeyImpl ski;
  70         long updateCount;
  71         MapEntry(SelectionKeyImpl ski) {
  72             this.ski = ski;
  73         }
  74     }
  75 
  76     /**
  77      * Package private constructor called by factory method in
  78      * the abstract superclass Selector.
  79      */
  80     KQueueSelectorImpl(SelectorProvider sp) {
  81         super(sp);
  82         long fds = IOUtil.makePipe(false);
  83         fd0 = (int)(fds >>> 32);
  84         fd1 = (int)fds;
  85         try {
  86             kqueueWrapper = new KQueueArrayWrapper();
  87             kqueueWrapper.initInterrupt(fd0, fd1);
  88             fdMap = new HashMap<>();
  89             totalChannels = 1;


 181             }
 182         }
 183         return numKeysUpdated;
 184     }
 185 
 186 
 187     protected void implClose() throws IOException {
 188         if (!closed) {
 189             closed = true;
 190 
 191             // prevent further wakeup
 192             synchronized (interruptLock) {
 193                 interruptTriggered = true;
 194             }
 195 
 196             FileDispatcherImpl.closeIntFD(fd0);
 197             FileDispatcherImpl.closeIntFD(fd1);
 198             if (kqueueWrapper != null) {
 199                 kqueueWrapper.close();
 200                 kqueueWrapper = null;
 201                 selectedKeys.clear();
 202 
 203                 // Deregister channels
 204                 Iterator<SelectionKey> i = keys.iterator();
 205                 while (i.hasNext()) {
 206                     SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
 207                     deregister(ski);
 208                     SelectableChannel selch = ski.channel();
 209                     if (!selch.isOpen() && !selch.isRegistered())
 210                         ((SelChImpl)selch).kill();
 211                     i.remove();
 212                 }
 213                 totalChannels = 0;
 214             }
 215             fd0 = -1;
 216             fd1 = -1;
 217         }
 218     }
 219 
 220 
 221     protected void implRegister(SelectionKeyImpl ski) {
 222         if (closed)
 223             throw new ClosedSelectorException();
 224         int fd = IOUtil.fdVal(ski.channel.getFD());
 225         fdMap.put(Integer.valueOf(fd), new MapEntry(ski));
 226         totalChannels++;
 227         keys.add(ski);
 228     }
 229 
 230 
 231     protected void implDereg(SelectionKeyImpl ski) throws IOException {
 232         int fd = ski.channel.getFDVal();
 233         fdMap.remove(Integer.valueOf(fd));
 234         kqueueWrapper.release(ski.channel);
 235         totalChannels--;
 236         keys.remove(ski);
 237         selectedKeys.remove(ski);
 238         deregister(ski);
 239         SelectableChannel selch = ski.channel();
 240         if (!selch.isOpen() && !selch.isRegistered())
 241             ((SelChImpl)selch).kill();
 242     }
 243 
 244 
 245     public void putEventOps(SelectionKeyImpl ski, int ops) {
 246         if (closed)
 247             throw new ClosedSelectorException();
 248         kqueueWrapper.setInterest(ski.channel, ops);
 249     }
 250 
 251 
 252     public Selector wakeup() {
 253         synchronized (interruptLock) {
 254             if (!interruptTriggered) {
 255                 kqueueWrapper.interrupt();
 256                 interruptTriggered = true;
 257             }
 258         }
< prev index next >