Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java
32288 views
/*1* Copyright (c) 2001, 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.*;323334/**35* An implementation of Selector for Solaris.36*/37class DevPollSelectorImpl38extends SelectorImpl39{4041// File descriptors used for interrupt42protected int fd0;43protected int fd1;4445// The poll object46DevPollArrayWrapper pollWrapper;4748// Maps from file descriptors to keys49private Map<Integer,SelectionKeyImpl> fdToKey;5051// True if this Selector has been closed52private boolean closed = false;5354// Lock for close/cleanup55private Object closeLock = new Object();5657// Lock for interrupt triggering and clearing58private Object interruptLock = new Object();59private boolean interruptTriggered = false;6061/**62* Package private constructor called by factory method in63* the abstract superclass Selector.64*/65DevPollSelectorImpl(SelectorProvider sp) {66super(sp);67long pipeFds = IOUtil.makePipe(false);68fd0 = (int) (pipeFds >>> 32);69fd1 = (int) pipeFds;70try {71pollWrapper = new DevPollArrayWrapper();72pollWrapper.initInterrupt(fd0, fd1);73fdToKey = new HashMap<>();74} catch (Throwable t) {75try {76FileDispatcherImpl.closeIntFD(fd0);77} catch (IOException ioe0) {78t.addSuppressed(ioe0);79}80try {81FileDispatcherImpl.closeIntFD(fd1);82} catch (IOException ioe1) {83t.addSuppressed(ioe1);84}85throw t;86}87}8889protected int doSelect(long timeout)90throws IOException91{92if (closed)93throw new ClosedSelectorException();94processDeregisterQueue();95try {96begin();97pollWrapper.poll(timeout);98} finally {99end();100}101processDeregisterQueue();102int numKeysUpdated = updateSelectedKeys();103if (pollWrapper.interrupted()) {104// Clear the wakeup pipe105pollWrapper.putReventOps(pollWrapper.interruptedIndex(), 0);106synchronized (interruptLock) {107pollWrapper.clearInterrupted();108IOUtil.drain(fd0);109interruptTriggered = false;110}111}112return numKeysUpdated;113}114115/**116* Update the keys whose fd's have been selected by the devpoll117* driver. Add the ready keys to the ready queue.118*/119private int updateSelectedKeys() {120int entries = pollWrapper.updated;121int numKeysUpdated = 0;122for (int i=0; i<entries; i++) {123int nextFD = pollWrapper.getDescriptor(i);124SelectionKeyImpl ski = fdToKey.get(Integer.valueOf(nextFD));125// ski is null in the case of an interrupt126if (ski != null) {127int rOps = pollWrapper.getReventOps(i);128if (selectedKeys.contains(ski)) {129if (ski.channel.translateAndSetReadyOps(rOps, ski)) {130numKeysUpdated++;131}132} else {133ski.channel.translateAndSetReadyOps(rOps, ski);134if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) {135selectedKeys.add(ski);136numKeysUpdated++;137}138}139}140}141return numKeysUpdated;142}143144protected void implClose() throws IOException {145if (closed)146return;147closed = true;148149// prevent further wakeup150synchronized (interruptLock) {151interruptTriggered = true;152}153154FileDispatcherImpl.closeIntFD(fd0);155FileDispatcherImpl.closeIntFD(fd1);156157pollWrapper.release(fd0);158pollWrapper.closeDevPollFD();159selectedKeys = null;160161// Deregister channels162Iterator<SelectionKey> i = keys.iterator();163while (i.hasNext()) {164SelectionKeyImpl ski = (SelectionKeyImpl)i.next();165deregister(ski);166SelectableChannel selch = ski.channel();167if (!selch.isOpen() && !selch.isRegistered())168((SelChImpl)selch).kill();169i.remove();170}171fd0 = -1;172fd1 = -1;173}174175protected void implRegister(SelectionKeyImpl ski) {176int fd = IOUtil.fdVal(ski.channel.getFD());177fdToKey.put(Integer.valueOf(fd), ski);178keys.add(ski);179}180181protected void implDereg(SelectionKeyImpl ski) throws IOException {182int i = ski.getIndex();183assert (i >= 0);184int fd = ski.channel.getFDVal();185fdToKey.remove(Integer.valueOf(fd));186pollWrapper.release(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 sk, int ops) {197if (closed)198throw new ClosedSelectorException();199int fd = IOUtil.fdVal(sk.channel.getFD());200pollWrapper.setInterest(fd, ops);201}202203public Selector wakeup() {204synchronized (interruptLock) {205if (!interruptTriggered) {206pollWrapper.interrupt();207interruptTriggered = true;208}209}210return this;211}212}213214215