feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
324
jdkSrc/jdk8/java/nio/channels/spi/AbstractSelectableChannel.java
Normal file
324
jdkSrc/jdk8/java/nio/channels/spi/AbstractSelectableChannel.java
Normal file
@@ -0,0 +1,324 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.nio.channels.spi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.CancelledKeyException;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.channels.ClosedSelectorException;
|
||||
import java.nio.channels.IllegalBlockingModeException;
|
||||
import java.nio.channels.IllegalSelectorException;
|
||||
import java.nio.channels.SelectableChannel;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
|
||||
|
||||
/**
|
||||
* Base implementation class for selectable channels.
|
||||
*
|
||||
* <p> This class defines methods that handle the mechanics of channel
|
||||
* registration, deregistration, and closing. It maintains the current
|
||||
* blocking mode of this channel as well as its current set of selection keys.
|
||||
* It performs all of the synchronization required to implement the {@link
|
||||
* java.nio.channels.SelectableChannel} specification. Implementations of the
|
||||
* abstract protected methods defined in this class need not synchronize
|
||||
* against other threads that might be engaged in the same operations. </p>
|
||||
*
|
||||
*
|
||||
* @author Mark Reinhold
|
||||
* @author Mike McCloskey
|
||||
* @author JSR-51 Expert Group
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public abstract class AbstractSelectableChannel
|
||||
extends SelectableChannel
|
||||
{
|
||||
|
||||
// The provider that created this channel
|
||||
private final SelectorProvider provider;
|
||||
|
||||
// Keys that have been created by registering this channel with selectors.
|
||||
// They are saved because if this channel is closed the keys must be
|
||||
// deregistered. Protected by keyLock.
|
||||
//
|
||||
private SelectionKey[] keys = null;
|
||||
private int keyCount = 0;
|
||||
|
||||
// Lock for key set and count
|
||||
private final Object keyLock = new Object();
|
||||
|
||||
// Lock for registration and configureBlocking operations
|
||||
private final Object regLock = new Object();
|
||||
|
||||
// True when non-blocking, need regLock to change;
|
||||
private volatile boolean nonBlocking;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of this class.
|
||||
*
|
||||
* @param provider
|
||||
* The provider that created this channel
|
||||
*/
|
||||
protected AbstractSelectableChannel(SelectorProvider provider) {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the provider that created this channel.
|
||||
*
|
||||
* @return The provider that created this channel
|
||||
*/
|
||||
public final SelectorProvider provider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
|
||||
// -- Utility methods for the key set --
|
||||
|
||||
private void addKey(SelectionKey k) {
|
||||
assert Thread.holdsLock(keyLock);
|
||||
int i = 0;
|
||||
if ((keys != null) && (keyCount < keys.length)) {
|
||||
// Find empty element of key array
|
||||
for (i = 0; i < keys.length; i++)
|
||||
if (keys[i] == null)
|
||||
break;
|
||||
} else if (keys == null) {
|
||||
keys = new SelectionKey[3];
|
||||
} else {
|
||||
// Grow key array
|
||||
int n = keys.length * 2;
|
||||
SelectionKey[] ks = new SelectionKey[n];
|
||||
for (i = 0; i < keys.length; i++)
|
||||
ks[i] = keys[i];
|
||||
keys = ks;
|
||||
i = keyCount;
|
||||
}
|
||||
keys[i] = k;
|
||||
keyCount++;
|
||||
}
|
||||
|
||||
private SelectionKey findKey(Selector sel) {
|
||||
synchronized (keyLock) {
|
||||
if (keys == null)
|
||||
return null;
|
||||
for (int i = 0; i < keys.length; i++)
|
||||
if ((keys[i] != null) && (keys[i].selector() == sel))
|
||||
return keys[i];
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
void removeKey(SelectionKey k) { // package-private
|
||||
synchronized (keyLock) {
|
||||
for (int i = 0; i < keys.length; i++)
|
||||
if (keys[i] == k) {
|
||||
keys[i] = null;
|
||||
keyCount--;
|
||||
}
|
||||
((AbstractSelectionKey)k).invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean haveValidKeys() {
|
||||
synchronized (keyLock) {
|
||||
if (keyCount == 0)
|
||||
return false;
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
if ((keys[i] != null) && keys[i].isValid())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -- Registration --
|
||||
|
||||
public final boolean isRegistered() {
|
||||
synchronized (keyLock) {
|
||||
return keyCount != 0;
|
||||
}
|
||||
}
|
||||
|
||||
public final SelectionKey keyFor(Selector sel) {
|
||||
return findKey(sel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this channel with the given selector, returning a selection key.
|
||||
*
|
||||
* <p> This method first verifies that this channel is open and that the
|
||||
* given initial interest set is valid.
|
||||
*
|
||||
* <p> If this channel is already registered with the given selector then
|
||||
* the selection key representing that registration is returned after
|
||||
* setting its interest set to the given value.
|
||||
*
|
||||
* <p> Otherwise this channel has not yet been registered with the given
|
||||
* selector, so the {@link AbstractSelector#register register} method of
|
||||
* the selector is invoked while holding the appropriate locks. The
|
||||
* resulting key is added to this channel's key set before being returned.
|
||||
* </p>
|
||||
*
|
||||
* @throws ClosedSelectorException {@inheritDoc}
|
||||
*
|
||||
* @throws IllegalBlockingModeException {@inheritDoc}
|
||||
*
|
||||
* @throws IllegalSelectorException {@inheritDoc}
|
||||
*
|
||||
* @throws CancelledKeyException {@inheritDoc}
|
||||
*
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
*/
|
||||
public final SelectionKey register(Selector sel, int ops,
|
||||
Object att)
|
||||
throws ClosedChannelException
|
||||
{
|
||||
synchronized (regLock) {
|
||||
if (!isOpen())
|
||||
throw new ClosedChannelException();
|
||||
if ((ops & ~validOps()) != 0)
|
||||
throw new IllegalArgumentException();
|
||||
if (isBlocking())
|
||||
throw new IllegalBlockingModeException();
|
||||
SelectionKey k = findKey(sel);
|
||||
if (k != null) {
|
||||
k.interestOps(ops);
|
||||
k.attach(att);
|
||||
}
|
||||
if (k == null) {
|
||||
// New registration
|
||||
synchronized (keyLock) {
|
||||
if (!isOpen())
|
||||
throw new ClosedChannelException();
|
||||
k = ((AbstractSelector)sel).register(this, ops, att);
|
||||
addKey(k);
|
||||
}
|
||||
}
|
||||
return k;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -- Closing --
|
||||
|
||||
/**
|
||||
* Closes this channel.
|
||||
*
|
||||
* <p> This method, which is specified in the {@link
|
||||
* AbstractInterruptibleChannel} class and is invoked by the {@link
|
||||
* java.nio.channels.Channel#close close} method, in turn invokes the
|
||||
* {@link #implCloseSelectableChannel implCloseSelectableChannel} method in
|
||||
* order to perform the actual work of closing this channel. It then
|
||||
* cancels all of this channel's keys. </p>
|
||||
*/
|
||||
protected final void implCloseChannel() throws IOException {
|
||||
implCloseSelectableChannel();
|
||||
synchronized (keyLock) {
|
||||
int count = (keys == null) ? 0 : keys.length;
|
||||
for (int i = 0; i < count; i++) {
|
||||
SelectionKey k = keys[i];
|
||||
if (k != null)
|
||||
k.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this selectable channel.
|
||||
*
|
||||
* <p> This method is invoked by the {@link java.nio.channels.Channel#close
|
||||
* close} method in order to perform the actual work of closing the
|
||||
* channel. This method is only invoked if the channel has not yet been
|
||||
* closed, and it is never invoked more than once.
|
||||
*
|
||||
* <p> An implementation of this method must arrange for any other thread
|
||||
* that is blocked in an I/O operation upon this channel to return
|
||||
* immediately, either by throwing an exception or by returning normally.
|
||||
* </p>
|
||||
*
|
||||
* @throws IOException
|
||||
* If an I/O error occurs
|
||||
*/
|
||||
protected abstract void implCloseSelectableChannel() throws IOException;
|
||||
|
||||
|
||||
// -- Blocking --
|
||||
|
||||
public final boolean isBlocking() {
|
||||
return !nonBlocking;
|
||||
}
|
||||
|
||||
public final Object blockingLock() {
|
||||
return regLock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts this channel's blocking mode.
|
||||
*
|
||||
* <p> If the given blocking mode is different from the current blocking
|
||||
* mode then this method invokes the {@link #implConfigureBlocking
|
||||
* implConfigureBlocking} method, while holding the appropriate locks, in
|
||||
* order to change the mode. </p>
|
||||
*/
|
||||
public final SelectableChannel configureBlocking(boolean block)
|
||||
throws IOException
|
||||
{
|
||||
synchronized (regLock) {
|
||||
if (!isOpen())
|
||||
throw new ClosedChannelException();
|
||||
boolean blocking = !nonBlocking;
|
||||
if (block != blocking) {
|
||||
if (block && haveValidKeys())
|
||||
throw new IllegalBlockingModeException();
|
||||
implConfigureBlocking(block);
|
||||
nonBlocking = !block;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts this channel's blocking mode.
|
||||
*
|
||||
* <p> This method is invoked by the {@link #configureBlocking
|
||||
* configureBlocking} method in order to perform the actual work of
|
||||
* changing the blocking mode. This method is only invoked if the new mode
|
||||
* is different from the current mode. </p>
|
||||
*
|
||||
* @param block If <tt>true</tt> then this channel will be placed in
|
||||
* blocking mode; if <tt>false</tt> then it will be placed
|
||||
* non-blocking mode
|
||||
*
|
||||
* @throws IOException
|
||||
* If an I/O error occurs
|
||||
*/
|
||||
protected abstract void implConfigureBlocking(boolean block)
|
||||
throws IOException;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user