Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/nio/ch/AbstractPollSelectorImpl.java
38918 views
/*1* Copyright (c) 2001, 2013, 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 abstract selector impl.36*/3738abstract class AbstractPollSelectorImpl39extends SelectorImpl40{4142// The poll fd array43PollArrayWrapper pollWrapper;4445// Initial capacity of the pollfd array46protected final int INIT_CAP = 10;4748// The list of SelectableChannels serviced by this Selector49protected SelectionKeyImpl[] channelArray;5051// In some impls the first entry of channelArray is bogus52protected int channelOffset = 0;5354// The number of valid channels in this Selector's poll array55protected int totalChannels;5657// True if this Selector has been closed58private boolean closed = false;5960// Lock for close and cleanup61private Object closeLock = new Object();6263AbstractPollSelectorImpl(SelectorProvider sp, int channels, int offset) {64super(sp);65this.totalChannels = channels;66this.channelOffset = offset;67}6869public void putEventOps(SelectionKeyImpl sk, int ops) {70synchronized (closeLock) {71if (closed)72throw new ClosedSelectorException();73pollWrapper.putEventOps(sk.getIndex(), ops);74}75}7677public Selector wakeup() {78pollWrapper.interrupt();79return this;80}8182protected abstract int doSelect(long timeout) throws IOException;8384protected void implClose() throws IOException {85synchronized (closeLock) {86if (closed)87return;88closed = true;89// Deregister channels90for(int i=channelOffset; i<totalChannels; i++) {91SelectionKeyImpl ski = channelArray[i];92assert(ski.getIndex() != -1);93ski.setIndex(-1);94deregister(ski);95SelectableChannel selch = channelArray[i].channel();96if (!selch.isOpen() && !selch.isRegistered())97((SelChImpl)selch).kill();98}99implCloseInterrupt();100pollWrapper.free();101pollWrapper = null;102selectedKeys = null;103channelArray = null;104totalChannels = 0;105}106}107108protected abstract void implCloseInterrupt() throws IOException;109110/**111* Copy the information in the pollfd structs into the opss112* of the corresponding Channels. Add the ready keys to the113* ready queue.114*/115protected int updateSelectedKeys() {116int numKeysUpdated = 0;117// Skip zeroth entry; it is for interrupts only118for (int i=channelOffset; i<totalChannels; i++) {119int rOps = pollWrapper.getReventOps(i);120if (rOps != 0) {121SelectionKeyImpl sk = channelArray[i];122pollWrapper.putReventOps(i, 0);123if (selectedKeys.contains(sk)) {124if (sk.channel.translateAndSetReadyOps(rOps, sk)) {125numKeysUpdated++;126}127} else {128sk.channel.translateAndSetReadyOps(rOps, sk);129if ((sk.nioReadyOps() & sk.nioInterestOps()) != 0) {130selectedKeys.add(sk);131numKeysUpdated++;132}133}134}135}136return numKeysUpdated;137}138139protected void implRegister(SelectionKeyImpl ski) {140synchronized (closeLock) {141if (closed)142throw new ClosedSelectorException();143144// Check to see if the array is large enough145if (channelArray.length == totalChannels) {146// Make a larger array147int newSize = pollWrapper.totalChannels * 2;148SelectionKeyImpl temp[] = new SelectionKeyImpl[newSize];149// Copy over150for (int i=channelOffset; i<totalChannels; i++)151temp[i] = channelArray[i];152channelArray = temp;153// Grow the NativeObject poll array154pollWrapper.grow(newSize);155}156channelArray[totalChannels] = ski;157ski.setIndex(totalChannels);158pollWrapper.addEntry(ski.channel);159totalChannels++;160keys.add(ski);161}162}163164protected void implDereg(SelectionKeyImpl ski) throws IOException {165// Algorithm: Copy the sc from the end of the list and put it into166// the location of the sc to be removed (since order doesn't167// matter). Decrement the sc count. Update the index of the sc168// that is moved.169int i = ski.getIndex();170assert (i >= 0);171if (i != totalChannels - 1) {172// Copy end one over it173SelectionKeyImpl endChannel = channelArray[totalChannels-1];174channelArray[i] = endChannel;175endChannel.setIndex(i);176pollWrapper.release(i);177PollArrayWrapper.replaceEntry(pollWrapper, totalChannels - 1,178pollWrapper, i);179} else {180pollWrapper.release(i);181}182// Destroy the last one183channelArray[totalChannels-1] = null;184totalChannels--;185pollWrapper.totalChannels--;186ski.setIndex(-1);187// Remove the key from keys and selectedKeys188keys.remove(ski);189selectedKeys.remove(ski);190deregister((AbstractSelectionKey)ski);191SelectableChannel selch = ski.channel();192if (!selch.isOpen() && !selch.isRegistered())193((SelChImpl)selch).kill();194}195}196197198