0N/A/*
2362N/A * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.nio.ch;
0N/A
0N/Aimport java.io.IOException;
0N/Aimport java.nio.channels.*;
0N/Aimport java.nio.channels.spi.*;
0N/Aimport java.util.*;
0N/Aimport sun.misc.*;
0N/A
0N/A
0N/A/**
0N/A * An abstract selector impl.
0N/A */
0N/A
0N/Aabstract class AbstractPollSelectorImpl
0N/A extends SelectorImpl
0N/A{
0N/A
0N/A // The poll fd array
0N/A PollArrayWrapper pollWrapper;
0N/A
0N/A // Initial capacity of the pollfd array
0N/A protected final int INIT_CAP = 10;
0N/A
0N/A // The list of SelectableChannels serviced by this Selector
0N/A protected SelectionKeyImpl[] channelArray;
0N/A
0N/A // In some impls the first entry of channelArray is bogus
0N/A protected int channelOffset = 0;
0N/A
0N/A // The number of valid channels in this Selector's poll array
0N/A protected int totalChannels;
0N/A
0N/A // True if this Selector has been closed
0N/A private boolean closed = false;
0N/A
673N/A // Lock for close and cleanup
673N/A private Object closeLock = new Object();
673N/A
0N/A AbstractPollSelectorImpl(SelectorProvider sp, int channels, int offset) {
0N/A super(sp);
0N/A this.totalChannels = channels;
0N/A this.channelOffset = offset;
0N/A }
0N/A
0N/A void putEventOps(SelectionKeyImpl sk, int ops) {
673N/A synchronized (closeLock) {
673N/A if (closed)
673N/A throw new ClosedSelectorException();
673N/A pollWrapper.putEventOps(sk.getIndex(), ops);
673N/A }
0N/A }
0N/A
0N/A public Selector wakeup() {
0N/A pollWrapper.interrupt();
0N/A return this;
0N/A }
0N/A
0N/A protected abstract int doSelect(long timeout) throws IOException;
0N/A
0N/A protected void implClose() throws IOException {
673N/A synchronized (closeLock) {
673N/A if (closed)
673N/A return;
0N/A closed = true;
0N/A // Deregister channels
0N/A for(int i=channelOffset; i<totalChannels; i++) {
0N/A SelectionKeyImpl ski = channelArray[i];
0N/A assert(ski.getIndex() != -1);
0N/A ski.setIndex(-1);
0N/A deregister(ski);
0N/A SelectableChannel selch = channelArray[i].channel();
0N/A if (!selch.isOpen() && !selch.isRegistered())
0N/A ((SelChImpl)selch).kill();
0N/A }
0N/A implCloseInterrupt();
0N/A pollWrapper.free();
0N/A pollWrapper = null;
0N/A selectedKeys = null;
0N/A channelArray = null;
0N/A totalChannels = 0;
0N/A }
0N/A }
0N/A
0N/A protected abstract void implCloseInterrupt() throws IOException;
0N/A
0N/A /**
0N/A * Copy the information in the pollfd structs into the opss
0N/A * of the corresponding Channels. Add the ready keys to the
0N/A * ready queue.
0N/A */
0N/A protected int updateSelectedKeys() {
0N/A int numKeysUpdated = 0;
0N/A // Skip zeroth entry; it is for interrupts only
0N/A for (int i=channelOffset; i<totalChannels; i++) {
0N/A int rOps = pollWrapper.getReventOps(i);
0N/A if (rOps != 0) {
0N/A SelectionKeyImpl sk = channelArray[i];
0N/A pollWrapper.putReventOps(i, 0);
0N/A if (selectedKeys.contains(sk)) {
0N/A if (sk.channel.translateAndSetReadyOps(rOps, sk)) {
0N/A numKeysUpdated++;
0N/A }
0N/A } else {
0N/A sk.channel.translateAndSetReadyOps(rOps, sk);
0N/A if ((sk.nioReadyOps() & sk.nioInterestOps()) != 0) {
0N/A selectedKeys.add(sk);
0N/A numKeysUpdated++;
0N/A }
0N/A }
0N/A }
0N/A }
0N/A return numKeysUpdated;
0N/A }
0N/A
0N/A protected void implRegister(SelectionKeyImpl ski) {
673N/A synchronized (closeLock) {
673N/A if (closed)
673N/A throw new ClosedSelectorException();
673N/A
673N/A // Check to see if the array is large enough
673N/A if (channelArray.length == totalChannels) {
673N/A // Make a larger array
673N/A int newSize = pollWrapper.totalChannels * 2;
673N/A SelectionKeyImpl temp[] = new SelectionKeyImpl[newSize];
673N/A // Copy over
673N/A for (int i=channelOffset; i<totalChannels; i++)
673N/A temp[i] = channelArray[i];
673N/A channelArray = temp;
673N/A // Grow the NativeObject poll array
673N/A pollWrapper.grow(newSize);
673N/A }
673N/A channelArray[totalChannels] = ski;
673N/A ski.setIndex(totalChannels);
673N/A pollWrapper.addEntry(ski.channel);
673N/A totalChannels++;
673N/A keys.add(ski);
0N/A }
0N/A }
0N/A
0N/A protected void implDereg(SelectionKeyImpl ski) throws IOException {
0N/A // Algorithm: Copy the sc from the end of the list and put it into
0N/A // the location of the sc to be removed (since order doesn't
0N/A // matter). Decrement the sc count. Update the index of the sc
0N/A // that is moved.
0N/A int i = ski.getIndex();
0N/A assert (i >= 0);
0N/A if (i != totalChannels - 1) {
0N/A // Copy end one over it
0N/A SelectionKeyImpl endChannel = channelArray[totalChannels-1];
0N/A channelArray[i] = endChannel;
0N/A endChannel.setIndex(i);
0N/A pollWrapper.release(i);
0N/A PollArrayWrapper.replaceEntry(pollWrapper, totalChannels - 1,
0N/A pollWrapper, i);
0N/A } else {
0N/A pollWrapper.release(i);
0N/A }
0N/A // Destroy the last one
0N/A channelArray[totalChannels-1] = null;
0N/A totalChannels--;
0N/A pollWrapper.totalChannels--;
0N/A ski.setIndex(-1);
0N/A // Remove the key from keys and selectedKeys
0N/A keys.remove(ski);
0N/A selectedKeys.remove(ski);
0N/A deregister((AbstractSelectionKey)ski);
0N/A SelectableChannel selch = ski.channel();
0N/A if (!selch.isOpen() && !selch.isRegistered())
0N/A ((SelChImpl)selch).kill();
0N/A }
0N/A
0N/A static {
0N/A Util.load();
0N/A }
0N/A
0N/A}