Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/nio/ch/EPollSelectorImpl.java
32288 views
/*1* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.nio.ch;2627import java.io.IOException;28import java.nio.channels.*;29import java.nio.channels.spi.*;30import java.util.*;31import sun.misc.*;3233/**34* An implementation of Selector for Linux 2.6+ kernels that uses35* the epoll event notification facility.36*/37class EPollSelectorImpl38extends SelectorImpl39{4041// File descriptors used for interrupt42protected int fd0;43protected int fd1;4445// The poll object46EPollArrayWrapper pollWrapper;4748// Maps from file descriptors to keys49private Map<Integer,SelectionKeyImpl> fdToKey;5051// True if this Selector has been closed52private volatile boolean closed = false;5354// Lock for interrupt triggering and clearing55private final Object interruptLock = new Object();56private boolean interruptTriggered = false;5758/**59* Package private constructor called by factory method in60* the abstract superclass Selector.61*/62EPollSelectorImpl(SelectorProvider sp) throws IOException {63super(sp);64long pipeFds = IOUtil.makePipe(false);65fd0 = (int) (pipeFds >>> 32);66fd1 = (int) pipeFds;67try {68pollWrapper = new EPollArrayWrapper();69pollWrapper.initInterrupt(fd0, fd1);70fdToKey = new HashMap<>();71} catch (Throwable t) {72try {73FileDispatcherImpl.closeIntFD(fd0);74} catch (IOException ioe0) {75t.addSuppressed(ioe0);76}77try {78FileDispatcherImpl.closeIntFD(fd1);79} catch (IOException ioe1) {80t.addSuppressed(ioe1);81}82throw t;83}84}8586protected int doSelect(long timeout) throws IOException {87if (closed)88throw new ClosedSelectorException();89processDeregisterQueue();90try {91begin();92pollWrapper.poll(timeout);93} finally {94end();95}96processDeregisterQueue();97int numKeysUpdated = updateSelectedKeys();98if (pollWrapper.interrupted()) {99// Clear the wakeup pipe100pollWrapper.putEventOps(pollWrapper.interruptedIndex(), 0);101synchronized (interruptLock) {102pollWrapper.clearInterrupted();103IOUtil.drain(fd0);104interruptTriggered = false;105}106}107return numKeysUpdated;108}109110/**111* Update the keys whose fd's have been selected by the epoll.112* Add the ready keys to the ready queue.113*/114private int updateSelectedKeys() {115int entries = pollWrapper.updated;116int numKeysUpdated = 0;117for (int i=0; i<entries; i++) {118int nextFD = pollWrapper.getDescriptor(i);119SelectionKeyImpl ski = fdToKey.get(Integer.valueOf(nextFD));120// ski is null in the case of an interrupt121if (ski != null) {122int rOps = pollWrapper.getEventOps(i);123if (selectedKeys.contains(ski)) {124if (ski.channel.translateAndSetReadyOps(rOps, ski)) {125numKeysUpdated++;126}127} else {128ski.channel.translateAndSetReadyOps(rOps, ski);129if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) {130selectedKeys.add(ski);131numKeysUpdated++;132}133}134}135}136return numKeysUpdated;137}138139protected void implClose() throws IOException {140if (closed)141return;142closed = true;143144// prevent further wakeup145synchronized (interruptLock) {146interruptTriggered = true;147}148149FileDispatcherImpl.closeIntFD(fd0);150FileDispatcherImpl.closeIntFD(fd1);151152pollWrapper.closeEPollFD();153// it is possible154selectedKeys = null;155156// Deregister channels157Iterator<SelectionKey> i = keys.iterator();158while (i.hasNext()) {159SelectionKeyImpl ski = (SelectionKeyImpl)i.next();160deregister(ski);161SelectableChannel selch = ski.channel();162if (!selch.isOpen() && !selch.isRegistered())163((SelChImpl)selch).kill();164i.remove();165}166167fd0 = -1;168fd1 = -1;169}170171protected void implRegister(SelectionKeyImpl ski) {172if (closed)173throw new ClosedSelectorException();174SelChImpl ch = ski.channel;175int fd = Integer.valueOf(ch.getFDVal());176fdToKey.put(fd, ski);177pollWrapper.add(fd);178keys.add(ski);179}180181protected void implDereg(SelectionKeyImpl ski) throws IOException {182assert (ski.getIndex() >= 0);183SelChImpl ch = ski.channel;184int fd = ch.getFDVal();185fdToKey.remove(Integer.valueOf(fd));186pollWrapper.remove(fd);187ski.setIndex(-1);188keys.remove(ski);189selectedKeys.remove(ski);190deregister((AbstractSelectionKey)ski);191SelectableChannel selch = ski.channel();192if (!selch.isOpen() && !selch.isRegistered())193((SelChImpl)selch).kill();194}195196public void putEventOps(SelectionKeyImpl ski, int ops) {197if (closed)198throw new ClosedSelectorException();199SelChImpl ch = ski.channel;200pollWrapper.setInterest(ch.getFDVal(), ops);201}202203public Selector wakeup() {204synchronized (interruptLock) {205if (!interruptTriggered) {206pollWrapper.interrupt();207interruptTriggered = true;208}209}210return this;211}212}213214215