mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8187443: Forest Consolidation: Move files to unified layout
Reviewed-by: darcy, ihse
This commit is contained in:
parent
270fe13182
commit
3789983e89
56923 changed files with 3 additions and 15727 deletions
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2017, 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.*;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import sun.nio.ch.Interruptible;
|
||||
|
||||
|
||||
/**
|
||||
* Base implementation class for interruptible channels.
|
||||
*
|
||||
* <p> This class encapsulates the low-level machinery required to implement
|
||||
* the asynchronous closing and interruption of channels. A concrete channel
|
||||
* class must invoke the {@link #begin begin} and {@link #end end} methods
|
||||
* before and after, respectively, invoking an I/O operation that might block
|
||||
* indefinitely. In order to ensure that the {@link #end end} method is always
|
||||
* invoked, these methods should be used within a
|
||||
* {@code try} ... {@code finally} block:
|
||||
*
|
||||
* <blockquote><pre id="be">
|
||||
* boolean completed = false;
|
||||
* try {
|
||||
* begin();
|
||||
* completed = ...; // Perform blocking I/O operation
|
||||
* return ...; // Return result
|
||||
* } finally {
|
||||
* end(completed);
|
||||
* }</pre></blockquote>
|
||||
*
|
||||
* <p> The {@code completed} argument to the {@link #end end} method tells
|
||||
* whether or not the I/O operation actually completed, that is, whether it had
|
||||
* any effect that would be visible to the invoker. In the case of an
|
||||
* operation that reads bytes, for example, this argument should be
|
||||
* {@code true} if, and only if, some bytes were actually transferred into the
|
||||
* invoker's target buffer.
|
||||
*
|
||||
* <p> A concrete channel class must also implement the {@link
|
||||
* #implCloseChannel implCloseChannel} method in such a way that if it is
|
||||
* invoked while another thread is blocked in a native I/O operation upon the
|
||||
* channel then that operation will immediately return, either by throwing an
|
||||
* exception or by returning normally. If a thread is interrupted or the
|
||||
* channel upon which it is blocked is asynchronously closed then the channel's
|
||||
* {@link #end end} method will throw the appropriate exception.
|
||||
*
|
||||
* <p> This class performs the synchronization required to implement the {@link
|
||||
* java.nio.channels.Channel} specification. Implementations of the {@link
|
||||
* #implCloseChannel implCloseChannel} method need not synchronize against
|
||||
* other threads that might be attempting to close the channel. </p>
|
||||
*
|
||||
*
|
||||
* @author Mark Reinhold
|
||||
* @author JSR-51 Expert Group
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public abstract class AbstractInterruptibleChannel
|
||||
implements Channel, InterruptibleChannel
|
||||
{
|
||||
|
||||
private final Object closeLock = new Object();
|
||||
private volatile boolean closed;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of this class.
|
||||
*/
|
||||
protected AbstractInterruptibleChannel() { }
|
||||
|
||||
/**
|
||||
* Closes this channel.
|
||||
*
|
||||
* <p> If the channel has already been closed then this method returns
|
||||
* immediately. Otherwise it marks the channel as closed and then invokes
|
||||
* the {@link #implCloseChannel implCloseChannel} method in order to
|
||||
* complete the close operation. </p>
|
||||
*
|
||||
* @throws IOException
|
||||
* If an I/O error occurs
|
||||
*/
|
||||
public final void close() throws IOException {
|
||||
synchronized (closeLock) {
|
||||
if (closed)
|
||||
return;
|
||||
closed = true;
|
||||
implCloseChannel();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this channel.
|
||||
*
|
||||
* <p> This method is invoked by the {@link #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 while closing the channel
|
||||
*/
|
||||
protected abstract void implCloseChannel() throws IOException;
|
||||
|
||||
public final boolean isOpen() {
|
||||
return !closed;
|
||||
}
|
||||
|
||||
|
||||
// -- Interruption machinery --
|
||||
|
||||
private Interruptible interruptor;
|
||||
private volatile Thread interrupted;
|
||||
|
||||
/**
|
||||
* Marks the beginning of an I/O operation that might block indefinitely.
|
||||
*
|
||||
* <p> This method should be invoked in tandem with the {@link #end end}
|
||||
* method, using a {@code try} ... {@code finally} block as
|
||||
* shown <a href="#be">above</a>, in order to implement asynchronous
|
||||
* closing and interruption for this channel. </p>
|
||||
*/
|
||||
protected final void begin() {
|
||||
if (interruptor == null) {
|
||||
interruptor = new Interruptible() {
|
||||
public void interrupt(Thread target) {
|
||||
synchronized (closeLock) {
|
||||
if (closed)
|
||||
return;
|
||||
closed = true;
|
||||
interrupted = target;
|
||||
try {
|
||||
AbstractInterruptibleChannel.this.implCloseChannel();
|
||||
} catch (IOException x) { }
|
||||
}
|
||||
}};
|
||||
}
|
||||
blockedOn(interruptor);
|
||||
Thread me = Thread.currentThread();
|
||||
if (me.isInterrupted())
|
||||
interruptor.interrupt(me);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the end of an I/O operation that might block indefinitely.
|
||||
*
|
||||
* <p> This method should be invoked in tandem with the {@link #begin
|
||||
* begin} method, using a {@code try} ... {@code finally} block
|
||||
* as shown <a href="#be">above</a>, in order to implement asynchronous
|
||||
* closing and interruption for this channel. </p>
|
||||
*
|
||||
* @param completed
|
||||
* {@code true} if, and only if, the I/O operation completed
|
||||
* successfully, that is, had some effect that would be visible to
|
||||
* the operation's invoker
|
||||
*
|
||||
* @throws AsynchronousCloseException
|
||||
* If the channel was asynchronously closed
|
||||
*
|
||||
* @throws ClosedByInterruptException
|
||||
* If the thread blocked in the I/O operation was interrupted
|
||||
*/
|
||||
protected final void end(boolean completed)
|
||||
throws AsynchronousCloseException
|
||||
{
|
||||
blockedOn(null);
|
||||
Thread interrupted = this.interrupted;
|
||||
if (interrupted != null && interrupted == Thread.currentThread()) {
|
||||
this.interrupted = null;
|
||||
throw new ClosedByInterruptException();
|
||||
}
|
||||
if (!completed && closed)
|
||||
throw new AsynchronousCloseException();
|
||||
}
|
||||
|
||||
|
||||
// -- jdk.internal.misc.SharedSecrets --
|
||||
static void blockedOn(Interruptible intr) { // package-private
|
||||
SharedSecrets.getJavaLangAccess().blockedOn(Thread.currentThread(), intr);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,318 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2013, 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.*;
|
||||
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
// Blocking mode, protected by regLock
|
||||
boolean blocking = true;
|
||||
|
||||
/**
|
||||
* 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 (blocking)
|
||||
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() {
|
||||
synchronized (regLock) {
|
||||
return blocking;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
if (blocking == block)
|
||||
return this;
|
||||
if (block && haveValidKeys())
|
||||
throw new IllegalBlockingModeException();
|
||||
implConfigureBlocking(block);
|
||||
blocking = 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 {@code true} then this channel will be placed in
|
||||
* blocking mode; if {@code false} then it will be placed
|
||||
* non-blocking mode
|
||||
*
|
||||
* @throws IOException
|
||||
* If an I/O error occurs
|
||||
*/
|
||||
protected abstract void implConfigureBlocking(boolean block)
|
||||
throws IOException;
|
||||
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2013, 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.nio.channels.*;
|
||||
|
||||
|
||||
/**
|
||||
* Base implementation class for selection keys.
|
||||
*
|
||||
* <p> This class tracks the validity of the key and implements cancellation.
|
||||
*
|
||||
* @author Mark Reinhold
|
||||
* @author JSR-51 Expert Group
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public abstract class AbstractSelectionKey
|
||||
extends SelectionKey
|
||||
{
|
||||
|
||||
/**
|
||||
* Initializes a new instance of this class.
|
||||
*/
|
||||
protected AbstractSelectionKey() { }
|
||||
|
||||
private volatile boolean valid = true;
|
||||
|
||||
public final boolean isValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
void invalidate() { // package-private
|
||||
valid = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels this key.
|
||||
*
|
||||
* <p> If this key has not yet been cancelled then it is added to its
|
||||
* selector's cancelled-key set while synchronized on that set. </p>
|
||||
*/
|
||||
public final void cancel() {
|
||||
// Synchronizing "this" to prevent this key from getting canceled
|
||||
// multiple times by different threads, which might cause race
|
||||
// condition between selector's select() and channel's close().
|
||||
synchronized (this) {
|
||||
if (valid) {
|
||||
valid = false;
|
||||
((AbstractSelector)selector()).cancel(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2017, 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.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import sun.nio.ch.Interruptible;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
|
||||
/**
|
||||
* Base implementation class for selectors.
|
||||
*
|
||||
* <p> This class encapsulates the low-level machinery required to implement
|
||||
* the interruption of selection operations. A concrete selector class must
|
||||
* invoke the {@link #begin begin} and {@link #end end} methods before and
|
||||
* after, respectively, invoking an I/O operation that might block
|
||||
* indefinitely. In order to ensure that the {@link #end end} method is always
|
||||
* invoked, these methods should be used within a
|
||||
* {@code try} ... {@code finally} block:
|
||||
*
|
||||
* <blockquote><pre id="be">
|
||||
* try {
|
||||
* begin();
|
||||
* // Perform blocking I/O operation here
|
||||
* ...
|
||||
* } finally {
|
||||
* end();
|
||||
* }</pre></blockquote>
|
||||
*
|
||||
* <p> This class also defines methods for maintaining a selector's
|
||||
* cancelled-key set and for removing a key from its channel's key set, and
|
||||
* declares the abstract {@link #register register} method that is invoked by a
|
||||
* selectable channel's {@link AbstractSelectableChannel#register register}
|
||||
* method in order to perform the actual work of registering a channel. </p>
|
||||
*
|
||||
*
|
||||
* @author Mark Reinhold
|
||||
* @author JSR-51 Expert Group
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public abstract class AbstractSelector
|
||||
extends Selector
|
||||
{
|
||||
|
||||
private final AtomicBoolean selectorOpen = new AtomicBoolean(true);
|
||||
|
||||
// The provider that created this selector
|
||||
private final SelectorProvider provider;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of this class.
|
||||
*
|
||||
* @param provider
|
||||
* The provider that created this selector
|
||||
*/
|
||||
protected AbstractSelector(SelectorProvider provider) {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
private final Set<SelectionKey> cancelledKeys = new HashSet<SelectionKey>();
|
||||
|
||||
void cancel(SelectionKey k) { // package-private
|
||||
synchronized (cancelledKeys) {
|
||||
cancelledKeys.add(k);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this selector.
|
||||
*
|
||||
* <p> If the selector has already been closed then this method returns
|
||||
* immediately. Otherwise it marks the selector as closed and then invokes
|
||||
* the {@link #implCloseSelector implCloseSelector} method in order to
|
||||
* complete the close operation. </p>
|
||||
*
|
||||
* @throws IOException
|
||||
* If an I/O error occurs
|
||||
*/
|
||||
public final void close() throws IOException {
|
||||
boolean open = selectorOpen.getAndSet(false);
|
||||
if (!open)
|
||||
return;
|
||||
implCloseSelector();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this selector.
|
||||
*
|
||||
* <p> This method is invoked by the {@link #close close} method in order
|
||||
* to perform the actual work of closing the selector. This method is only
|
||||
* invoked if the selector 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 a selection operation upon this selector to return
|
||||
* immediately as if by invoking the {@link
|
||||
* java.nio.channels.Selector#wakeup wakeup} method. </p>
|
||||
*
|
||||
* @throws IOException
|
||||
* If an I/O error occurs while closing the selector
|
||||
*/
|
||||
protected abstract void implCloseSelector() throws IOException;
|
||||
|
||||
public final boolean isOpen() {
|
||||
return selectorOpen.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the provider that created this channel.
|
||||
*
|
||||
* @return The provider that created this channel
|
||||
*/
|
||||
public final SelectorProvider provider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves this selector's cancelled-key set.
|
||||
*
|
||||
* <p> This set should only be used while synchronized upon it. </p>
|
||||
*
|
||||
* @return The cancelled-key set
|
||||
*/
|
||||
protected final Set<SelectionKey> cancelledKeys() {
|
||||
return cancelledKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the given channel with this selector.
|
||||
*
|
||||
* <p> This method is invoked by a channel's {@link
|
||||
* AbstractSelectableChannel#register register} method in order to perform
|
||||
* the actual work of registering the channel with this selector. </p>
|
||||
*
|
||||
* @param ch
|
||||
* The channel to be registered
|
||||
*
|
||||
* @param ops
|
||||
* The initial interest set, which must be valid
|
||||
*
|
||||
* @param att
|
||||
* The initial attachment for the resulting key
|
||||
*
|
||||
* @return A new key representing the registration of the given channel
|
||||
* with this selector
|
||||
*/
|
||||
protected abstract SelectionKey register(AbstractSelectableChannel ch,
|
||||
int ops, Object att);
|
||||
|
||||
/**
|
||||
* Removes the given key from its channel's key set.
|
||||
*
|
||||
* <p> This method must be invoked by the selector for each channel that it
|
||||
* deregisters. </p>
|
||||
*
|
||||
* @param key
|
||||
* The selection key to be removed
|
||||
*/
|
||||
protected final void deregister(AbstractSelectionKey key) {
|
||||
((AbstractSelectableChannel)key.channel()).removeKey(key);
|
||||
}
|
||||
|
||||
|
||||
// -- Interruption machinery --
|
||||
|
||||
private Interruptible interruptor = null;
|
||||
|
||||
/**
|
||||
* Marks the beginning of an I/O operation that might block indefinitely.
|
||||
*
|
||||
* <p> This method should be invoked in tandem with the {@link #end end}
|
||||
* method, using a {@code try} ... {@code finally} block as
|
||||
* shown <a href="#be">above</a>, in order to implement interruption for
|
||||
* this selector.
|
||||
*
|
||||
* <p> Invoking this method arranges for the selector's {@link
|
||||
* Selector#wakeup wakeup} method to be invoked if a thread's {@link
|
||||
* Thread#interrupt interrupt} method is invoked while the thread is
|
||||
* blocked in an I/O operation upon the selector. </p>
|
||||
*/
|
||||
protected final void begin() {
|
||||
if (interruptor == null) {
|
||||
interruptor = new Interruptible() {
|
||||
public void interrupt(Thread ignore) {
|
||||
AbstractSelector.this.wakeup();
|
||||
}};
|
||||
}
|
||||
AbstractInterruptibleChannel.blockedOn(interruptor);
|
||||
Thread me = Thread.currentThread();
|
||||
if (me.isInterrupted())
|
||||
interruptor.interrupt(me);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the end of an I/O operation that might block indefinitely.
|
||||
*
|
||||
* <p> This method should be invoked in tandem with the {@link #begin begin}
|
||||
* method, using a {@code try} ... {@code finally} block as
|
||||
* shown <a href="#be">above</a>, in order to implement interruption for
|
||||
* this selector. </p>
|
||||
*/
|
||||
protected final void end() {
|
||||
AbstractInterruptibleChannel.blockedOn(null);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,246 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2013, 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.nio.channels.*;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.ServiceConfigurationError;
|
||||
import java.util.concurrent.*;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/**
|
||||
* Service-provider class for asynchronous channels.
|
||||
*
|
||||
* <p> An asynchronous channel provider is a concrete subclass of this class that
|
||||
* has a zero-argument constructor and implements the abstract methods specified
|
||||
* below. A given invocation of the Java virtual machine maintains a single
|
||||
* system-wide default provider instance, which is returned by the {@link
|
||||
* #provider() provider} method. The first invocation of that method will locate
|
||||
* the default provider as specified below.
|
||||
*
|
||||
* <p> All of the methods in this class are safe for use by multiple concurrent
|
||||
* threads. </p>
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
|
||||
public abstract class AsynchronousChannelProvider {
|
||||
private static Void checkPermission() {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null)
|
||||
sm.checkPermission(new RuntimePermission("asynchronousChannelProvider"));
|
||||
return null;
|
||||
}
|
||||
private AsynchronousChannelProvider(Void ignore) { }
|
||||
|
||||
/**
|
||||
* Initializes a new instance of this class.
|
||||
*
|
||||
* @throws SecurityException
|
||||
* If a security manager has been installed and it denies
|
||||
* {@link RuntimePermission}{@code ("asynchronousChannelProvider")}
|
||||
*/
|
||||
protected AsynchronousChannelProvider() {
|
||||
this(checkPermission());
|
||||
}
|
||||
|
||||
// lazy initialization of default provider
|
||||
private static class ProviderHolder {
|
||||
static final AsynchronousChannelProvider provider = load();
|
||||
|
||||
private static AsynchronousChannelProvider load() {
|
||||
return AccessController
|
||||
.doPrivileged(new PrivilegedAction<>() {
|
||||
public AsynchronousChannelProvider run() {
|
||||
AsynchronousChannelProvider p;
|
||||
p = loadProviderFromProperty();
|
||||
if (p != null)
|
||||
return p;
|
||||
p = loadProviderAsService();
|
||||
if (p != null)
|
||||
return p;
|
||||
return sun.nio.ch.DefaultAsynchronousChannelProvider.create();
|
||||
}});
|
||||
}
|
||||
|
||||
private static AsynchronousChannelProvider loadProviderFromProperty() {
|
||||
String cn = System.getProperty("java.nio.channels.spi.AsynchronousChannelProvider");
|
||||
if (cn == null)
|
||||
return null;
|
||||
try {
|
||||
@SuppressWarnings("deprecation")
|
||||
Object tmp = Class.forName(cn, true,
|
||||
ClassLoader.getSystemClassLoader()).newInstance();
|
||||
return (AsynchronousChannelProvider)tmp;
|
||||
} catch (ClassNotFoundException x) {
|
||||
throw new ServiceConfigurationError(null, x);
|
||||
} catch (IllegalAccessException x) {
|
||||
throw new ServiceConfigurationError(null, x);
|
||||
} catch (InstantiationException x) {
|
||||
throw new ServiceConfigurationError(null, x);
|
||||
} catch (SecurityException x) {
|
||||
throw new ServiceConfigurationError(null, x);
|
||||
}
|
||||
}
|
||||
|
||||
private static AsynchronousChannelProvider loadProviderAsService() {
|
||||
ServiceLoader<AsynchronousChannelProvider> sl =
|
||||
ServiceLoader.load(AsynchronousChannelProvider.class,
|
||||
ClassLoader.getSystemClassLoader());
|
||||
Iterator<AsynchronousChannelProvider> i = sl.iterator();
|
||||
for (;;) {
|
||||
try {
|
||||
return (i.hasNext()) ? i.next() : null;
|
||||
} catch (ServiceConfigurationError sce) {
|
||||
if (sce.getCause() instanceof SecurityException) {
|
||||
// Ignore the security exception, try the next provider
|
||||
continue;
|
||||
}
|
||||
throw sce;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the system-wide default asynchronous channel provider for this
|
||||
* invocation of the Java virtual machine.
|
||||
*
|
||||
* <p> The first invocation of this method locates the default provider
|
||||
* object as follows: </p>
|
||||
*
|
||||
* <ol>
|
||||
*
|
||||
* <li><p> If the system property
|
||||
* {@code java.nio.channels.spi.AsynchronousChannelProvider} is defined
|
||||
* then it is taken to be the fully-qualified name of a concrete provider class.
|
||||
* The class is loaded and instantiated; if this process fails then an
|
||||
* unspecified error is thrown. </p></li>
|
||||
*
|
||||
* <li><p> If a provider class has been installed in a jar file that is
|
||||
* visible to the system class loader, and that jar file contains a
|
||||
* provider-configuration file named
|
||||
* {@code java.nio.channels.spi.AsynchronousChannelProvider} in the resource
|
||||
* directory {@code META-INF/services}, then the first class name
|
||||
* specified in that file is taken. The class is loaded and
|
||||
* instantiated; if this process fails then an unspecified error is
|
||||
* thrown. </p></li>
|
||||
*
|
||||
* <li><p> Finally, if no provider has been specified by any of the above
|
||||
* means then the system-default provider class is instantiated and the
|
||||
* result is returned. </p></li>
|
||||
*
|
||||
* </ol>
|
||||
*
|
||||
* <p> Subsequent invocations of this method return the provider that was
|
||||
* returned by the first invocation. </p>
|
||||
*
|
||||
* @return The system-wide default AsynchronousChannel provider
|
||||
*/
|
||||
public static AsynchronousChannelProvider provider() {
|
||||
return ProviderHolder.provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new asynchronous channel group with a fixed thread pool.
|
||||
*
|
||||
* @param nThreads
|
||||
* The number of threads in the pool
|
||||
* @param threadFactory
|
||||
* The factory to use when creating new threads
|
||||
*
|
||||
* @return A new asynchronous channel group
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* If {@code nThreads <= 0}
|
||||
* @throws IOException
|
||||
* If an I/O error occurs
|
||||
*
|
||||
* @see AsynchronousChannelGroup#withFixedThreadPool
|
||||
*/
|
||||
public abstract AsynchronousChannelGroup
|
||||
openAsynchronousChannelGroup(int nThreads, ThreadFactory threadFactory) throws IOException;
|
||||
|
||||
/**
|
||||
* Constructs a new asynchronous channel group with the given thread pool.
|
||||
*
|
||||
* @param executor
|
||||
* The thread pool
|
||||
* @param initialSize
|
||||
* A value {@code >=0} or a negative value for implementation
|
||||
* specific default
|
||||
*
|
||||
* @return A new asynchronous channel group
|
||||
*
|
||||
* @throws IOException
|
||||
* If an I/O error occurs
|
||||
*
|
||||
* @see AsynchronousChannelGroup#withCachedThreadPool
|
||||
*/
|
||||
public abstract AsynchronousChannelGroup
|
||||
openAsynchronousChannelGroup(ExecutorService executor, int initialSize) throws IOException;
|
||||
|
||||
/**
|
||||
* Opens an asynchronous server-socket channel.
|
||||
*
|
||||
* @param group
|
||||
* The group to which the channel is bound, or {@code null} to
|
||||
* bind to the default group
|
||||
*
|
||||
* @return The new channel
|
||||
*
|
||||
* @throws IllegalChannelGroupException
|
||||
* If the provider that created the group differs from this provider
|
||||
* @throws ShutdownChannelGroupException
|
||||
* The group is shutdown
|
||||
* @throws IOException
|
||||
* If an I/O error occurs
|
||||
*/
|
||||
public abstract AsynchronousServerSocketChannel openAsynchronousServerSocketChannel
|
||||
(AsynchronousChannelGroup group) throws IOException;
|
||||
|
||||
/**
|
||||
* Opens an asynchronous socket channel.
|
||||
*
|
||||
* @param group
|
||||
* The group to which the channel is bound, or {@code null} to
|
||||
* bind to the default group
|
||||
*
|
||||
* @return The new channel
|
||||
*
|
||||
* @throws IllegalChannelGroupException
|
||||
* If the provider that created the group differs from this provider
|
||||
* @throws ShutdownChannelGroupException
|
||||
* The group is shutdown
|
||||
* @throws IOException
|
||||
* If an I/O error occurs
|
||||
*/
|
||||
public abstract AsynchronousSocketChannel openAsynchronousSocketChannel
|
||||
(AsynchronousChannelGroup group) throws IOException;
|
||||
}
|
|
@ -0,0 +1,324 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2013, 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.net.ProtocolFamily;
|
||||
import java.nio.channels.*;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Iterator;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.ServiceConfigurationError;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
|
||||
/**
|
||||
* Service-provider class for selectors and selectable channels.
|
||||
*
|
||||
* <p> A selector provider is a concrete subclass of this class that has a
|
||||
* zero-argument constructor and implements the abstract methods specified
|
||||
* below. A given invocation of the Java virtual machine maintains a single
|
||||
* system-wide default provider instance, which is returned by the {@link
|
||||
* #provider() provider} method. The first invocation of that method will locate
|
||||
* the default provider as specified below.
|
||||
*
|
||||
* <p> The system-wide default provider is used by the static {@code open}
|
||||
* methods of the {@link java.nio.channels.DatagramChannel#open
|
||||
* DatagramChannel}, {@link java.nio.channels.Pipe#open Pipe}, {@link
|
||||
* java.nio.channels.Selector#open Selector}, {@link
|
||||
* java.nio.channels.ServerSocketChannel#open ServerSocketChannel}, and {@link
|
||||
* java.nio.channels.SocketChannel#open SocketChannel} classes. It is also
|
||||
* used by the {@link java.lang.System#inheritedChannel System.inheritedChannel()}
|
||||
* method. A program may make use of a provider other than the default provider
|
||||
* by instantiating that provider and then directly invoking the {@code open}
|
||||
* methods defined in this class.
|
||||
*
|
||||
* <p> All of the methods in this class are safe for use by multiple concurrent
|
||||
* threads. </p>
|
||||
*
|
||||
*
|
||||
* @author Mark Reinhold
|
||||
* @author JSR-51 Expert Group
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public abstract class SelectorProvider {
|
||||
|
||||
private static final Object lock = new Object();
|
||||
private static SelectorProvider provider = null;
|
||||
|
||||
private static Void checkPermission() {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null)
|
||||
sm.checkPermission(new RuntimePermission("selectorProvider"));
|
||||
return null;
|
||||
}
|
||||
private SelectorProvider(Void ignore) { }
|
||||
|
||||
/**
|
||||
* Initializes a new instance of this class.
|
||||
*
|
||||
* @throws SecurityException
|
||||
* If a security manager has been installed and it denies
|
||||
* {@link RuntimePermission}{@code ("selectorProvider")}
|
||||
*/
|
||||
protected SelectorProvider() {
|
||||
this(checkPermission());
|
||||
}
|
||||
|
||||
private static boolean loadProviderFromProperty() {
|
||||
String cn = System.getProperty("java.nio.channels.spi.SelectorProvider");
|
||||
if (cn == null)
|
||||
return false;
|
||||
try {
|
||||
@SuppressWarnings("deprecation")
|
||||
Object tmp = Class.forName(cn, true,
|
||||
ClassLoader.getSystemClassLoader()).newInstance();
|
||||
provider = (SelectorProvider)tmp;
|
||||
return true;
|
||||
} catch (ClassNotFoundException x) {
|
||||
throw new ServiceConfigurationError(null, x);
|
||||
} catch (IllegalAccessException x) {
|
||||
throw new ServiceConfigurationError(null, x);
|
||||
} catch (InstantiationException x) {
|
||||
throw new ServiceConfigurationError(null, x);
|
||||
} catch (SecurityException x) {
|
||||
throw new ServiceConfigurationError(null, x);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean loadProviderAsService() {
|
||||
|
||||
ServiceLoader<SelectorProvider> sl =
|
||||
ServiceLoader.load(SelectorProvider.class,
|
||||
ClassLoader.getSystemClassLoader());
|
||||
Iterator<SelectorProvider> i = sl.iterator();
|
||||
for (;;) {
|
||||
try {
|
||||
if (!i.hasNext())
|
||||
return false;
|
||||
provider = i.next();
|
||||
return true;
|
||||
} catch (ServiceConfigurationError sce) {
|
||||
if (sce.getCause() instanceof SecurityException) {
|
||||
// Ignore the security exception, try the next provider
|
||||
continue;
|
||||
}
|
||||
throw sce;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the system-wide default selector provider for this invocation of
|
||||
* the Java virtual machine.
|
||||
*
|
||||
* <p> The first invocation of this method locates the default provider
|
||||
* object as follows: </p>
|
||||
*
|
||||
* <ol>
|
||||
*
|
||||
* <li><p> If the system property
|
||||
* {@code java.nio.channels.spi.SelectorProvider} is defined then it is
|
||||
* taken to be the fully-qualified name of a concrete provider class.
|
||||
* The class is loaded and instantiated; if this process fails then an
|
||||
* unspecified error is thrown. </p></li>
|
||||
*
|
||||
* <li><p> If a provider class has been installed in a jar file that is
|
||||
* visible to the system class loader, and that jar file contains a
|
||||
* provider-configuration file named
|
||||
* {@code java.nio.channels.spi.SelectorProvider} in the resource
|
||||
* directory {@code META-INF/services}, then the first class name
|
||||
* specified in that file is taken. The class is loaded and
|
||||
* instantiated; if this process fails then an unspecified error is
|
||||
* thrown. </p></li>
|
||||
*
|
||||
* <li><p> Finally, if no provider has been specified by any of the above
|
||||
* means then the system-default provider class is instantiated and the
|
||||
* result is returned. </p></li>
|
||||
*
|
||||
* </ol>
|
||||
*
|
||||
* <p> Subsequent invocations of this method return the provider that was
|
||||
* returned by the first invocation. </p>
|
||||
*
|
||||
* @return The system-wide default selector provider
|
||||
*/
|
||||
public static SelectorProvider provider() {
|
||||
synchronized (lock) {
|
||||
if (provider != null)
|
||||
return provider;
|
||||
return AccessController.doPrivileged(
|
||||
new PrivilegedAction<>() {
|
||||
public SelectorProvider run() {
|
||||
if (loadProviderFromProperty())
|
||||
return provider;
|
||||
if (loadProviderAsService())
|
||||
return provider;
|
||||
provider = sun.nio.ch.DefaultSelectorProvider.create();
|
||||
return provider;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a datagram channel.
|
||||
*
|
||||
* @return The new channel
|
||||
*
|
||||
* @throws IOException
|
||||
* If an I/O error occurs
|
||||
*/
|
||||
public abstract DatagramChannel openDatagramChannel()
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Opens a datagram channel.
|
||||
*
|
||||
* @param family
|
||||
* The protocol family
|
||||
*
|
||||
* @return A new datagram channel
|
||||
*
|
||||
* @throws UnsupportedOperationException
|
||||
* If the specified protocol family is not supported
|
||||
* @throws IOException
|
||||
* If an I/O error occurs
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public abstract DatagramChannel openDatagramChannel(ProtocolFamily family)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Opens a pipe.
|
||||
*
|
||||
* @return The new pipe
|
||||
*
|
||||
* @throws IOException
|
||||
* If an I/O error occurs
|
||||
*/
|
||||
public abstract Pipe openPipe()
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Opens a selector.
|
||||
*
|
||||
* @return The new selector
|
||||
*
|
||||
* @throws IOException
|
||||
* If an I/O error occurs
|
||||
*/
|
||||
public abstract AbstractSelector openSelector()
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Opens a server-socket channel.
|
||||
*
|
||||
* @return The new channel
|
||||
*
|
||||
* @throws IOException
|
||||
* If an I/O error occurs
|
||||
*/
|
||||
public abstract ServerSocketChannel openServerSocketChannel()
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Opens a socket channel.
|
||||
*
|
||||
* @return The new channel
|
||||
*
|
||||
* @throws IOException
|
||||
* If an I/O error occurs
|
||||
*/
|
||||
public abstract SocketChannel openSocketChannel()
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Returns the channel inherited from the entity that created this
|
||||
* Java virtual machine.
|
||||
*
|
||||
* <p> On many operating systems a process, such as a Java virtual
|
||||
* machine, can be started in a manner that allows the process to
|
||||
* inherit a channel from the entity that created the process. The
|
||||
* manner in which this is done is system dependent, as are the
|
||||
* possible entities to which the channel may be connected. For example,
|
||||
* on UNIX systems, the Internet services daemon (<i>inetd</i>) is used to
|
||||
* start programs to service requests when a request arrives on an
|
||||
* associated network port. In this example, the process that is started,
|
||||
* inherits a channel representing a network socket.
|
||||
*
|
||||
* <p> In cases where the inherited channel represents a network socket
|
||||
* then the {@link java.nio.channels.Channel Channel} type returned
|
||||
* by this method is determined as follows:
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li><p> If the inherited channel represents a stream-oriented connected
|
||||
* socket then a {@link java.nio.channels.SocketChannel SocketChannel} is
|
||||
* returned. The socket channel is, at least initially, in blocking
|
||||
* mode, bound to a socket address, and connected to a peer.
|
||||
* </p></li>
|
||||
*
|
||||
* <li><p> If the inherited channel represents a stream-oriented listening
|
||||
* socket then a {@link java.nio.channels.ServerSocketChannel
|
||||
* ServerSocketChannel} is returned. The server-socket channel is, at
|
||||
* least initially, in blocking mode, and bound to a socket address.
|
||||
* </p></li>
|
||||
*
|
||||
* <li><p> If the inherited channel is a datagram-oriented socket
|
||||
* then a {@link java.nio.channels.DatagramChannel DatagramChannel} is
|
||||
* returned. The datagram channel is, at least initially, in blocking
|
||||
* mode, and bound to a socket address.
|
||||
* </p></li>
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* <p> In addition to the network-oriented channels described, this method
|
||||
* may return other kinds of channels in the future.
|
||||
*
|
||||
* <p> The first invocation of this method creates the channel that is
|
||||
* returned. Subsequent invocations of this method return the same
|
||||
* channel. </p>
|
||||
*
|
||||
* @return The inherited channel, if any, otherwise {@code null}.
|
||||
*
|
||||
* @throws IOException
|
||||
* If an I/O error occurs
|
||||
*
|
||||
* @throws SecurityException
|
||||
* If a security manager has been installed and it denies
|
||||
* {@link RuntimePermission}{@code ("inheritedChannel")}
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public Channel inheritedChannel() throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2009, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Service-provider classes for the {@link java.nio.channels}
|
||||
* package.
|
||||
*
|
||||
* <p> Only developers who are defining new selector providers or
|
||||
* asynchronous channel providers should need to make direct use of
|
||||
* this package. </p>
|
||||
*
|
||||
* <p> Unless otherwise noted, passing a {@code null} argument to a
|
||||
* constructor or method in any class or interface in this package
|
||||
* will cause a {@link java.lang.NullPointerException
|
||||
* NullPointerException} to be thrown.
|
||||
*
|
||||
*
|
||||
* @since 1.4
|
||||
* @author Mark Reinhold
|
||||
* @author JSR-51 Expert Group
|
||||
*/
|
||||
package java.nio.channels.spi;
|
Loading…
Add table
Add a link
Reference in a new issue