8187443: Forest Consolidation: Move files to unified layout

Reviewed-by: darcy, ihse
This commit is contained in:
Erik Joelsson 2017-09-12 19:03:39 +02:00
parent 270fe13182
commit 3789983e89
56923 changed files with 3 additions and 15727 deletions

View file

@ -0,0 +1,213 @@
/*
* 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;
import java.nio.ByteBuffer;
import java.util.concurrent.Future;
/**
* An asynchronous channel that can read and write bytes.
*
* <p> Some channels may not allow more than one read or write to be outstanding
* at any given time. If a thread invokes a read method before a previous read
* operation has completed then a {@link ReadPendingException} will be thrown.
* Similarly, if a write method is invoked before a previous write has completed
* then {@link WritePendingException} is thrown. Whether or not other kinds of
* I/O operations may proceed concurrently with a read operation depends upon
* the type of the channel.
*
* <p> Note that {@link java.nio.ByteBuffer ByteBuffers} are not safe for use by
* multiple concurrent threads. When a read or write operation is initiated then
* care must be taken to ensure that the buffer is not accessed until the
* operation completes.
*
* @see Channels#newInputStream(AsynchronousByteChannel)
* @see Channels#newOutputStream(AsynchronousByteChannel)
*
* @since 1.7
*/
public interface AsynchronousByteChannel
extends AsynchronousChannel
{
/**
* Reads a sequence of bytes from this channel into the given buffer.
*
* <p> This method initiates an asynchronous read operation to read a
* sequence of bytes from this channel into the given buffer. The {@code
* handler} parameter is a completion handler that is invoked when the read
* operation completes (or fails). The result passed to the completion
* handler is the number of bytes read or {@code -1} if no bytes could be
* read because the channel has reached end-of-stream.
*
* <p> The read operation may read up to <i>r</i> bytes from the channel,
* where <i>r</i> is the number of bytes remaining in the buffer, that is,
* {@code dst.remaining()} at the time that the read is attempted. Where
* <i>r</i> is 0, the read operation completes immediately with a result of
* {@code 0} without initiating an I/O operation.
*
* <p> Suppose that a byte sequence of length <i>n</i> is read, where
* {@code 0}&nbsp;{@code <}&nbsp;<i>n</i>&nbsp;{@code <=}&nbsp;<i>r</i>.
* This byte sequence will be transferred into the buffer so that the first
* byte in the sequence is at index <i>p</i> and the last byte is at index
* <i>p</i>&nbsp;{@code +}&nbsp;<i>n</i>&nbsp;{@code -}&nbsp;{@code 1},
* where <i>p</i> is the buffer's position at the moment the read is
* performed. Upon completion the buffer's position will be equal to
* <i>p</i>&nbsp;{@code +}&nbsp;<i>n</i>; its limit will not have changed.
*
* <p> Buffers are not safe for use by multiple concurrent threads so care
* should be taken to not access the buffer until the operation has
* completed.
*
* <p> This method may be invoked at any time. Some channel types may not
* allow more than one read to be outstanding at any given time. If a thread
* initiates a read operation before a previous read operation has
* completed then a {@link ReadPendingException} will be thrown.
*
* @param <A>
* The type of the attachment
* @param dst
* The buffer into which bytes are to be transferred
* @param attachment
* The object to attach to the I/O operation; can be {@code null}
* @param handler
* The completion handler
*
* @throws IllegalArgumentException
* If the buffer is read-only
* @throws ReadPendingException
* If the channel does not allow more than one read to be outstanding
* and a previous read has not completed
* @throws ShutdownChannelGroupException
* If the channel is associated with a {@link AsynchronousChannelGroup
* group} that has terminated
*/
<A> void read(ByteBuffer dst,
A attachment,
CompletionHandler<Integer,? super A> handler);
/**
* Reads a sequence of bytes from this channel into the given buffer.
*
* <p> This method initiates an asynchronous read operation to read a
* sequence of bytes from this channel into the given buffer. The method
* behaves in exactly the same manner as the {@link
* #read(ByteBuffer,Object,CompletionHandler)
* read(ByteBuffer,Object,CompletionHandler)} method except that instead
* of specifying a completion handler, this method returns a {@code Future}
* representing the pending result. The {@code Future}'s {@link Future#get()
* get} method returns the number of bytes read or {@code -1} if no bytes
* could be read because the channel has reached end-of-stream.
*
* @param dst
* The buffer into which bytes are to be transferred
*
* @return A Future representing the result of the operation
*
* @throws IllegalArgumentException
* If the buffer is read-only
* @throws ReadPendingException
* If the channel does not allow more than one read to be outstanding
* and a previous read has not completed
*/
Future<Integer> read(ByteBuffer dst);
/**
* Writes a sequence of bytes to this channel from the given buffer.
*
* <p> This method initiates an asynchronous write operation to write a
* sequence of bytes to this channel from the given buffer. The {@code
* handler} parameter is a completion handler that is invoked when the write
* operation completes (or fails). The result passed to the completion
* handler is the number of bytes written.
*
* <p> The write operation may write up to <i>r</i> bytes to the channel,
* where <i>r</i> is the number of bytes remaining in the buffer, that is,
* {@code src.remaining()} at the time that the write is attempted. Where
* <i>r</i> is 0, the write operation completes immediately with a result of
* {@code 0} without initiating an I/O operation.
*
* <p> Suppose that a byte sequence of length <i>n</i> is written, where
* {@code 0}&nbsp;{@code <}&nbsp;<i>n</i>&nbsp;{@code <=}&nbsp;<i>r</i>.
* This byte sequence will be transferred from the buffer starting at index
* <i>p</i>, where <i>p</i> is the buffer's position at the moment the
* write is performed; the index of the last byte written will be
* <i>p</i>&nbsp;{@code +}&nbsp;<i>n</i>&nbsp;{@code -}&nbsp;{@code 1}.
* Upon completion the buffer's position will be equal to
* <i>p</i>&nbsp;{@code +}&nbsp;<i>n</i>; its limit will not have changed.
*
* <p> Buffers are not safe for use by multiple concurrent threads so care
* should be taken to not access the buffer until the operation has
* completed.
*
* <p> This method may be invoked at any time. Some channel types may not
* allow more than one write to be outstanding at any given time. If a thread
* initiates a write operation before a previous write operation has
* completed then a {@link WritePendingException} will be thrown.
*
* @param <A>
* The type of the attachment
* @param src
* The buffer from which bytes are to be retrieved
* @param attachment
* The object to attach to the I/O operation; can be {@code null}
* @param handler
* The completion handler object
*
* @throws WritePendingException
* If the channel does not allow more than one write to be outstanding
* and a previous write has not completed
* @throws ShutdownChannelGroupException
* If the channel is associated with a {@link AsynchronousChannelGroup
* group} that has terminated
*/
<A> void write(ByteBuffer src,
A attachment,
CompletionHandler<Integer,? super A> handler);
/**
* Writes a sequence of bytes to this channel from the given buffer.
*
* <p> This method initiates an asynchronous write operation to write a
* sequence of bytes to this channel from the given buffer. The method
* behaves in exactly the same manner as the {@link
* #write(ByteBuffer,Object,CompletionHandler)
* write(ByteBuffer,Object,CompletionHandler)} method except that instead
* of specifying a completion handler, this method returns a {@code Future}
* representing the pending result. The {@code Future}'s {@link Future#get()
* get} method returns the number of bytes written.
*
* @param src
* The buffer from which bytes are to be retrieved
*
* @return A Future representing the result of the operation
*
* @throws WritePendingException
* If the channel does not allow more than one write to be outstanding
* and a previous write has not completed
*/
Future<Integer> write(ByteBuffer src);
}

View file

@ -0,0 +1,117 @@
/*
* 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;
import java.io.IOException;
import java.util.concurrent.Future; // javadoc
/**
* A channel that supports asynchronous I/O operations. Asynchronous I/O
* operations will usually take one of two forms:
*
* <ol>
* <li><pre>{@link Future}&lt;V&gt; <em>operation</em>(<em>...</em>)</pre></li>
* <li><pre>void <em>operation</em>(<em>...</em> A attachment, {@link
* CompletionHandler}&lt;V,? super A&gt; handler)</pre></li>
* </ol>
*
* where <i>operation</i> is the name of the I/O operation (read or write for
* example), <i>V</i> is the result type of the I/O operation, and <i>A</i> is
* the type of an object attached to the I/O operation to provide context when
* consuming the result. The attachment is important for cases where a
* <em>state-less</em> {@code CompletionHandler} is used to consume the result
* of many I/O operations.
*
* <p> In the first form, the methods defined by the {@link Future Future}
* interface may be used to check if the operation has completed, wait for its
* completion, and to retrieve the result. In the second form, a {@link
* CompletionHandler} is invoked to consume the result of the I/O operation when
* it completes or fails.
*
* <p> A channel that implements this interface is <em>asynchronously
* closeable</em>: If an I/O operation is outstanding on the channel and the
* channel's {@link #close close} method is invoked, then the I/O operation
* fails with the exception {@link AsynchronousCloseException}.
*
* <p> Asynchronous channels are safe for use by multiple concurrent threads.
* Some channel implementations may support concurrent reading and writing, but
* may not allow more than one read and one write operation to be outstanding at
* any given time.
*
* <h2>Cancellation</h2>
*
* <p> The {@code Future} interface defines the {@link Future#cancel cancel}
* method to cancel execution. This causes all threads waiting on the result of
* the I/O operation to throw {@link java.util.concurrent.CancellationException}.
* Whether the underlying I/O operation can be cancelled is highly implementation
* specific and therefore not specified. Where cancellation leaves the channel,
* or the entity to which it is connected, in an inconsistent state, then the
* channel is put into an implementation specific <em>error state</em> that
* prevents further attempts to initiate I/O operations that are <i>similar</i>
* to the operation that was cancelled. For example, if a read operation is
* cancelled but the implementation cannot guarantee that bytes have not been
* read from the channel then it puts the channel into an error state; further
* attempts to initiate a {@code read} operation cause an unspecified runtime
* exception to be thrown. Similarly, if a write operation is cancelled but the
* implementation cannot guarantee that bytes have not been written to the
* channel then subsequent attempts to initiate a {@code write} will fail with
* an unspecified runtime exception.
*
* <p> Where the {@link Future#cancel cancel} method is invoked with the {@code
* mayInterruptIfRunning} parameter set to {@code true} then the I/O operation
* may be interrupted by closing the channel. In that case all threads waiting
* on the result of the I/O operation throw {@code CancellationException} and
* any other I/O operations outstanding on the channel complete with the
* exception {@link AsynchronousCloseException}.
*
* <p> Where the {@code cancel} method is invoked to cancel read or write
* operations then it is recommended that all buffers used in the I/O operations
* be discarded or care taken to ensure that the buffers are not accessed while
* the channel remains open.
*
* @since 1.7
*/
public interface AsynchronousChannel
extends Channel
{
/**
* Closes this channel.
*
* <p> Any outstanding asynchronous operations upon this channel will
* complete with the exception {@link AsynchronousCloseException}. After a
* channel is closed, further attempts to initiate asynchronous I/O
* operations complete immediately with cause {@link ClosedChannelException}.
*
* <p> This method otherwise behaves exactly as specified by the {@link
* Channel} interface.
*
* @throws IOException
* If an I/O error occurs
*/
@Override
void close() throws IOException;
}

View file

@ -0,0 +1,348 @@
/*
* Copyright (c) 2007, 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;
import java.nio.channels.spi.AsynchronousChannelProvider;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
/**
* A grouping of asynchronous channels for the purpose of resource sharing.
*
* <p> An asynchronous channel group encapsulates the mechanics required to
* handle the completion of I/O operations initiated by {@link AsynchronousChannel
* asynchronous channels} that are bound to the group. A group has an associated
* thread pool to which tasks are submitted to handle I/O events and dispatch to
* {@link CompletionHandler completion-handlers} that consume the result of
* asynchronous operations performed on channels in the group. In addition to
* handling I/O events, the pooled threads may also execute other tasks required
* to support the execution of asynchronous I/O operations.
*
* <p> An asynchronous channel group is created by invoking the {@link
* #withFixedThreadPool withFixedThreadPool} or {@link #withCachedThreadPool
* withCachedThreadPool} methods defined here. Channels are bound to a group by
* specifying the group when constructing the channel. The associated thread
* pool is <em>owned</em> by the group; termination of the group results in the
* shutdown of the associated thread pool.
*
* <p> In addition to groups created explicitly, the Java virtual machine
* maintains a system-wide <em>default group</em> that is constructed
* automatically. Asynchronous channels that do not specify a group at
* construction time are bound to the default group. The default group has an
* associated thread pool that creates new threads as needed. The default group
* may be configured by means of system properties defined in the table below.
* Where the {@link java.util.concurrent.ThreadFactory ThreadFactory} for the
* default group is not configured then the pooled threads of the default group
* are {@link Thread#isDaemon daemon} threads.
*
* <table class="striped">
* <caption style="display:none:">System properties</caption>
* <thead>
* <tr>
* <th scope="col">System property</th>
* <th scope="col">Description</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <th scope="row"> {@code java.nio.channels.DefaultThreadPool.threadFactory} </th>
* <td> The value of this property is taken to be the fully-qualified name
* of a concrete {@link java.util.concurrent.ThreadFactory ThreadFactory}
* class. The class is loaded using the system class loader and instantiated.
* The factory's {@link java.util.concurrent.ThreadFactory#newThread
* newThread} method is invoked to create each thread for the default
* group's thread pool. If the process to load and instantiate the value
* of the property fails then an unspecified error is thrown during the
* construction of the default group. </td>
* </tr>
* <tr>
* <th scope="row"> {@code java.nio.channels.DefaultThreadPool.initialSize} </th>
* <td> The value of the {@code initialSize} parameter for the default
* group (see {@link #withCachedThreadPool withCachedThreadPool}).
* The value of the property is taken to be the {@code String}
* representation of an {@code Integer} that is the initial size parameter.
* If the value cannot be parsed as an {@code Integer} it causes an
* unspecified error to be thrown during the construction of the default
* group. </td>
* </tr>
* </tbody>
* </table>
*
* <a id="threading"></a><h2>Threading</h2>
*
* <p> The completion handler for an I/O operation initiated on a channel bound
* to a group is guaranteed to be invoked by one of the pooled threads in the
* group. This ensures that the completion handler is run by a thread with the
* expected <em>identity</em>.
*
* <p> Where an I/O operation completes immediately, and the initiating thread
* is one of the pooled threads in the group then the completion handler may
* be invoked directly by the initiating thread. To avoid stack overflow, an
* implementation may impose a limit as to the number of activations on the
* thread stack. Some I/O operations may prohibit invoking the completion
* handler directly by the initiating thread (see {@link
* AsynchronousServerSocketChannel#accept(Object,CompletionHandler) accept}).
*
* <a id="shutdown"></a><h2>Shutdown and Termination</h2>
*
* <p> The {@link #shutdown() shutdown} method is used to initiate an <em>orderly
* shutdown</em> of a group. An orderly shutdown marks the group as shutdown;
* further attempts to construct a channel that binds to the group will throw
* {@link ShutdownChannelGroupException}. Whether or not a group is shutdown can
* be tested using the {@link #isShutdown() isShutdown} method. Once shutdown,
* the group <em>terminates</em> when all asynchronous channels that are bound to
* the group are closed, all actively executing completion handlers have run to
* completion, and resources used by the group are released. No attempt is made
* to stop or interrupt threads that are executing completion handlers. The
* {@link #isTerminated() isTerminated} method is used to test if the group has
* terminated, and the {@link #awaitTermination awaitTermination} method can be
* used to block until the group has terminated.
*
* <p> The {@link #shutdownNow() shutdownNow} method can be used to initiate a
* <em>forceful shutdown</em> of the group. In addition to the actions performed
* by an orderly shutdown, the {@code shutdownNow} method closes all open channels
* in the group as if by invoking the {@link AsynchronousChannel#close close}
* method.
*
* @since 1.7
*
* @see AsynchronousSocketChannel#open(AsynchronousChannelGroup)
* @see AsynchronousServerSocketChannel#open(AsynchronousChannelGroup)
*/
public abstract class AsynchronousChannelGroup {
private final AsynchronousChannelProvider provider;
/**
* Initialize a new instance of this class.
*
* @param provider
* The asynchronous channel provider for this group
*/
protected AsynchronousChannelGroup(AsynchronousChannelProvider provider) {
this.provider = provider;
}
/**
* Returns the provider that created this channel group.
*
* @return The provider that created this channel group
*/
public final AsynchronousChannelProvider provider() {
return provider;
}
/**
* Creates an asynchronous channel group with a fixed thread pool.
*
* <p> The resulting asynchronous channel group reuses a fixed number of
* threads. At any point, at most {@code nThreads} threads will be active
* processing tasks that are submitted to handle I/O events and dispatch
* completion results for operations initiated on asynchronous channels in
* the group.
*
* <p> The group is created by invoking the {@link
* AsynchronousChannelProvider#openAsynchronousChannelGroup(int,ThreadFactory)
* openAsynchronousChannelGroup(int,ThreadFactory)} method of the system-wide
* default {@link AsynchronousChannelProvider} object.
*
* @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
*/
public static AsynchronousChannelGroup withFixedThreadPool(int nThreads,
ThreadFactory threadFactory)
throws IOException
{
return AsynchronousChannelProvider.provider()
.openAsynchronousChannelGroup(nThreads, threadFactory);
}
/**
* Creates an asynchronous channel group with a given thread pool that
* creates new threads as needed.
*
* <p> The {@code executor} parameter is an {@code ExecutorService} that
* creates new threads as needed to execute tasks that are submitted to
* handle I/O events and dispatch completion results for operations initiated
* on asynchronous channels in the group. It may reuse previously constructed
* threads when they are available.
*
* <p> The {@code initialSize} parameter may be used by the implementation
* as a <em>hint</em> as to the initial number of tasks it may submit. For
* example, it may be used to indicate the initial number of threads that
* wait on I/O events.
*
* <p> The executor is intended to be used exclusively by the resulting
* asynchronous channel group. Termination of the group results in the
* orderly {@link ExecutorService#shutdown shutdown} of the executor
* service. Shutting down the executor service by other means results in
* unspecified behavior.
*
* <p> The group is created by invoking the {@link
* AsynchronousChannelProvider#openAsynchronousChannelGroup(ExecutorService,int)
* openAsynchronousChannelGroup(ExecutorService,int)} method of the system-wide
* default {@link AsynchronousChannelProvider} object.
*
* @param executor
* The thread pool for the resulting group
* @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 java.util.concurrent.Executors#newCachedThreadPool
*/
public static AsynchronousChannelGroup withCachedThreadPool(ExecutorService executor,
int initialSize)
throws IOException
{
return AsynchronousChannelProvider.provider()
.openAsynchronousChannelGroup(executor, initialSize);
}
/**
* Creates an asynchronous channel group with a given thread pool.
*
* <p> The {@code executor} parameter is an {@code ExecutorService} that
* executes tasks submitted to dispatch completion results for operations
* initiated on asynchronous channels in the group.
*
* <p> Care should be taken when configuring the executor service. It
* should support <em>direct handoff</em> or <em>unbounded queuing</em> of
* submitted tasks, and the thread that invokes the {@link
* ExecutorService#execute execute} method should never invoke the task
* directly. An implementation may mandate additional constraints.
*
* <p> The executor is intended to be used exclusively by the resulting
* asynchronous channel group. Termination of the group results in the
* orderly {@link ExecutorService#shutdown shutdown} of the executor
* service. Shutting down the executor service by other means results in
* unspecified behavior.
*
* <p> The group is created by invoking the {@link
* AsynchronousChannelProvider#openAsynchronousChannelGroup(ExecutorService,int)
* openAsynchronousChannelGroup(ExecutorService,int)} method of the system-wide
* default {@link AsynchronousChannelProvider} object with an {@code
* initialSize} of {@code 0}.
*
* @param executor
* The thread pool for the resulting group
*
* @return A new asynchronous channel group
*
* @throws IOException
* If an I/O error occurs
*/
public static AsynchronousChannelGroup withThreadPool(ExecutorService executor)
throws IOException
{
return AsynchronousChannelProvider.provider()
.openAsynchronousChannelGroup(executor, 0);
}
/**
* Tells whether or not this asynchronous channel group is shutdown.
*
* @return {@code true} if this asynchronous channel group is shutdown or
* has been marked for shutdown.
*/
public abstract boolean isShutdown();
/**
* Tells whether or not this group has terminated.
*
* <p> Where this method returns {@code true}, then the associated thread
* pool has also {@link ExecutorService#isTerminated terminated}.
*
* @return {@code true} if this group has terminated
*/
public abstract boolean isTerminated();
/**
* Initiates an orderly shutdown of the group.
*
* <p> This method marks the group as shutdown. Further attempts to construct
* channel that binds to this group will throw {@link ShutdownChannelGroupException}.
* The group terminates when all asynchronous channels in the group are
* closed, all actively executing completion handlers have run to completion,
* and all resources have been released. This method has no effect if the
* group is already shutdown.
*/
public abstract void shutdown();
/**
* Shuts down the group and closes all open channels in the group.
*
* <p> In addition to the actions performed by the {@link #shutdown() shutdown}
* method, this method invokes the {@link AsynchronousChannel#close close}
* method on all open channels in the group. This method does not attempt to
* stop or interrupt threads that are executing completion handlers. The
* group terminates when all actively executing completion handlers have run
* to completion and all resources have been released. This method may be
* invoked at any time. If some other thread has already invoked it, then
* another invocation will block until the first invocation is complete,
* after which it will return without effect.
*
* @throws IOException
* If an I/O error occurs
*/
public abstract void shutdownNow() throws IOException;
/**
* Awaits termination of the group.
* <p> This method blocks until the group has terminated, or the timeout
* occurs, or the current thread is interrupted, whichever happens first.
*
* @param timeout
* The maximum time to wait, or zero or less to not wait
* @param unit
* The time unit of the timeout argument
*
* @return {@code true} if the group has terminated; {@code false} if the
* timeout elapsed before termination
*
* @throws InterruptedException
* If interrupted while waiting
*/
public abstract boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
}

View file

@ -0,0 +1,784 @@
/*
* Copyright (c) 2007, 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;
import java.nio.file.*;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.spi.*;
import java.nio.ByteBuffer;
import java.io.IOException;
import java.util.concurrent.Future;
import java.util.concurrent.ExecutorService;
import java.util.Set;
import java.util.HashSet;
import java.util.Collections;
/**
* An asynchronous channel for reading, writing, and manipulating a file.
*
* <p> An asynchronous file channel is created when a file is opened by invoking
* one of the {@link #open open} methods defined by this class. The file contains
* a variable-length sequence of bytes that can be read and written and whose
* current size can be {@link #size() queried}. The size of the file increases
* when bytes are written beyond its current size; the size of the file decreases
* when it is {@link #truncate truncated}.
*
* <p> An asynchronous file channel does not have a <i>current position</i>
* within the file. Instead, the file position is specified to each read and
* write method that initiates asynchronous operations. A {@link CompletionHandler}
* is specified as a parameter and is invoked to consume the result of the I/O
* operation. This class also defines read and write methods that initiate
* asynchronous operations, returning a {@link Future} to represent the pending
* result of the operation. The {@code Future} may be used to check if the
* operation has completed, wait for its completion, and retrieve the result.
*
* <p> In addition to read and write operations, this class defines the
* following operations: </p>
*
* <ul>
*
* <li><p> Updates made to a file may be {@link #force <i>forced
* out</i>} to the underlying storage device, ensuring that data are not
* lost in the event of a system crash. </p></li>
*
* <li><p> A region of a file may be {@link #lock <i>locked</i>} against
* access by other programs. </p></li>
*
* </ul>
*
* <p> An {@code AsynchronousFileChannel} is associated with a thread pool to
* which tasks are submitted to handle I/O events and dispatch to completion
* handlers that consume the results of I/O operations on the channel. The
* completion handler for an I/O operation initiated on a channel is guaranteed
* to be invoked by one of the threads in the thread pool (This ensures that the
* completion handler is run by a thread with the expected <em>identity</em>).
* Where an I/O operation completes immediately, and the initiating thread is
* itself a thread in the thread pool, then the completion handler may be invoked
* directly by the initiating thread. When an {@code AsynchronousFileChannel} is
* created without specifying a thread pool then the channel is associated with
* a system-dependent default thread pool that may be shared with other
* channels. The default thread pool is configured by the system properties
* defined by the {@link AsynchronousChannelGroup} class.
*
* <p> Channels of this type are safe for use by multiple concurrent threads. The
* {@link Channel#close close} method may be invoked at any time, as specified
* by the {@link Channel} interface. This causes all outstanding asynchronous
* operations on the channel to complete with the exception {@link
* AsynchronousCloseException}. Multiple read and write operations may be
* outstanding at the same time. When multiple read and write operations are
* outstanding then the ordering of the I/O operations, and the order that the
* completion handlers are invoked, is not specified; they are not, in particular,
* guaranteed to execute in the order that the operations were initiated. The
* {@link java.nio.ByteBuffer ByteBuffers} used when reading or writing are not
* safe for use by multiple concurrent I/O operations. Furthermore, after an I/O
* operation is initiated then care should be taken to ensure that the buffer is
* not accessed until after the operation has completed.
*
* <p> As with {@link FileChannel}, the view of a file provided by an instance of
* this class is guaranteed to be consistent with other views of the same file
* provided by other instances in the same program. The view provided by an
* instance of this class may or may not, however, be consistent with the views
* seen by other concurrently-running programs due to caching performed by the
* underlying operating system and delays induced by network-filesystem protocols.
* This is true regardless of the language in which these other programs are
* written, and whether they are running on the same machine or on some other
* machine. The exact nature of any such inconsistencies are system-dependent
* and are therefore unspecified.
*
* @since 1.7
*/
public abstract class AsynchronousFileChannel
implements AsynchronousChannel
{
/**
* Initializes a new instance of this class.
*/
protected AsynchronousFileChannel() {
}
/**
* Opens or creates a file for reading and/or writing, returning an
* asynchronous file channel to access the file.
*
* <p> The {@code options} parameter determines how the file is opened.
* The {@link StandardOpenOption#READ READ} and {@link StandardOpenOption#WRITE
* WRITE} options determines if the file should be opened for reading and/or
* writing. If neither option is contained in the array then an existing file
* is opened for reading.
*
* <p> In addition to {@code READ} and {@code WRITE}, the following options
* may be present:
*
* <table class="striped">
* <caption style="display:none">additional options</caption>
* <thead>
* <tr> <th scope="col">Option</th> <th scope="col">Description</th> </tr>
* </thead>
* <tbody>
* <tr>
* <th scope="row"> {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING} </th>
* <td> When opening an existing file, the file is first truncated to a
* size of 0 bytes. This option is ignored when the file is opened only
* for reading.</td>
* </tr>
* <tr>
* <th scope="row"> {@link StandardOpenOption#CREATE_NEW CREATE_NEW} </th>
* <td> If this option is present then a new file is created, failing if
* the file already exists. When creating a file the check for the
* existence of the file and the creation of the file if it does not exist
* is atomic with respect to other file system operations. This option is
* ignored when the file is opened only for reading. </td>
* </tr>
* <tr>
* <th scope="row" > {@link StandardOpenOption#CREATE CREATE} </th>
* <td> If this option is present then an existing file is opened if it
* exists, otherwise a new file is created. When creating a file the check
* for the existence of the file and the creation of the file if it does
* not exist is atomic with respect to other file system operations. This
* option is ignored if the {@code CREATE_NEW} option is also present or
* the file is opened only for reading. </td>
* </tr>
* <tr>
* <th scope="row" > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </th>
* <td> When this option is present then the implementation makes a
* <em>best effort</em> attempt to delete the file when closed by the
* the {@link #close close} method. If the {@code close} method is not
* invoked then a <em>best effort</em> attempt is made to delete the file
* when the Java virtual machine terminates. </td>
* </tr>
* <tr>
* <th scope="row">{@link StandardOpenOption#SPARSE SPARSE} </th>
* <td> When creating a new file this option is a <em>hint</em> that the
* new file will be sparse. This option is ignored when not creating
* a new file. </td>
* </tr>
* <tr>
* <th scope="row"> {@link StandardOpenOption#SYNC SYNC} </th>
* <td> Requires that every update to the file's content or metadata be
* written synchronously to the underlying storage device. (see <a
* href="../file/package-summary.html#integrity"> Synchronized I/O file
* integrity</a>). </td>
* </tr>
* <tr>
* <th scope="row"> {@link StandardOpenOption#DSYNC DSYNC} </th>
* <td> Requires that every update to the file's content be written
* synchronously to the underlying storage device. (see <a
* href="../file/package-summary.html#integrity"> Synchronized I/O file
* integrity</a>). </td>
* </tr>
* </tbody>
* </table>
*
* <p> An implementation may also support additional options.
*
* <p> The {@code executor} parameter is the {@link ExecutorService} to
* which tasks are submitted to handle I/O events and dispatch completion
* results for operations initiated on resulting channel.
* The nature of these tasks is highly implementation specific and so care
* should be taken when configuring the {@code Executor}. Minimally it
* should support an unbounded work queue and should not run tasks on the
* caller thread of the {@link ExecutorService#execute execute} method.
* Shutting down the executor service while the channel is open results in
* unspecified behavior.
*
* <p> The {@code attrs} parameter is an optional array of file {@link
* FileAttribute file-attributes} to set atomically when creating the file.
*
* <p> The new channel is created by invoking the {@link
* FileSystemProvider#newFileChannel newFileChannel} method on the
* provider that created the {@code Path}.
*
* @param file
* The path of the file to open or create
* @param options
* Options specifying how the file is opened
* @param executor
* The thread pool or {@code null} to associate the channel with
* the default thread pool
* @param attrs
* An optional list of file attributes to set atomically when
* creating the file
*
* @return A new asynchronous file channel
*
* @throws IllegalArgumentException
* If the set contains an invalid combination of options
* @throws UnsupportedOperationException
* If the {@code file} is associated with a provider that does not
* support creating asynchronous file channels, or an unsupported
* open option is specified, or the array contains an attribute that
* cannot be set atomically when creating the file
* @throws IOException
* If an I/O error occurs
* @throws SecurityException
* If a security manager is installed and it denies an
* unspecified permission required by the implementation.
* In the case of the default provider, the {@link
* SecurityManager#checkRead(String)} method is invoked to check
* read access if the file is opened for reading. The {@link
* SecurityManager#checkWrite(String)} method is invoked to check
* write access if the file is opened for writing
*/
public static AsynchronousFileChannel open(Path file,
Set<? extends OpenOption> options,
ExecutorService executor,
FileAttribute<?>... attrs)
throws IOException
{
FileSystemProvider provider = file.getFileSystem().provider();
return provider.newAsynchronousFileChannel(file, options, executor, attrs);
}
@SuppressWarnings({"unchecked", "rawtypes"}) // generic array construction
private static final FileAttribute<?>[] NO_ATTRIBUTES = new FileAttribute[0];
/**
* Opens or creates a file for reading and/or writing, returning an
* asynchronous file channel to access the file.
*
* <p> An invocation of this method behaves in exactly the same way as the
* invocation
* <pre>
* ch.{@link #open(Path,Set,ExecutorService,FileAttribute[])
* open}(file, opts, null, new FileAttribute&lt;?&gt;[0]);
* </pre>
* where {@code opts} is a {@code Set} containing the options specified to
* this method.
*
* <p> The resulting channel is associated with default thread pool to which
* tasks are submitted to handle I/O events and dispatch to completion
* handlers that consume the result of asynchronous operations performed on
* the resulting channel.
*
* @param file
* The path of the file to open or create
* @param options
* Options specifying how the file is opened
*
* @return A new asynchronous file channel
*
* @throws IllegalArgumentException
* If the set contains an invalid combination of options
* @throws UnsupportedOperationException
* If the {@code file} is associated with a provider that does not
* support creating file channels, or an unsupported open option is
* specified
* @throws IOException
* If an I/O error occurs
* @throws SecurityException
* If a security manager is installed and it denies an
* unspecified permission required by the implementation.
* In the case of the default provider, the {@link
* SecurityManager#checkRead(String)} method is invoked to check
* read access if the file is opened for reading. The {@link
* SecurityManager#checkWrite(String)} method is invoked to check
* write access if the file is opened for writing
*/
public static AsynchronousFileChannel open(Path file, OpenOption... options)
throws IOException
{
Set<OpenOption> set = new HashSet<>(options.length);
Collections.addAll(set, options);
return open(file, set, null, NO_ATTRIBUTES);
}
/**
* Returns the current size of this channel's file.
*
* @return The current size of this channel's file, measured in bytes
*
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If some other I/O error occurs
*/
public abstract long size() throws IOException;
/**
* Truncates this channel's file to the given size.
*
* <p> If the given size is less than the file's current size then the file
* is truncated, discarding any bytes beyond the new end of the file. If
* the given size is greater than or equal to the file's current size then
* the file is not modified. </p>
*
* @param size
* The new size, a non-negative byte count
*
* @return This file channel
*
* @throws NonWritableChannelException
* If this channel was not opened for writing
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws IllegalArgumentException
* If the new size is negative
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract AsynchronousFileChannel truncate(long size) throws IOException;
/**
* Forces any updates to this channel's file to be written to the storage
* device that contains it.
*
* <p> If this channel's file resides on a local storage device then when
* this method returns it is guaranteed that all changes made to the file
* since this channel was created, or since this method was last invoked,
* will have been written to that device. This is useful for ensuring that
* critical information is not lost in the event of a system crash.
*
* <p> If the file does not reside on a local device then no such guarantee
* is made.
*
* <p> The {@code metaData} parameter can be used to limit the number of
* I/O operations that this method is required to perform. Passing
* {@code false} for this parameter indicates that only updates to the
* file's content need be written to storage; passing {@code true}
* indicates that updates to both the file's content and metadata must be
* written, which generally requires at least one more I/O operation.
* Whether this parameter actually has any effect is dependent upon the
* underlying operating system and is therefore unspecified.
*
* <p> Invoking this method may cause an I/O operation to occur even if the
* channel was only opened for reading. Some operating systems, for
* example, maintain a last-access time as part of a file's metadata, and
* this time is updated whenever the file is read. Whether or not this is
* actually done is system-dependent and is therefore unspecified.
*
* <p> This method is only guaranteed to force changes that were made to
* this channel's file via the methods defined in this class.
*
* @param metaData
* If {@code true} then this method is required to force changes
* to both the file's content and metadata to be written to
* storage; otherwise, it need only force content changes to be
* written
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract void force(boolean metaData) throws IOException;
/**
* Acquires a lock on the given region of this channel's file.
*
* <p> This method initiates an operation to acquire a lock on the given
* region of this channel's file. The {@code handler} parameter is a
* completion handler that is invoked when the lock is acquired (or the
* operation fails). The result passed to the completion handler is the
* resulting {@code FileLock}.
*
* <p> The region specified by the {@code position} and {@code size}
* parameters need not be contained within, or even overlap, the actual
* underlying file. Lock regions are fixed in size; if a locked region
* initially contains the end of the file and the file grows beyond the
* region then the new portion of the file will not be covered by the lock.
* If a file is expected to grow in size and a lock on the entire file is
* required then a region starting at zero, and no smaller than the
* expected maximum size of the file, should be locked. The two-argument
* {@link #lock(Object,CompletionHandler)} method simply locks a region
* of size {@link Long#MAX_VALUE}. If a lock that overlaps the requested
* region is already held by this Java virtual machine, or this method has
* been invoked to lock an overlapping region and that operation has not
* completed, then this method throws {@link OverlappingFileLockException}.
*
* <p> Some operating systems do not support a mechanism to acquire a file
* lock in an asynchronous manner. Consequently an implementation may
* acquire the file lock in a background thread or from a task executed by
* a thread in the associated thread pool. If there are many lock operations
* outstanding then it may consume threads in the Java virtual machine for
* indefinite periods.
*
* <p> Some operating systems do not support shared locks, in which case a
* request for a shared lock is automatically converted into a request for
* an exclusive lock. Whether the newly-acquired lock is shared or
* exclusive may be tested by invoking the resulting lock object's {@link
* FileLock#isShared() isShared} method.
*
* <p> File locks are held on behalf of the entire Java virtual machine.
* They are not suitable for controlling access to a file by multiple
* threads within the same virtual machine.
*
* @param <A>
* The type of the attachment
* @param position
* The position at which the locked region is to start; must be
* non-negative
* @param size
* The size of the locked region; must be non-negative, and the sum
* {@code position}&nbsp;+&nbsp;{@code size} must be non-negative
* @param shared
* {@code true} to request a shared lock, in which case this
* channel must be open for reading (and possibly writing);
* {@code false} to request an exclusive lock, in which case this
* channel must be open for writing (and possibly reading)
* @param attachment
* The object to attach to the I/O operation; can be {@code null}
* @param handler
* The handler for consuming the result
*
* @throws OverlappingFileLockException
* If a lock that overlaps the requested region is already held by
* this Java virtual machine, or there is already a pending attempt
* to lock an overlapping region
* @throws IllegalArgumentException
* If the preconditions on the parameters do not hold
* @throws NonReadableChannelException
* If {@code shared} is true but this channel was not opened for reading
* @throws NonWritableChannelException
* If {@code shared} is false but this channel was not opened for writing
*/
public abstract <A> void lock(long position,
long size,
boolean shared,
A attachment,
CompletionHandler<FileLock,? super A> handler);
/**
* Acquires an exclusive lock on this channel's file.
*
* <p> This method initiates an operation to acquire a lock on the given
* region of this channel's file. The {@code handler} parameter is a
* completion handler that is invoked when the lock is acquired (or the
* operation fails). The result passed to the completion handler is the
* resulting {@code FileLock}.
*
* <p> An invocation of this method of the form {@code ch.lock(att,handler)}
* behaves in exactly the same way as the invocation
* <pre>
* ch.{@link #lock(long,long,boolean,Object,CompletionHandler) lock}(0L, Long.MAX_VALUE, false, att, handler)
* </pre>
*
* @param <A>
* The type of the attachment
* @param attachment
* The object to attach to the I/O operation; can be {@code null}
* @param handler
* The handler for consuming the result
*
* @throws OverlappingFileLockException
* If a lock is already held by this Java virtual machine, or there
* is already a pending attempt to lock a region
* @throws NonWritableChannelException
* If this channel was not opened for writing
*/
public final <A> void lock(A attachment,
CompletionHandler<FileLock,? super A> handler)
{
lock(0L, Long.MAX_VALUE, false, attachment, handler);
}
/**
* Acquires a lock on the given region of this channel's file.
*
* <p> This method initiates an operation to acquire a lock on the given
* region of this channel's file. The method behaves in exactly the same
* manner as the {@link #lock(long, long, boolean, Object, CompletionHandler)}
* method except that instead of specifying a completion handler, this
* method returns a {@code Future} representing the pending result. The
* {@code Future}'s {@link Future#get() get} method returns the {@link
* FileLock} on successful completion.
*
* @param position
* The position at which the locked region is to start; must be
* non-negative
* @param size
* The size of the locked region; must be non-negative, and the sum
* {@code position}&nbsp;+&nbsp;{@code size} must be non-negative
* @param shared
* {@code true} to request a shared lock, in which case this
* channel must be open for reading (and possibly writing);
* {@code false} to request an exclusive lock, in which case this
* channel must be open for writing (and possibly reading)
*
* @return a {@code Future} object representing the pending result
*
* @throws OverlappingFileLockException
* If a lock is already held by this Java virtual machine, or there
* is already a pending attempt to lock a region
* @throws IllegalArgumentException
* If the preconditions on the parameters do not hold
* @throws NonReadableChannelException
* If {@code shared} is true but this channel was not opened for reading
* @throws NonWritableChannelException
* If {@code shared} is false but this channel was not opened for writing
*/
public abstract Future<FileLock> lock(long position, long size, boolean shared);
/**
* Acquires an exclusive lock on this channel's file.
*
* <p> This method initiates an operation to acquire an exclusive lock on this
* channel's file. The method returns a {@code Future} representing the
* pending result of the operation. The {@code Future}'s {@link Future#get()
* get} method returns the {@link FileLock} on successful completion.
*
* <p> An invocation of this method behaves in exactly the same way as the
* invocation
* <pre>
* ch.{@link #lock(long,long,boolean) lock}(0L, Long.MAX_VALUE, false)
* </pre>
*
* @return a {@code Future} object representing the pending result
*
* @throws OverlappingFileLockException
* If a lock is already held by this Java virtual machine, or there
* is already a pending attempt to lock a region
* @throws NonWritableChannelException
* If this channel was not opened for writing
*/
public final Future<FileLock> lock() {
return lock(0L, Long.MAX_VALUE, false);
}
/**
* Attempts to acquire a lock on the given region of this channel's file.
*
* <p> This method does not block. An invocation always returns immediately,
* either having acquired a lock on the requested region or having failed to
* do so. If it fails to acquire a lock because an overlapping lock is held
* by another program then it returns {@code null}. If it fails to acquire
* a lock for any other reason then an appropriate exception is thrown.
*
* @param position
* The position at which the locked region is to start; must be
* non-negative
*
* @param size
* The size of the locked region; must be non-negative, and the sum
* {@code position}&nbsp;+&nbsp;{@code size} must be non-negative
*
* @param shared
* {@code true} to request a shared lock,
* {@code false} to request an exclusive lock
*
* @return A lock object representing the newly-acquired lock,
* or {@code null} if the lock could not be acquired
* because another program holds an overlapping lock
*
* @throws IllegalArgumentException
* If the preconditions on the parameters do not hold
* @throws ClosedChannelException
* If this channel is closed
* @throws OverlappingFileLockException
* If a lock that overlaps the requested region is already held by
* this Java virtual machine, or if another thread is already
* blocked in this method and is attempting to lock an overlapping
* region of the same file
* @throws NonReadableChannelException
* If {@code shared} is true but this channel was not opened for reading
* @throws NonWritableChannelException
* If {@code shared} is false but this channel was not opened for writing
*
* @throws IOException
* If some other I/O error occurs
*
* @see #lock(Object,CompletionHandler)
* @see #lock(long,long,boolean,Object,CompletionHandler)
* @see #tryLock()
*/
public abstract FileLock tryLock(long position, long size, boolean shared)
throws IOException;
/**
* Attempts to acquire an exclusive lock on this channel's file.
*
* <p> An invocation of this method of the form {@code ch.tryLock()}
* behaves in exactly the same way as the invocation
*
* <pre>
* ch.{@link #tryLock(long,long,boolean) tryLock}(0L, Long.MAX_VALUE, false) </pre>
*
* @return A lock object representing the newly-acquired lock,
* or {@code null} if the lock could not be acquired
* because another program holds an overlapping lock
*
* @throws ClosedChannelException
* If this channel is closed
* @throws OverlappingFileLockException
* If a lock that overlaps the requested region is already held by
* this Java virtual machine, or if another thread is already
* blocked in this method and is attempting to lock an overlapping
* region
* @throws NonWritableChannelException
* If {@code shared} is false but this channel was not opened for writing
*
* @throws IOException
* If some other I/O error occurs
*
* @see #lock(Object,CompletionHandler)
* @see #lock(long,long,boolean,Object,CompletionHandler)
* @see #tryLock(long,long,boolean)
*/
public final FileLock tryLock() throws IOException {
return tryLock(0L, Long.MAX_VALUE, false);
}
/**
* Reads a sequence of bytes from this channel into the given buffer,
* starting at the given file position.
*
* <p> This method initiates the reading of a sequence of bytes from this
* channel into the given buffer, starting at the given file position. The
* result of the read is the number of bytes read or {@code -1} if the given
* position is greater than or equal to the file's size at the time that the
* read is attempted.
*
* <p> This method works in the same manner as the {@link
* AsynchronousByteChannel#read(ByteBuffer,Object,CompletionHandler)}
* method, except that bytes are read starting at the given file position.
* If the given file position is greater than the file's size at the time
* that the read is attempted then no bytes are read.
*
* @param <A>
* The type of the attachment
* @param dst
* The buffer into which bytes are to be transferred
* @param position
* The file position at which the transfer is to begin;
* must be non-negative
* @param attachment
* The object to attach to the I/O operation; can be {@code null}
* @param handler
* The handler for consuming the result
*
* @throws IllegalArgumentException
* If the position is negative or the buffer is read-only
* @throws NonReadableChannelException
* If this channel was not opened for reading
*/
public abstract <A> void read(ByteBuffer dst,
long position,
A attachment,
CompletionHandler<Integer,? super A> handler);
/**
* Reads a sequence of bytes from this channel into the given buffer,
* starting at the given file position.
*
* <p> This method initiates the reading of a sequence of bytes from this
* channel into the given buffer, starting at the given file position. This
* method returns a {@code Future} representing the pending result of the
* operation. The {@code Future}'s {@link Future#get() get} method returns
* the number of bytes read or {@code -1} if the given position is greater
* than or equal to the file's size at the time that the read is attempted.
*
* <p> This method works in the same manner as the {@link
* AsynchronousByteChannel#read(ByteBuffer)} method, except that bytes are
* read starting at the given file position. If the given file position is
* greater than the file's size at the time that the read is attempted then
* no bytes are read.
*
* @param dst
* The buffer into which bytes are to be transferred
* @param position
* The file position at which the transfer is to begin;
* must be non-negative
*
* @return A {@code Future} object representing the pending result
*
* @throws IllegalArgumentException
* If the position is negative or the buffer is read-only
* @throws NonReadableChannelException
* If this channel was not opened for reading
*/
public abstract Future<Integer> read(ByteBuffer dst, long position);
/**
* Writes a sequence of bytes to this channel from the given buffer, starting
* at the given file position.
*
* <p> This method works in the same manner as the {@link
* AsynchronousByteChannel#write(ByteBuffer,Object,CompletionHandler)}
* method, except that bytes are written starting at the given file position.
* If the given position is greater than the file's size, at the time that
* the write is attempted, then the file will be grown to accommodate the new
* bytes; the values of any bytes between the previous end-of-file and the
* newly-written bytes are unspecified.
*
* @param <A>
* The type of the attachment
* @param src
* The buffer from which bytes are to be transferred
* @param position
* The file position at which the transfer is to begin;
* must be non-negative
* @param attachment
* The object to attach to the I/O operation; can be {@code null}
* @param handler
* The handler for consuming the result
*
* @throws IllegalArgumentException
* If the position is negative
* @throws NonWritableChannelException
* If this channel was not opened for writing
*/
public abstract <A> void write(ByteBuffer src,
long position,
A attachment,
CompletionHandler<Integer,? super A> handler);
/**
* Writes a sequence of bytes to this channel from the given buffer, starting
* at the given file position.
*
* <p> This method initiates the writing of a sequence of bytes to this
* channel from the given buffer, starting at the given file position. The
* method returns a {@code Future} representing the pending result of the
* write operation. The {@code Future}'s {@link Future#get() get} method
* returns the number of bytes written.
*
* <p> This method works in the same manner as the {@link
* AsynchronousByteChannel#write(ByteBuffer)} method, except that bytes are
* written starting at the given file position. If the given position is
* greater than the file's size, at the time that the write is attempted,
* then the file will be grown to accommodate the new bytes; the values of
* any bytes between the previous end-of-file and the newly-written bytes
* are unspecified.
*
* @param src
* The buffer from which bytes are to be transferred
* @param position
* The file position at which the transfer is to begin;
* must be non-negative
*
* @return A {@code Future} object representing the pending result
*
* @throws IllegalArgumentException
* If the position is negative
* @throws NonWritableChannelException
* If this channel was not opened for writing
*/
public abstract Future<Integer> write(ByteBuffer src, long position);
}

View file

@ -0,0 +1,333 @@
/*
* Copyright (c) 2007, 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;
import java.nio.channels.spi.*;
import java.net.SocketOption;
import java.net.SocketAddress;
import java.util.concurrent.Future;
import java.io.IOException;
/**
* An asynchronous channel for stream-oriented listening sockets.
*
* <p> An asynchronous server-socket channel is created by invoking the
* {@link #open open} method of this class.
* A newly-created asynchronous server-socket channel is open but not yet bound.
* It can be bound to a local address and configured to listen for connections
* by invoking the {@link #bind(SocketAddress,int) bind} method. Once bound,
* the {@link #accept(Object,CompletionHandler) accept} method
* is used to initiate the accepting of connections to the channel's socket.
* An attempt to invoke the {@code accept} method on an unbound channel will
* cause a {@link NotYetBoundException} to be thrown.
*
* <p> Channels of this type are safe for use by multiple concurrent threads
* though at most one accept operation can be outstanding at any time.
* If a thread initiates an accept operation before a previous accept operation
* has completed then an {@link AcceptPendingException} will be thrown.
*
* <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
* setOption} method. Channels of this type support the following options:
* <blockquote>
* <table class="striped">
* <caption style="display:none">Socket options</caption>
* <thead>
* <tr>
* <th scope="col">Option Name</th>
* <th scope="col">Description</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </th>
* <td> The size of the socket receive buffer </td>
* </tr>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </th>
* <td> Re-use address </td>
* </tr>
* </tbody>
* </table>
* </blockquote>
* Additional (implementation specific) options may also be supported.
*
* <p> <b>Usage Example:</b>
* <pre>
* final AsynchronousServerSocketChannel listener =
* AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(5000));
*
* listener.accept(null, new CompletionHandler&lt;AsynchronousSocketChannel,Void&gt;() {
* public void completed(AsynchronousSocketChannel ch, Void att) {
* // accept the next connection
* listener.accept(null, this);
*
* // handle this connection
* handle(ch);
* }
* public void failed(Throwable exc, Void att) {
* ...
* }
* });
* </pre>
*
* @since 1.7
*/
public abstract class AsynchronousServerSocketChannel
implements AsynchronousChannel, NetworkChannel
{
private final AsynchronousChannelProvider provider;
/**
* Initializes a new instance of this class.
*
* @param provider
* The provider that created this channel
*/
protected AsynchronousServerSocketChannel(AsynchronousChannelProvider provider) {
this.provider = provider;
}
/**
* Returns the provider that created this channel.
*
* @return The provider that created this channel
*/
public final AsynchronousChannelProvider provider() {
return provider;
}
/**
* Opens an asynchronous server-socket channel.
*
* <p> The new channel is created by invoking the {@link
* java.nio.channels.spi.AsynchronousChannelProvider#openAsynchronousServerSocketChannel
* openAsynchronousServerSocketChannel} method on the {@link
* java.nio.channels.spi.AsynchronousChannelProvider} object that created
* the given group. If the group parameter is {@code null} then the
* resulting channel is created by the system-wide default provider, and
* bound to the <em>default group</em>.
*
* @param group
* The group to which the newly constructed channel should be bound,
* or {@code null} for the default group
*
* @return A new asynchronous server socket channel
*
* @throws ShutdownChannelGroupException
* If the channel group is shutdown
* @throws IOException
* If an I/O error occurs
*/
public static AsynchronousServerSocketChannel open(AsynchronousChannelGroup group)
throws IOException
{
AsynchronousChannelProvider provider = (group == null) ?
AsynchronousChannelProvider.provider() : group.provider();
return provider.openAsynchronousServerSocketChannel(group);
}
/**
* Opens an asynchronous server-socket channel.
*
* <p> This method returns an asynchronous server socket channel that is
* bound to the <em>default group</em>. This method is equivalent to evaluating
* the expression:
* <blockquote><pre>
* open((AsynchronousChannelGroup)null);
* </pre></blockquote>
*
* @return A new asynchronous server socket channel
*
* @throws IOException
* If an I/O error occurs
*/
public static AsynchronousServerSocketChannel open()
throws IOException
{
return open(null);
}
/**
* Binds the channel's socket to a local address and configures the socket to
* listen for connections.
*
* <p> An invocation of this method is equivalent to the following:
* <blockquote><pre>
* bind(local, 0);
* </pre></blockquote>
*
* @param local
* The local address to bind the socket, or {@code null} to bind
* to an automatically assigned socket address
*
* @return This channel
*
* @throws AlreadyBoundException {@inheritDoc}
* @throws UnsupportedAddressTypeException {@inheritDoc}
* @throws SecurityException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
*/
public final AsynchronousServerSocketChannel bind(SocketAddress local)
throws IOException
{
return bind(local, 0);
}
/**
* Binds the channel's socket to a local address and configures the socket to
* listen for connections.
*
* <p> This method is used to establish an association between the socket and
* a local address. Once an association is established then the socket remains
* bound until the associated channel is closed.
*
* <p> The {@code backlog} parameter is the maximum number of pending
* connections on the socket. Its exact semantics are implementation specific.
* In particular, an implementation may impose a maximum length or may choose
* to ignore the parameter altogther. If the {@code backlog} parameter has
* the value {@code 0}, or a negative value, then an implementation specific
* default is used.
*
* @param local
* The local address to bind the socket, or {@code null} to bind
* to an automatically assigned socket address
* @param backlog
* The maximum number of pending connections
*
* @return This channel
*
* @throws AlreadyBoundException
* If the socket is already bound
* @throws UnsupportedAddressTypeException
* If the type of the given address is not supported
* @throws SecurityException
* If a security manager has been installed and its {@link
* SecurityManager#checkListen checkListen} method denies the operation
* @throws ClosedChannelException
* If the channel is closed
* @throws IOException
* If some other I/O error occurs
*/
public abstract AsynchronousServerSocketChannel bind(SocketAddress local, int backlog)
throws IOException;
/**
* @throws IllegalArgumentException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
*/
public abstract <T> AsynchronousServerSocketChannel setOption(SocketOption<T> name, T value)
throws IOException;
/**
* Accepts a connection.
*
* <p> This method initiates an asynchronous operation to accept a
* connection made to this channel's socket. The {@code handler} parameter is
* a completion handler that is invoked when a connection is accepted (or
* the operation fails). The result passed to the completion handler is
* the {@link AsynchronousSocketChannel} to the new connection.
*
* <p> When a new connection is accepted then the resulting {@code
* AsynchronousSocketChannel} will be bound to the same {@link
* AsynchronousChannelGroup} as this channel. If the group is {@link
* AsynchronousChannelGroup#isShutdown shutdown} and a connection is accepted,
* then the connection is closed, and the operation completes with an {@code
* IOException} and cause {@link ShutdownChannelGroupException}.
*
* <p> To allow for concurrent handling of new connections, the completion
* handler is not invoked directly by the initiating thread when a new
* connection is accepted immediately (see <a
* href="AsynchronousChannelGroup.html#threading">Threading</a>).
*
* <p> If a security manager has been installed then it verifies that the
* address and port number of the connection's remote endpoint are permitted
* by the security manager's {@link SecurityManager#checkAccept checkAccept}
* method. The permission check is performed with privileges that are restricted
* by the calling context of this method. If the permission check fails then
* the connection is closed and the operation completes with a {@link
* SecurityException}.
*
* @param <A>
* The type of the attachment
* @param attachment
* The object to attach to the I/O operation; can be {@code null}
* @param handler
* The handler for consuming the result
*
* @throws AcceptPendingException
* If an accept operation is already in progress on this channel
* @throws NotYetBoundException
* If this channel's socket has not yet been bound
* @throws ShutdownChannelGroupException
* If the channel group has terminated
*/
public abstract <A> void accept(A attachment,
CompletionHandler<AsynchronousSocketChannel,? super A> handler);
/**
* Accepts a connection.
*
* <p> This method initiates an asynchronous operation to accept a
* connection made to this channel's socket. The method behaves in exactly
* the same manner as the {@link #accept(Object, CompletionHandler)} method
* except that instead of specifying a completion handler, this method
* returns a {@code Future} representing the pending result. The {@code
* Future}'s {@link Future#get() get} method returns the {@link
* AsynchronousSocketChannel} to the new connection on successful completion.
*
* @return a {@code Future} object representing the pending result
*
* @throws AcceptPendingException
* If an accept operation is already in progress on this channel
* @throws NotYetBoundException
* If this channel's socket has not yet been bound
*/
public abstract Future<AsynchronousSocketChannel> accept();
/**
* {@inheritDoc}
* <p>
* If there is a security manager set, its {@code checkConnect} method is
* called with the local address and {@code -1} as its arguments to see
* if the operation is allowed. If the operation is not allowed,
* a {@code SocketAddress} representing the
* {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
* local port of the channel's socket is returned.
*
* @return The {@code SocketAddress} that the socket is bound to, or the
* {@code SocketAddress} representing the loopback address if
* denied by the security manager, or {@code null} if the
* channel's socket is not bound
*
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
*/
@Override
public abstract SocketAddress getLocalAddress() throws IOException;
}

View file

@ -0,0 +1,692 @@
/*
* Copyright (c) 2007, 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;
import java.nio.channels.spi.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.Future;
import java.io.IOException;
import java.net.SocketOption;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
/**
* An asynchronous channel for stream-oriented connecting sockets.
*
* <p> Asynchronous socket channels are created in one of two ways. A newly-created
* {@code AsynchronousSocketChannel} is created by invoking one of the {@link
* #open open} methods defined by this class. A newly-created channel is open but
* not yet connected. A connected {@code AsynchronousSocketChannel} is created
* when a connection is made to the socket of an {@link AsynchronousServerSocketChannel}.
* It is not possible to create an asynchronous socket channel for an arbitrary,
* pre-existing {@link java.net.Socket socket}.
*
* <p> A newly-created channel is connected by invoking its {@link #connect connect}
* method; once connected, a channel remains connected until it is closed. Whether
* or not a socket channel is connected may be determined by invoking its {@link
* #getRemoteAddress getRemoteAddress} method. An attempt to invoke an I/O
* operation upon an unconnected channel will cause a {@link NotYetConnectedException}
* to be thrown.
*
* <p> Channels of this type are safe for use by multiple concurrent threads.
* They support concurrent reading and writing, though at most one read operation
* and one write operation can be outstanding at any time.
* If a thread initiates a read operation before a previous read operation has
* completed then a {@link ReadPendingException} will be thrown. Similarly, an
* attempt to initiate a write operation before a previous write has completed
* will throw a {@link WritePendingException}.
*
* <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
* setOption} method. Asynchronous socket channels support the following options:
* <blockquote>
* <table class="striped">
* <caption style="display:none">Socket options</caption>
* <thead>
* <tr>
* <th scope="col">Option Name</th>
* <th scope="col">Description</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#SO_SNDBUF SO_SNDBUF} </th>
* <td> The size of the socket send buffer </td>
* </tr>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </th>
* <td> The size of the socket receive buffer </td>
* </tr>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#SO_KEEPALIVE SO_KEEPALIVE} </th>
* <td> Keep connection alive </td>
* </tr>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </th>
* <td> Re-use address </td>
* </tr>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#TCP_NODELAY TCP_NODELAY} </th>
* <td> Disable the Nagle algorithm </td>
* </tr>
* </tbody>
* </table>
* </blockquote>
* Additional (implementation specific) options may also be supported.
*
* <h2>Timeouts</h2>
*
* <p> The {@link #read(ByteBuffer,long,TimeUnit,Object,CompletionHandler) read}
* and {@link #write(ByteBuffer,long,TimeUnit,Object,CompletionHandler) write}
* methods defined by this class allow a timeout to be specified when initiating
* a read or write operation. If the timeout elapses before an operation completes
* then the operation completes with the exception {@link
* InterruptedByTimeoutException}. A timeout may leave the channel, or the
* underlying connection, in an inconsistent state. Where the implementation
* cannot guarantee that bytes have not been read from the channel then it puts
* the channel into an implementation specific <em>error state</em>. A subsequent
* attempt to initiate a {@code read} operation causes an unspecified runtime
* exception to be thrown. Similarly if a {@code write} operation times out and
* the implementation cannot guarantee bytes have not been written to the
* channel then further attempts to {@code write} to the channel cause an
* unspecified runtime exception to be thrown. When a timeout elapses then the
* state of the {@link ByteBuffer}, or the sequence of buffers, for the I/O
* operation is not defined. Buffers should be discarded or at least care must
* be taken to ensure that the buffers are not accessed while the channel remains
* open. All methods that accept timeout parameters treat values less than or
* equal to zero to mean that the I/O operation does not timeout.
*
* @since 1.7
*/
public abstract class AsynchronousSocketChannel
implements AsynchronousByteChannel, NetworkChannel
{
private final AsynchronousChannelProvider provider;
/**
* Initializes a new instance of this class.
*
* @param provider
* The provider that created this channel
*/
protected AsynchronousSocketChannel(AsynchronousChannelProvider provider) {
this.provider = provider;
}
/**
* Returns the provider that created this channel.
*
* @return The provider that created this channel
*/
public final AsynchronousChannelProvider provider() {
return provider;
}
/**
* Opens an asynchronous socket channel.
*
* <p> The new channel is created by invoking the {@link
* AsynchronousChannelProvider#openAsynchronousSocketChannel
* openAsynchronousSocketChannel} method on the {@link
* AsynchronousChannelProvider} that created the group. If the group parameter
* is {@code null} then the resulting channel is created by the system-wide
* default provider, and bound to the <em>default group</em>.
*
* @param group
* The group to which the newly constructed channel should be bound,
* or {@code null} for the default group
*
* @return A new asynchronous socket channel
*
* @throws ShutdownChannelGroupException
* If the channel group is shutdown
* @throws IOException
* If an I/O error occurs
*/
public static AsynchronousSocketChannel open(AsynchronousChannelGroup group)
throws IOException
{
AsynchronousChannelProvider provider = (group == null) ?
AsynchronousChannelProvider.provider() : group.provider();
return provider.openAsynchronousSocketChannel(group);
}
/**
* Opens an asynchronous socket channel.
*
* <p> This method returns an asynchronous socket channel that is bound to
* the <em>default group</em>.This method is equivalent to evaluating the
* expression:
* <blockquote><pre>
* open((AsynchronousChannelGroup)null);
* </pre></blockquote>
*
* @return A new asynchronous socket channel
*
* @throws IOException
* If an I/O error occurs
*/
public static AsynchronousSocketChannel open()
throws IOException
{
return open(null);
}
// -- socket options and related --
/**
* @throws ConnectionPendingException
* If a connection operation is already in progress on this channel
* @throws AlreadyBoundException {@inheritDoc}
* @throws UnsupportedAddressTypeException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
* @throws SecurityException
* If a security manager has been installed and its
* {@link SecurityManager#checkListen checkListen} method denies
* the operation
*/
@Override
public abstract AsynchronousSocketChannel bind(SocketAddress local)
throws IOException;
/**
* @throws IllegalArgumentException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
*/
@Override
public abstract <T> AsynchronousSocketChannel setOption(SocketOption<T> name, T value)
throws IOException;
/**
* Shutdown the connection for reading without closing the channel.
*
* <p> Once shutdown for reading then further reads on the channel will
* return {@code -1}, the end-of-stream indication. If the input side of the
* connection is already shutdown then invoking this method has no effect.
* The effect on an outstanding read operation is system dependent and
* therefore not specified. The effect, if any, when there is data in the
* socket receive buffer that has not been read, or data arrives subsequently,
* is also system dependent.
*
* @return The channel
*
* @throws NotYetConnectedException
* If this channel is not yet connected
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If some other I/O error occurs
*/
public abstract AsynchronousSocketChannel shutdownInput() throws IOException;
/**
* Shutdown the connection for writing without closing the channel.
*
* <p> Once shutdown for writing then further attempts to write to the
* channel will throw {@link ClosedChannelException}. If the output side of
* the connection is already shutdown then invoking this method has no
* effect. The effect on an outstanding write operation is system dependent
* and therefore not specified.
*
* @return The channel
*
* @throws NotYetConnectedException
* If this channel is not yet connected
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If some other I/O error occurs
*/
public abstract AsynchronousSocketChannel shutdownOutput() throws IOException;
// -- state --
/**
* Returns the remote address to which this channel's socket is connected.
*
* <p> Where the channel is bound and connected to an Internet Protocol
* socket address then the return value from this method is of type {@link
* java.net.InetSocketAddress}.
*
* @return The remote address; {@code null} if the channel's socket is not
* connected
*
* @throws ClosedChannelException
* If the channel is closed
* @throws IOException
* If an I/O error occurs
*/
public abstract SocketAddress getRemoteAddress() throws IOException;
// -- asynchronous operations --
/**
* Connects this channel.
*
* <p> This method initiates an operation to connect this channel. The
* {@code handler} parameter is a completion handler that is invoked when
* the connection is successfully established or connection cannot be
* established. If the connection cannot be established then the channel is
* closed.
*
* <p> This method performs exactly the same security checks as the {@link
* java.net.Socket} class. That is, if a security manager has been
* installed then this method verifies that its {@link
* java.lang.SecurityManager#checkConnect checkConnect} method permits
* connecting to the address and port number of the given remote endpoint.
*
* @param <A>
* The type of the attachment
* @param remote
* The remote address to which this channel is to be connected
* @param attachment
* The object to attach to the I/O operation; can be {@code null}
* @param handler
* The handler for consuming the result
*
* @throws UnresolvedAddressException
* If the given remote address is not fully resolved
* @throws UnsupportedAddressTypeException
* If the type of the given remote address is not supported
* @throws AlreadyConnectedException
* If this channel is already connected
* @throws ConnectionPendingException
* If a connection operation is already in progress on this channel
* @throws ShutdownChannelGroupException
* If the channel group has terminated
* @throws SecurityException
* If a security manager has been installed
* and it does not permit access to the given remote endpoint
*
* @see #getRemoteAddress
*/
public abstract <A> void connect(SocketAddress remote,
A attachment,
CompletionHandler<Void,? super A> handler);
/**
* Connects this channel.
*
* <p> This method initiates an operation to connect this channel. This
* method behaves in exactly the same manner as the {@link
* #connect(SocketAddress, Object, CompletionHandler)} method except that
* instead of specifying a completion handler, this method returns a {@code
* Future} representing the pending result. The {@code Future}'s {@link
* Future#get() get} method returns {@code null} on successful completion.
*
* @param remote
* The remote address to which this channel is to be connected
*
* @return A {@code Future} object representing the pending result
*
* @throws UnresolvedAddressException
* If the given remote address is not fully resolved
* @throws UnsupportedAddressTypeException
* If the type of the given remote address is not supported
* @throws AlreadyConnectedException
* If this channel is already connected
* @throws ConnectionPendingException
* If a connection operation is already in progress on this channel
* @throws SecurityException
* If a security manager has been installed
* and it does not permit access to the given remote endpoint
*/
public abstract Future<Void> connect(SocketAddress remote);
/**
* Reads a sequence of bytes from this channel into the given buffer.
*
* <p> This method initiates an asynchronous read operation to read a
* sequence of bytes from this channel into the given buffer. The {@code
* handler} parameter is a completion handler that is invoked when the read
* operation completes (or fails). The result passed to the completion
* handler is the number of bytes read or {@code -1} if no bytes could be
* read because the channel has reached end-of-stream.
*
* <p> If a timeout is specified and the timeout elapses before the operation
* completes then the operation completes with the exception {@link
* InterruptedByTimeoutException}. Where a timeout occurs, and the
* implementation cannot guarantee that bytes have not been read, or will not
* be read from the channel into the given buffer, then further attempts to
* read from the channel will cause an unspecific runtime exception to be
* thrown.
*
* <p> Otherwise this method works in the same manner as the {@link
* AsynchronousByteChannel#read(ByteBuffer,Object,CompletionHandler)}
* method.
*
* @param <A>
* The type of the attachment
* @param dst
* The buffer into which bytes are to be transferred
* @param timeout
* The maximum time for the I/O operation to complete
* @param unit
* The time unit of the {@code timeout} argument
* @param attachment
* The object to attach to the I/O operation; can be {@code null}
* @param handler
* The handler for consuming the result
*
* @throws IllegalArgumentException
* If the buffer is read-only
* @throws ReadPendingException
* If a read operation is already in progress on this channel
* @throws NotYetConnectedException
* If this channel is not yet connected
* @throws ShutdownChannelGroupException
* If the channel group has terminated
*/
public abstract <A> void read(ByteBuffer dst,
long timeout,
TimeUnit unit,
A attachment,
CompletionHandler<Integer,? super A> handler);
/**
* @throws IllegalArgumentException {@inheritDoc}
* @throws ReadPendingException {@inheritDoc}
* @throws NotYetConnectedException
* If this channel is not yet connected
* @throws ShutdownChannelGroupException
* If the channel group has terminated
*/
@Override
public final <A> void read(ByteBuffer dst,
A attachment,
CompletionHandler<Integer,? super A> handler)
{
read(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler);
}
/**
* @throws IllegalArgumentException {@inheritDoc}
* @throws ReadPendingException {@inheritDoc}
* @throws NotYetConnectedException
* If this channel is not yet connected
*/
@Override
public abstract Future<Integer> read(ByteBuffer dst);
/**
* Reads a sequence of bytes from this channel into a subsequence of the
* given buffers. This operation, sometimes called a <em>scattering read</em>,
* is often useful when implementing network protocols that group data into
* segments consisting of one or more fixed-length headers followed by a
* variable-length body. The {@code handler} parameter is a completion
* handler that is invoked when the read operation completes (or fails). The
* result passed to the completion handler is the number of bytes read or
* {@code -1} if no bytes could be read because the channel has reached
* end-of-stream.
*
* <p> This method initiates a read of up to <i>r</i> bytes from this channel,
* where <i>r</i> is the total number of bytes remaining in the specified
* subsequence of the given buffer array, that is,
*
* <blockquote><pre>
* dsts[offset].remaining()
* + dsts[offset+1].remaining()
* + ... + dsts[offset+length-1].remaining()</pre></blockquote>
*
* at the moment that the read is attempted.
*
* <p> Suppose that a byte sequence of length <i>n</i> is read, where
* {@code 0}&nbsp;{@code <}&nbsp;<i>n</i>&nbsp;{@code <=}&nbsp;<i>r</i>.
* Up to the first {@code dsts[offset].remaining()} bytes of this sequence
* are transferred into buffer {@code dsts[offset]}, up to the next
* {@code dsts[offset+1].remaining()} bytes are transferred into buffer
* {@code dsts[offset+1]}, and so forth, until the entire byte sequence
* is transferred into the given buffers. As many bytes as possible are
* transferred into each buffer, hence the final position of each updated
* buffer, except the last updated buffer, is guaranteed to be equal to
* that buffer's limit. The underlying operating system may impose a limit
* on the number of buffers that may be used in an I/O operation. Where the
* number of buffers (with bytes remaining), exceeds this limit, then the
* I/O operation is performed with the maximum number of buffers allowed by
* the operating system.
*
* <p> If a timeout is specified and the timeout elapses before the operation
* completes then it completes with the exception {@link
* InterruptedByTimeoutException}. Where a timeout occurs, and the
* implementation cannot guarantee that bytes have not been read, or will not
* be read from the channel into the given buffers, then further attempts to
* read from the channel will cause an unspecific runtime exception to be
* thrown.
*
* @param <A>
* The type of the attachment
* @param dsts
* The buffers into which bytes are to be transferred
* @param offset
* The offset within the buffer array of the first buffer into which
* bytes are to be transferred; must be non-negative and no larger than
* {@code dsts.length}
* @param length
* The maximum number of buffers to be accessed; must be non-negative
* and no larger than {@code dsts.length - offset}
* @param timeout
* The maximum time for the I/O operation to complete
* @param unit
* The time unit of the {@code timeout} argument
* @param attachment
* The object to attach to the I/O operation; can be {@code null}
* @param handler
* The handler for consuming the result
*
* @throws IndexOutOfBoundsException
* If the pre-conditions for the {@code offset} and {@code length}
* parameter aren't met
* @throws IllegalArgumentException
* If the buffer is read-only
* @throws ReadPendingException
* If a read operation is already in progress on this channel
* @throws NotYetConnectedException
* If this channel is not yet connected
* @throws ShutdownChannelGroupException
* If the channel group has terminated
*/
public abstract <A> void read(ByteBuffer[] dsts,
int offset,
int length,
long timeout,
TimeUnit unit,
A attachment,
CompletionHandler<Long,? super A> handler);
/**
* Writes a sequence of bytes to this channel from the given buffer.
*
* <p> This method initiates an asynchronous write operation to write a
* sequence of bytes to this channel from the given buffer. The {@code
* handler} parameter is a completion handler that is invoked when the write
* operation completes (or fails). The result passed to the completion
* handler is the number of bytes written.
*
* <p> If a timeout is specified and the timeout elapses before the operation
* completes then it completes with the exception {@link
* InterruptedByTimeoutException}. Where a timeout occurs, and the
* implementation cannot guarantee that bytes have not been written, or will
* not be written to the channel from the given buffer, then further attempts
* to write to the channel will cause an unspecific runtime exception to be
* thrown.
*
* <p> Otherwise this method works in the same manner as the {@link
* AsynchronousByteChannel#write(ByteBuffer,Object,CompletionHandler)}
* method.
*
* @param <A>
* The type of the attachment
* @param src
* The buffer from which bytes are to be retrieved
* @param timeout
* The maximum time for the I/O operation to complete
* @param unit
* The time unit of the {@code timeout} argument
* @param attachment
* The object to attach to the I/O operation; can be {@code null}
* @param handler
* The handler for consuming the result
*
* @throws WritePendingException
* If a write operation is already in progress on this channel
* @throws NotYetConnectedException
* If this channel is not yet connected
* @throws ShutdownChannelGroupException
* If the channel group has terminated
*/
public abstract <A> void write(ByteBuffer src,
long timeout,
TimeUnit unit,
A attachment,
CompletionHandler<Integer,? super A> handler);
/**
* @throws WritePendingException {@inheritDoc}
* @throws NotYetConnectedException
* If this channel is not yet connected
* @throws ShutdownChannelGroupException
* If the channel group has terminated
*/
@Override
public final <A> void write(ByteBuffer src,
A attachment,
CompletionHandler<Integer,? super A> handler)
{
write(src, 0L, TimeUnit.MILLISECONDS, attachment, handler);
}
/**
* @throws WritePendingException {@inheritDoc}
* @throws NotYetConnectedException
* If this channel is not yet connected
*/
@Override
public abstract Future<Integer> write(ByteBuffer src);
/**
* Writes a sequence of bytes to this channel from a subsequence of the given
* buffers. This operation, sometimes called a <em>gathering write</em>, is
* often useful when implementing network protocols that group data into
* segments consisting of one or more fixed-length headers followed by a
* variable-length body. The {@code handler} parameter is a completion
* handler that is invoked when the write operation completes (or fails).
* The result passed to the completion handler is the number of bytes written.
*
* <p> This method initiates a write of up to <i>r</i> bytes to this channel,
* where <i>r</i> is the total number of bytes remaining in the specified
* subsequence of the given buffer array, that is,
*
* <blockquote><pre>
* srcs[offset].remaining()
* + srcs[offset+1].remaining()
* + ... + srcs[offset+length-1].remaining()</pre></blockquote>
*
* at the moment that the write is attempted.
*
* <p> Suppose that a byte sequence of length <i>n</i> is written, where
* {@code 0}&nbsp;{@code <}&nbsp;<i>n</i>&nbsp;{@code <=}&nbsp;<i>r</i>.
* Up to the first {@code srcs[offset].remaining()} bytes of this sequence
* are written from buffer {@code srcs[offset]}, up to the next
* {@code srcs[offset+1].remaining()} bytes are written from buffer
* {@code srcs[offset+1]}, and so forth, until the entire byte sequence is
* written. As many bytes as possible are written from each buffer, hence
* the final position of each updated buffer, except the last updated
* buffer, is guaranteed to be equal to that buffer's limit. The underlying
* operating system may impose a limit on the number of buffers that may be
* used in an I/O operation. Where the number of buffers (with bytes
* remaining), exceeds this limit, then the I/O operation is performed with
* the maximum number of buffers allowed by the operating system.
*
* <p> If a timeout is specified and the timeout elapses before the operation
* completes then it completes with the exception {@link
* InterruptedByTimeoutException}. Where a timeout occurs, and the
* implementation cannot guarantee that bytes have not been written, or will
* not be written to the channel from the given buffers, then further attempts
* to write to the channel will cause an unspecific runtime exception to be
* thrown.
*
* @param <A>
* The type of the attachment
* @param srcs
* The buffers from which bytes are to be retrieved
* @param offset
* The offset within the buffer array of the first buffer from which
* bytes are to be retrieved; must be non-negative and no larger
* than {@code srcs.length}
* @param length
* The maximum number of buffers to be accessed; must be non-negative
* and no larger than {@code srcs.length - offset}
* @param timeout
* The maximum time for the I/O operation to complete
* @param unit
* The time unit of the {@code timeout} argument
* @param attachment
* The object to attach to the I/O operation; can be {@code null}
* @param handler
* The handler for consuming the result
*
* @throws IndexOutOfBoundsException
* If the pre-conditions for the {@code offset} and {@code length}
* parameter aren't met
* @throws WritePendingException
* If a write operation is already in progress on this channel
* @throws NotYetConnectedException
* If this channel is not yet connected
* @throws ShutdownChannelGroupException
* If the channel group has terminated
*/
public abstract <A> void write(ByteBuffer[] srcs,
int offset,
int length,
long timeout,
TimeUnit unit,
A attachment,
CompletionHandler<Long,? super A> handler);
/**
* {@inheritDoc}
* <p>
* If there is a security manager set, its {@code checkConnect} method is
* called with the local address and {@code -1} as its arguments to see
* if the operation is allowed. If the operation is not allowed,
* a {@code SocketAddress} representing the
* {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
* local port of the channel's socket is returned.
*
* @return The {@code SocketAddress} that the socket is bound to, or the
* {@code SocketAddress} representing the loopback address if
* denied by the security manager, or {@code null} if the
* channel's socket is not bound
*
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
*/
public abstract SocketAddress getLocalAddress() throws IOException;
}

View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2000, 2001, 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;
import java.io.IOException;
/**
* A channel that can read and write bytes. This interface simply unifies
* {@link ReadableByteChannel} and {@link WritableByteChannel}; it does not
* specify any new operations.
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public interface ByteChannel
extends ReadableByteChannel, WritableByteChannel
{
}

View file

@ -0,0 +1,84 @@
/*
* 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;
import java.io.IOException;
import java.io.Closeable;
/**
* A nexus for I/O operations.
*
* <p> A channel represents an open connection to an entity such as a hardware
* device, a file, a network socket, or a program component that is capable of
* performing one or more distinct I/O operations, for example reading or
* writing.
*
* <p> A channel is either open or closed. A channel is open upon creation,
* and once closed it remains closed. Once a channel is closed, any attempt to
* invoke an I/O operation upon it will cause a {@link ClosedChannelException}
* to be thrown. Whether or not a channel is open may be tested by invoking
* its {@link #isOpen isOpen} method.
*
* <p> Channels are, in general, intended to be safe for multithreaded access
* as described in the specifications of the interfaces and classes that extend
* and implement this interface.
*
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public interface Channel extends Closeable {
/**
* Tells whether or not this channel is open.
*
* @return {@code true} if, and only if, this channel is open
*/
public boolean isOpen();
/**
* Closes this channel.
*
* <p> After a channel is closed, any further attempt to invoke I/O
* operations upon it will cause a {@link ClosedChannelException} to be
* thrown.
*
* <p> If this channel is already closed then invoking this method has no
* effect.
*
* <p> This method may be invoked at any time. If some other thread has
* already invoked it, however, then another invocation will block until
* the first invocation is complete, after which it will return without
* effect. </p>
*
* @throws IOException If an I/O error occurs
*/
public void close() throws IOException;
}

View file

@ -0,0 +1,611 @@
/*
* Copyright (c) 2000, 2015, 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;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.UnsupportedCharsetException;
import java.nio.channels.spi.AbstractInterruptibleChannel;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import sun.nio.ch.ChannelInputStream;
import sun.nio.cs.StreamDecoder;
import sun.nio.cs.StreamEncoder;
/**
* Utility methods for channels and streams.
*
* <p> This class defines static methods that support the interoperation of the
* stream classes of the {@link java.io} package with the channel classes
* of this package. </p>
*
*
* @author Mark Reinhold
* @author Mike McCloskey
* @author JSR-51 Expert Group
* @since 1.4
*/
public final class Channels {
private Channels() { throw new Error("no instances"); }
/**
* Write all remaining bytes in buffer to the given channel.
* If the channel is selectable then it must be configured blocking.
*/
private static void writeFullyImpl(WritableByteChannel ch, ByteBuffer bb)
throws IOException
{
while (bb.remaining() > 0) {
int n = ch.write(bb);
if (n <= 0)
throw new RuntimeException("no bytes written");
}
}
/**
* Write all remaining bytes in buffer to the given channel.
*
* @throws IllegalBlockingModeException
* If the channel is selectable and configured non-blocking.
*/
private static void writeFully(WritableByteChannel ch, ByteBuffer bb)
throws IOException
{
if (ch instanceof SelectableChannel) {
SelectableChannel sc = (SelectableChannel) ch;
synchronized (sc.blockingLock()) {
if (!sc.isBlocking())
throw new IllegalBlockingModeException();
writeFullyImpl(ch, bb);
}
} else {
writeFullyImpl(ch, bb);
}
}
// -- Byte streams from channels --
/**
* Constructs a stream that reads bytes from the given channel.
*
* <p> The {@code read} methods of the resulting stream will throw an
* {@link IllegalBlockingModeException} if invoked while the underlying
* channel is in non-blocking mode. The stream will not be buffered, and
* it will not support the {@link InputStream#mark mark} or {@link
* InputStream#reset reset} methods. The stream will be safe for access by
* multiple concurrent threads. Closing the stream will in turn cause the
* channel to be closed. </p>
*
* @param ch
* The channel from which bytes will be read
*
* @return A new input stream
*/
public static InputStream newInputStream(ReadableByteChannel ch) {
Objects.requireNonNull(ch, "ch");
return new ChannelInputStream(ch);
}
/**
* Constructs a stream that writes bytes to the given channel.
*
* <p> The {@code write} methods of the resulting stream will throw an
* {@link IllegalBlockingModeException} if invoked while the underlying
* channel is in non-blocking mode. The stream will not be buffered. The
* stream will be safe for access by multiple concurrent threads. Closing
* the stream will in turn cause the channel to be closed. </p>
*
* @param ch
* The channel to which bytes will be written
*
* @return A new output stream
*/
public static OutputStream newOutputStream(WritableByteChannel ch) {
Objects.requireNonNull(ch, "ch");
return new OutputStream() {
private ByteBuffer bb;
private byte[] bs; // Invoker's previous array
private byte[] b1;
@Override
public synchronized void write(int b) throws IOException {
if (b1 == null)
b1 = new byte[1];
b1[0] = (byte) b;
this.write(b1);
}
@Override
public synchronized void write(byte[] bs, int off, int len)
throws IOException
{
if ((off < 0) || (off > bs.length) || (len < 0) ||
((off + len) > bs.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
ByteBuffer bb = ((this.bs == bs)
? this.bb
: ByteBuffer.wrap(bs));
bb.limit(Math.min(off + len, bb.capacity()));
bb.position(off);
this.bb = bb;
this.bs = bs;
Channels.writeFully(ch, bb);
}
@Override
public void close() throws IOException {
ch.close();
}
};
}
/**
* Constructs a stream that reads bytes from the given channel.
*
* <p> The stream will not be buffered, and it will not support the {@link
* InputStream#mark mark} or {@link InputStream#reset reset} methods. The
* stream will be safe for access by multiple concurrent threads. Closing
* the stream will in turn cause the channel to be closed. </p>
*
* @param ch
* The channel from which bytes will be read
*
* @return A new input stream
*
* @since 1.7
*/
public static InputStream newInputStream(AsynchronousByteChannel ch) {
Objects.requireNonNull(ch, "ch");
return new InputStream() {
private ByteBuffer bb;
private byte[] bs; // Invoker's previous array
private byte[] b1;
@Override
public synchronized int read() throws IOException {
if (b1 == null)
b1 = new byte[1];
int n = this.read(b1);
if (n == 1)
return b1[0] & 0xff;
return -1;
}
@Override
public synchronized int read(byte[] bs, int off, int len)
throws IOException
{
if ((off < 0) || (off > bs.length) || (len < 0) ||
((off + len) > bs.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
ByteBuffer bb = ((this.bs == bs)
? this.bb
: ByteBuffer.wrap(bs));
bb.position(off);
bb.limit(Math.min(off + len, bb.capacity()));
this.bb = bb;
this.bs = bs;
boolean interrupted = false;
try {
for (;;) {
try {
return ch.read(bb).get();
} catch (ExecutionException ee) {
throw new IOException(ee.getCause());
} catch (InterruptedException ie) {
interrupted = true;
}
}
} finally {
if (interrupted)
Thread.currentThread().interrupt();
}
}
@Override
public void close() throws IOException {
ch.close();
}
};
}
/**
* Constructs a stream that writes bytes to the given channel.
*
* <p> The stream will not be buffered. The stream will be safe for access
* by multiple concurrent threads. Closing the stream will in turn cause
* the channel to be closed. </p>
*
* @param ch
* The channel to which bytes will be written
*
* @return A new output stream
*
* @since 1.7
*/
public static OutputStream newOutputStream(AsynchronousByteChannel ch) {
Objects.requireNonNull(ch, "ch");
return new OutputStream() {
private ByteBuffer bb;
private byte[] bs; // Invoker's previous array
private byte[] b1;
@Override
public synchronized void write(int b) throws IOException {
if (b1 == null)
b1 = new byte[1];
b1[0] = (byte) b;
this.write(b1);
}
@Override
public synchronized void write(byte[] bs, int off, int len)
throws IOException
{
if ((off < 0) || (off > bs.length) || (len < 0) ||
((off + len) > bs.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
ByteBuffer bb = ((this.bs == bs)
? this.bb
: ByteBuffer.wrap(bs));
bb.limit(Math.min(off + len, bb.capacity()));
bb.position(off);
this.bb = bb;
this.bs = bs;
boolean interrupted = false;
try {
while (bb.remaining() > 0) {
try {
ch.write(bb).get();
} catch (ExecutionException ee) {
throw new IOException(ee.getCause());
} catch (InterruptedException ie) {
interrupted = true;
}
}
} finally {
if (interrupted)
Thread.currentThread().interrupt();
}
}
@Override
public void close() throws IOException {
ch.close();
}
};
}
// -- Channels from streams --
/**
* Constructs a channel that reads bytes from the given stream.
*
* <p> The resulting channel will not be buffered; it will simply redirect
* its I/O operations to the given stream. Closing the channel will in
* turn cause the stream to be closed. </p>
*
* @param in
* The stream from which bytes are to be read
*
* @return A new readable byte channel
*/
public static ReadableByteChannel newChannel(InputStream in) {
Objects.requireNonNull(in, "in");
if (in.getClass() == FileInputStream.class) {
return ((FileInputStream) in).getChannel();
}
return new ReadableByteChannelImpl(in);
}
private static class ReadableByteChannelImpl
extends AbstractInterruptibleChannel // Not really interruptible
implements ReadableByteChannel
{
private final InputStream in;
private static final int TRANSFER_SIZE = 8192;
private byte[] buf = new byte[0];
private final Object readLock = new Object();
ReadableByteChannelImpl(InputStream in) {
this.in = in;
}
@Override
public int read(ByteBuffer dst) throws IOException {
int len = dst.remaining();
int totalRead = 0;
int bytesRead = 0;
synchronized (readLock) {
while (totalRead < len) {
int bytesToRead = Math.min((len - totalRead),
TRANSFER_SIZE);
if (buf.length < bytesToRead)
buf = new byte[bytesToRead];
if ((totalRead > 0) && !(in.available() > 0))
break; // block at most once
try {
begin();
bytesRead = in.read(buf, 0, bytesToRead);
} finally {
end(bytesRead > 0);
}
if (bytesRead < 0)
break;
else
totalRead += bytesRead;
dst.put(buf, 0, bytesRead);
}
if ((bytesRead < 0) && (totalRead == 0))
return -1;
return totalRead;
}
}
@Override
protected void implCloseChannel() throws IOException {
in.close();
}
}
/**
* Constructs a channel that writes bytes to the given stream.
*
* <p> The resulting channel will not be buffered; it will simply redirect
* its I/O operations to the given stream. Closing the channel will in
* turn cause the stream to be closed. </p>
*
* @param out
* The stream to which bytes are to be written
*
* @return A new writable byte channel
*/
public static WritableByteChannel newChannel(OutputStream out) {
Objects.requireNonNull(out, "out");
if (out.getClass() == FileOutputStream.class) {
return ((FileOutputStream) out).getChannel();
}
return new WritableByteChannelImpl(out);
}
private static class WritableByteChannelImpl
extends AbstractInterruptibleChannel // Not really interruptible
implements WritableByteChannel
{
private final OutputStream out;
private static final int TRANSFER_SIZE = 8192;
private byte[] buf = new byte[0];
private final Object writeLock = new Object();
WritableByteChannelImpl(OutputStream out) {
this.out = out;
}
@Override
public int write(ByteBuffer src) throws IOException {
int len = src.remaining();
int totalWritten = 0;
synchronized (writeLock) {
while (totalWritten < len) {
int bytesToWrite = Math.min((len - totalWritten),
TRANSFER_SIZE);
if (buf.length < bytesToWrite)
buf = new byte[bytesToWrite];
src.get(buf, 0, bytesToWrite);
try {
begin();
out.write(buf, 0, bytesToWrite);
} finally {
end(bytesToWrite > 0);
}
totalWritten += bytesToWrite;
}
return totalWritten;
}
}
@Override
protected void implCloseChannel() throws IOException {
out.close();
}
}
// -- Character streams from channels --
/**
* Constructs a reader that decodes bytes from the given channel using the
* given decoder.
*
* <p> The resulting stream will contain an internal input buffer of at
* least {@code minBufferCap} bytes. The stream's {@code read} methods
* will, as needed, fill the buffer by reading bytes from the underlying
* channel; if the channel is in non-blocking mode when bytes are to be
* read then an {@link IllegalBlockingModeException} will be thrown. The
* resulting stream will not otherwise be buffered, and it will not support
* the {@link Reader#mark mark} or {@link Reader#reset reset} methods.
* Closing the stream will in turn cause the channel to be closed. </p>
*
* @param ch
* The channel from which bytes will be read
*
* @param dec
* The charset decoder to be used
*
* @param minBufferCap
* The minimum capacity of the internal byte buffer,
* or {@code -1} if an implementation-dependent
* default capacity is to be used
*
* @return A new reader
*/
public static Reader newReader(ReadableByteChannel ch,
CharsetDecoder dec,
int minBufferCap)
{
Objects.requireNonNull(ch, "ch");
return StreamDecoder.forDecoder(ch, dec.reset(), minBufferCap);
}
/**
* Constructs a reader that decodes bytes from the given channel according
* to the named charset.
*
* <p> An invocation of this method of the form
*
* <pre> {@code
* Channels.newReader(ch, csname)
* } </pre>
*
* behaves in exactly the same way as the expression
*
* <pre> {@code
* Channels.newReader(ch, Charset.forName(csName).newDecoder(), -1)
* } </pre>
*
* @param ch
* The channel from which bytes will be read
*
* @param csName
* The name of the charset to be used
*
* @return A new reader
*
* @throws UnsupportedCharsetException
* If no support for the named charset is available
* in this instance of the Java virtual machine
*/
public static Reader newReader(ReadableByteChannel ch,
String csName)
{
Objects.requireNonNull(csName, "csName");
return newReader(ch, Charset.forName(csName).newDecoder(), -1);
}
/**
* Constructs a writer that encodes characters using the given encoder and
* writes the resulting bytes to the given channel.
*
* <p> The resulting stream will contain an internal output buffer of at
* least {@code minBufferCap} bytes. The stream's {@code write} methods
* will, as needed, flush the buffer by writing bytes to the underlying
* channel; if the channel is in non-blocking mode when bytes are to be
* written then an {@link IllegalBlockingModeException} will be thrown.
* The resulting stream will not otherwise be buffered. Closing the stream
* will in turn cause the channel to be closed. </p>
*
* @param ch
* The channel to which bytes will be written
*
* @param enc
* The charset encoder to be used
*
* @param minBufferCap
* The minimum capacity of the internal byte buffer,
* or {@code -1} if an implementation-dependent
* default capacity is to be used
*
* @return A new writer
*/
public static Writer newWriter(WritableByteChannel ch,
CharsetEncoder enc,
int minBufferCap)
{
Objects.requireNonNull(ch, "ch");
return StreamEncoder.forEncoder(ch, enc.reset(), minBufferCap);
}
/**
* Constructs a writer that encodes characters according to the named
* charset and writes the resulting bytes to the given channel.
*
* <p> An invocation of this method of the form
*
* <pre> {@code
* Channels.newWriter(ch, csname)
* } </pre>
*
* behaves in exactly the same way as the expression
*
* <pre> {@code
* Channels.newWriter(ch, Charset.forName(csName).newEncoder(), -1)
* } </pre>
*
* @param ch
* The channel to which bytes will be written
*
* @param csName
* The name of the charset to be used
*
* @return A new writer
*
* @throws UnsupportedCharsetException
* If no support for the named charset is available
* in this instance of the Java virtual machine
*/
public static Writer newWriter(WritableByteChannel ch,
String csName)
{
Objects.requireNonNull(csName, "csName");
return newWriter(ch, Charset.forName(csName).newEncoder(), -1);
}
}

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2007, 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.
*/
package java.nio.channels;
/**
* A handler for consuming the result of an asynchronous I/O operation.
*
* <p> The asynchronous channels defined in this package allow a completion
* handler to be specified to consume the result of an asynchronous operation.
* The {@link #completed completed} method is invoked when the I/O operation
* completes successfully. The {@link #failed failed} method is invoked if the
* I/O operations fails. The implementations of these methods should complete
* in a timely manner so as to avoid keeping the invoking thread from dispatching
* to other completion handlers.
*
* @param <V> The result type of the I/O operation
* @param <A> The type of the object attached to the I/O operation
*
* @since 1.7
*/
public interface CompletionHandler<V,A> {
/**
* Invoked when an operation has completed.
*
* @param result
* The result of the I/O operation.
* @param attachment
* The object attached to the I/O operation when it was initiated.
*/
void completed(V result, A attachment);
/**
* Invoked when an operation fails.
*
* @param exc
* The exception to indicate why the I/O operation failed
* @param attachment
* The object attached to the I/O operation when it was initiated.
*/
void failed(Throwable exc, A attachment);
}

View file

@ -0,0 +1,597 @@
/*
* 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;
import java.io.IOException;
import java.net.ProtocolFamily;
import java.net.DatagramSocket;
import java.net.SocketOption;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.SelectorProvider;
/**
* A selectable channel for datagram-oriented sockets.
*
* <p> A datagram channel is created by invoking one of the {@link #open open} methods
* of this class. It is not possible to create a channel for an arbitrary,
* pre-existing datagram socket. A newly-created datagram channel is open but not
* connected. A datagram channel need not be connected in order for the {@link #send
* send} and {@link #receive receive} methods to be used. A datagram channel may be
* connected, by invoking its {@link #connect connect} method, in order to
* avoid the overhead of the security checks are otherwise performed as part of
* every send and receive operation. A datagram channel must be connected in
* order to use the {@link #read(java.nio.ByteBuffer) read} and {@link
* #write(java.nio.ByteBuffer) write} methods, since those methods do not
* accept or return socket addresses.
*
* <p> Once connected, a datagram channel remains connected until it is
* disconnected or closed. Whether or not a datagram channel is connected may
* be determined by invoking its {@link #isConnected isConnected} method.
*
* <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
* setOption} method. A datagram channel to an Internet Protocol socket supports
* the following options:
* <blockquote>
* <table class="striped">
* <caption style="display:none">Socket options</caption>
* <thead>
* <tr>
* <th scope="col">Option Name</th>
* <th scope="col">Description</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#SO_SNDBUF SO_SNDBUF} </th>
* <td> The size of the socket send buffer </td>
* </tr>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </th>
* <td> The size of the socket receive buffer </td>
* </tr>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </th>
* <td> Re-use address </td>
* </tr>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#SO_BROADCAST SO_BROADCAST} </th>
* <td> Allow transmission of broadcast datagrams </td>
* </tr>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#IP_TOS IP_TOS} </th>
* <td> The Type of Service (ToS) octet in the Internet Protocol (IP) header </td>
* </tr>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#IP_MULTICAST_IF IP_MULTICAST_IF} </th>
* <td> The network interface for Internet Protocol (IP) multicast datagrams </td>
* </tr>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#IP_MULTICAST_TTL
* IP_MULTICAST_TTL} </th>
* <td> The <em>time-to-live</em> for Internet Protocol (IP) multicast
* datagrams </td>
* </tr>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#IP_MULTICAST_LOOP
* IP_MULTICAST_LOOP} </th>
* <td> Loopback for Internet Protocol (IP) multicast datagrams </td>
* </tr>
* </tbody>
* </table>
* </blockquote>
* Additional (implementation specific) options may also be supported.
*
* <p> Datagram channels are safe for use by multiple concurrent threads. They
* support concurrent reading and writing, though at most one thread may be
* reading and at most one thread may be writing at any given time. </p>
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public abstract class DatagramChannel
extends AbstractSelectableChannel
implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, MulticastChannel
{
/**
* Initializes a new instance of this class.
*
* @param provider
* The provider that created this channel
*/
protected DatagramChannel(SelectorProvider provider) {
super(provider);
}
/**
* Opens a datagram channel.
*
* <p> The new channel is created by invoking the {@link
* java.nio.channels.spi.SelectorProvider#openDatagramChannel()
* openDatagramChannel} method of the system-wide default {@link
* java.nio.channels.spi.SelectorProvider} object. The channel will not be
* connected.
*
* <p> The {@link ProtocolFamily ProtocolFamily} of the channel's socket
* is platform (and possibly configuration) dependent and therefore unspecified.
* The {@link #open(ProtocolFamily) open} allows the protocol family to be
* selected when opening a datagram channel, and should be used to open
* datagram channels that are intended for Internet Protocol multicasting.
*
* @return A new datagram channel
*
* @throws IOException
* If an I/O error occurs
*/
public static DatagramChannel open() throws IOException {
return SelectorProvider.provider().openDatagramChannel();
}
/**
* Opens a datagram channel.
*
* <p> The {@code family} parameter is used to specify the {@link
* ProtocolFamily}. If the datagram channel is to be used for IP multicasting
* then this should correspond to the address type of the multicast groups
* that this channel will join.
*
* <p> The new channel is created by invoking the {@link
* java.nio.channels.spi.SelectorProvider#openDatagramChannel(ProtocolFamily)
* openDatagramChannel} method of the system-wide default {@link
* java.nio.channels.spi.SelectorProvider} object. The channel will not be
* connected.
*
* @param family
* The protocol family
*
* @return A new datagram channel
*
* @throws UnsupportedOperationException
* If the specified protocol family is not supported. For example,
* suppose the parameter is specified as {@link
* java.net.StandardProtocolFamily#INET6 StandardProtocolFamily.INET6}
* but IPv6 is not enabled on the platform.
* @throws IOException
* If an I/O error occurs
*
* @since 1.7
*/
public static DatagramChannel open(ProtocolFamily family) throws IOException {
return SelectorProvider.provider().openDatagramChannel(family);
}
/**
* Returns an operation set identifying this channel's supported
* operations.
*
* <p> Datagram channels support reading and writing, so this method
* returns {@code (}{@link SelectionKey#OP_READ} {@code |}&nbsp;{@link
* SelectionKey#OP_WRITE}{@code )}.
*
* @return The valid-operation set
*/
public final int validOps() {
return (SelectionKey.OP_READ
| SelectionKey.OP_WRITE);
}
// -- Socket-specific operations --
/**
* @throws AlreadyBoundException {@inheritDoc}
* @throws UnsupportedAddressTypeException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
* @throws SecurityException
* If a security manager has been installed and its {@link
* SecurityManager#checkListen checkListen} method denies the
* operation
*
* @since 1.7
*/
public abstract DatagramChannel bind(SocketAddress local)
throws IOException;
/**
* @throws UnsupportedOperationException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
*
* @since 1.7
*/
public abstract <T> DatagramChannel setOption(SocketOption<T> name, T value)
throws IOException;
/**
* Retrieves a datagram socket associated with this channel.
*
* <p> The returned object will not declare any public methods that are not
* declared in the {@link java.net.DatagramSocket} class. </p>
*
* @return A datagram socket associated with this channel
*/
public abstract DatagramSocket socket();
/**
* Tells whether or not this channel's socket is connected.
*
* @return {@code true} if, and only if, this channel's socket
* is {@link #isOpen open} and connected
*/
public abstract boolean isConnected();
/**
* Connects this channel's socket.
*
* <p> The channel's socket is configured so that it only receives
* datagrams from, and sends datagrams to, the given remote <i>peer</i>
* address. Once connected, datagrams may not be received from or sent to
* any other address. A datagram socket remains connected until it is
* explicitly disconnected or until it is closed.
*
* <p> This method performs exactly the same security checks as the {@link
* java.net.DatagramSocket#connect connect} method of the {@link
* java.net.DatagramSocket} class. That is, if a security manager has been
* installed then this method verifies that its {@link
* java.lang.SecurityManager#checkAccept checkAccept} and {@link
* java.lang.SecurityManager#checkConnect checkConnect} methods permit
* datagrams to be received from and sent to, respectively, the given
* remote address.
*
* <p> This method may be invoked at any time. It will not have any effect
* on read or write operations that are already in progress at the moment
* that it is invoked. If this channel's socket is not bound then this method
* will first cause the socket to be bound to an address that is assigned
* automatically, as if invoking the {@link #bind bind} method with a
* parameter of {@code null}. </p>
*
* @param remote
* The remote address to which this channel is to be connected
*
* @return This datagram channel
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws AsynchronousCloseException
* If another thread closes this channel
* while the connect operation is in progress
*
* @throws ClosedByInterruptException
* If another thread interrupts the current thread
* while the connect operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws SecurityException
* If a security manager has been installed
* and it does not permit access to the given remote address
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract DatagramChannel connect(SocketAddress remote)
throws IOException;
/**
* Disconnects this channel's socket.
*
* <p> The channel's socket is configured so that it can receive datagrams
* from, and sends datagrams to, any remote address so long as the security
* manager, if installed, permits it.
*
* <p> This method may be invoked at any time. It will not have any effect
* on read or write operations that are already in progress at the moment
* that it is invoked.
*
* <p> If this channel's socket is not connected, or if the channel is
* closed, then invoking this method has no effect. </p>
*
* @return This datagram channel
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract DatagramChannel disconnect() throws IOException;
/**
* Returns the remote address to which this channel's socket is connected.
*
* @return The remote address; {@code null} if the channel's socket is not
* connected
*
* @throws ClosedChannelException
* If the channel is closed
* @throws IOException
* If an I/O error occurs
*
* @since 1.7
*/
public abstract SocketAddress getRemoteAddress() throws IOException;
/**
* Receives a datagram via this channel.
*
* <p> If a datagram is immediately available, or if this channel is in
* blocking mode and one eventually becomes available, then the datagram is
* copied into the given byte buffer and its source address is returned.
* If this channel is in non-blocking mode and a datagram is not
* immediately available then this method immediately returns
* {@code null}.
*
* <p> The datagram is transferred into the given byte buffer starting at
* its current position, as if by a regular {@link
* ReadableByteChannel#read(java.nio.ByteBuffer) read} operation. If there
* are fewer bytes remaining in the buffer than are required to hold the
* datagram then the remainder of the datagram is silently discarded.
*
* <p> This method performs exactly the same security checks as the {@link
* java.net.DatagramSocket#receive receive} method of the {@link
* java.net.DatagramSocket} class. That is, if the socket is not connected
* to a specific remote address and a security manager has been installed
* then for each datagram received this method verifies that the source's
* address and port number are permitted by the security manager's {@link
* java.lang.SecurityManager#checkAccept checkAccept} method. The overhead
* of this security check can be avoided by first connecting the socket via
* the {@link #connect connect} method.
*
* <p> This method may be invoked at any time. If another thread has
* already initiated a read operation upon this channel, however, then an
* invocation of this method will block until the first operation is
* complete. If this channel's socket is not bound then this method will
* first cause the socket to be bound to an address that is assigned
* automatically, as if invoking the {@link #bind bind} method with a
* parameter of {@code null}. </p>
*
* @param dst
* The buffer into which the datagram is to be transferred
*
* @return The datagram's source address,
* or {@code null} if this channel is in non-blocking mode
* and no datagram was immediately available
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws AsynchronousCloseException
* If another thread closes this channel
* while the read operation is in progress
*
* @throws ClosedByInterruptException
* If another thread interrupts the current thread
* while the read operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws SecurityException
* If a security manager has been installed
* and it does not permit datagrams to be accepted
* from the datagram's sender
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract SocketAddress receive(ByteBuffer dst) throws IOException;
/**
* Sends a datagram via this channel.
*
* <p> If this channel is in non-blocking mode and there is sufficient room
* in the underlying output buffer, or if this channel is in blocking mode
* and sufficient room becomes available, then the remaining bytes in the
* given buffer are transmitted as a single datagram to the given target
* address.
*
* <p> The datagram is transferred from the byte buffer as if by a regular
* {@link WritableByteChannel#write(java.nio.ByteBuffer) write} operation.
*
* <p> This method performs exactly the same security checks as the {@link
* java.net.DatagramSocket#send send} method of the {@link
* java.net.DatagramSocket} class. That is, if the socket is not connected
* to a specific remote address and a security manager has been installed
* then for each datagram sent this method verifies that the target address
* and port number are permitted by the security manager's {@link
* java.lang.SecurityManager#checkConnect checkConnect} method. The
* overhead of this security check can be avoided by first connecting the
* socket via the {@link #connect connect} method.
*
* <p> This method may be invoked at any time. If another thread has
* already initiated a write operation upon this channel, however, then an
* invocation of this method will block until the first operation is
* complete. If this channel's socket is not bound then this method will
* first cause the socket to be bound to an address that is assigned
* automatically, as if by invoking the {@link #bind bind} method with a
* parameter of {@code null}. </p>
*
* @param src
* The buffer containing the datagram to be sent
*
* @param target
* The address to which the datagram is to be sent
*
* @return The number of bytes sent, which will be either the number
* of bytes that were remaining in the source buffer when this
* method was invoked or, if this channel is non-blocking, may be
* zero if there was insufficient room for the datagram in the
* underlying output buffer
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws AsynchronousCloseException
* If another thread closes this channel
* while the read operation is in progress
*
* @throws ClosedByInterruptException
* If another thread interrupts the current thread
* while the read operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws SecurityException
* If a security manager has been installed
* and it does not permit datagrams to be sent
* to the given address
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract int send(ByteBuffer src, SocketAddress target)
throws IOException;
// -- ByteChannel operations --
/**
* Reads a datagram from this channel.
*
* <p> This method may only be invoked if this channel's socket is
* connected, and it only accepts datagrams from the socket's peer. If
* there are more bytes in the datagram than remain in the given buffer
* then the remainder of the datagram is silently discarded. Otherwise
* this method behaves exactly as specified in the {@link
* ReadableByteChannel} interface. </p>
*
* @throws NotYetConnectedException
* If this channel's socket is not connected
*/
public abstract int read(ByteBuffer dst) throws IOException;
/**
* Reads a datagram from this channel.
*
* <p> This method may only be invoked if this channel's socket is
* connected, and it only accepts datagrams from the socket's peer. If
* there are more bytes in the datagram than remain in the given buffers
* then the remainder of the datagram is silently discarded. Otherwise
* this method behaves exactly as specified in the {@link
* ScatteringByteChannel} interface. </p>
*
* @throws NotYetConnectedException
* If this channel's socket is not connected
*/
public abstract long read(ByteBuffer[] dsts, int offset, int length)
throws IOException;
/**
* Reads a datagram from this channel.
*
* <p> This method may only be invoked if this channel's socket is
* connected, and it only accepts datagrams from the socket's peer. If
* there are more bytes in the datagram than remain in the given buffers
* then the remainder of the datagram is silently discarded. Otherwise
* this method behaves exactly as specified in the {@link
* ScatteringByteChannel} interface. </p>
*
* @throws NotYetConnectedException
* If this channel's socket is not connected
*/
public final long read(ByteBuffer[] dsts) throws IOException {
return read(dsts, 0, dsts.length);
}
/**
* Writes a datagram to this channel.
*
* <p> This method may only be invoked if this channel's socket is
* connected, in which case it sends datagrams directly to the socket's
* peer. Otherwise it behaves exactly as specified in the {@link
* WritableByteChannel} interface. </p>
*
* @throws NotYetConnectedException
* If this channel's socket is not connected
*/
public abstract int write(ByteBuffer src) throws IOException;
/**
* Writes a datagram to this channel.
*
* <p> This method may only be invoked if this channel's socket is
* connected, in which case it sends datagrams directly to the socket's
* peer. Otherwise it behaves exactly as specified in the {@link
* GatheringByteChannel} interface. </p>
*
* @return The number of bytes sent, which will be either the number
* of bytes that were remaining in the source buffer when this
* method was invoked or, if this channel is non-blocking, may be
* zero if there was insufficient room for the datagram in the
* underlying output buffer
*
* @throws NotYetConnectedException
* If this channel's socket is not connected
*/
public abstract long write(ByteBuffer[] srcs, int offset, int length)
throws IOException;
/**
* Writes a datagram to this channel.
*
* <p> This method may only be invoked if this channel's socket is
* connected, in which case it sends datagrams directly to the socket's
* peer. Otherwise it behaves exactly as specified in the {@link
* GatheringByteChannel} interface. </p>
*
* @return The number of bytes sent, which will be either the number
* of bytes that were remaining in the source buffer when this
* method was invoked or, if this channel is non-blocking, may be
* zero if there was insufficient room for the datagram in the
* underlying output buffer
*
* @throws NotYetConnectedException
* If this channel's socket is not connected
*/
public final long write(ByteBuffer[] srcs) throws IOException {
return write(srcs, 0, srcs.length);
}
/**
* {@inheritDoc}
* <p>
* If there is a security manager set, its {@code checkConnect} method is
* called with the local address and {@code -1} as its arguments to see
* if the operation is allowed. If the operation is not allowed,
* a {@code SocketAddress} representing the
* {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
* local port of the channel's socket is returned.
*
* @return The {@code SocketAddress} that the socket is bound to, or the
* {@code SocketAddress} representing the loopback address if
* denied by the security manager, or {@code null} if the
* channel's socket is not bound
*
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
*/
@Override
public abstract SocketAddress getLocalAddress() throws IOException;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,334 @@
/*
* Copyright (c) 2001, 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;
import java.io.IOException;
import java.util.Objects;
/**
* A token representing a lock on a region of a file.
*
* <p> A file-lock object is created each time a lock is acquired on a file via
* one of the {@link FileChannel#lock(long,long,boolean) lock} or {@link
* FileChannel#tryLock(long,long,boolean) tryLock} methods of the
* {@link FileChannel} class, or the {@link
* AsynchronousFileChannel#lock(long,long,boolean,Object,CompletionHandler) lock}
* or {@link AsynchronousFileChannel#tryLock(long,long,boolean) tryLock}
* methods of the {@link AsynchronousFileChannel} class.
*
* <p> A file-lock object is initially valid. It remains valid until the lock
* is released by invoking the {@link #release release} method, by closing the
* channel that was used to acquire it, or by the termination of the Java
* virtual machine, whichever comes first. The validity of a lock may be
* tested by invoking its {@link #isValid isValid} method.
*
* <p> A file lock is either <i>exclusive</i> or <i>shared</i>. A shared lock
* prevents other concurrently-running programs from acquiring an overlapping
* exclusive lock, but does allow them to acquire overlapping shared locks. An
* exclusive lock prevents other programs from acquiring an overlapping lock of
* either type. Once it is released, a lock has no further effect on the locks
* that may be acquired by other programs.
*
* <p> Whether a lock is exclusive or shared may be determined by invoking its
* {@link #isShared isShared} method. Some platforms do not support shared
* locks, in which case a request for a shared lock is automatically converted
* into a request for an exclusive lock.
*
* <p> The locks held on a particular file by a single Java virtual machine do
* not overlap. The {@link #overlaps overlaps} method may be used to test
* whether a candidate lock range overlaps an existing lock.
*
* <p> A file-lock object records the file channel upon whose file the lock is
* held, the type and validity of the lock, and the position and size of the
* locked region. Only the validity of a lock is subject to change over time;
* all other aspects of a lock's state are immutable.
*
* <p> File locks are held on behalf of the entire Java virtual machine.
* They are not suitable for controlling access to a file by multiple
* threads within the same virtual machine.
*
* <p> File-lock objects are safe for use by multiple concurrent threads.
*
*
* <a id="pdep"></a><h2> Platform dependencies </h2>
*
* <p> This file-locking API is intended to map directly to the native locking
* facility of the underlying operating system. Thus the locks held on a file
* should be visible to all programs that have access to the file, regardless
* of the language in which those programs are written.
*
* <p> Whether or not a lock actually prevents another program from accessing
* the content of the locked region is system-dependent and therefore
* unspecified. The native file-locking facilities of some systems are merely
* <i>advisory</i>, meaning that programs must cooperatively observe a known
* locking protocol in order to guarantee data integrity. On other systems
* native file locks are <i>mandatory</i>, meaning that if one program locks a
* region of a file then other programs are actually prevented from accessing
* that region in a way that would violate the lock. On yet other systems,
* whether native file locks are advisory or mandatory is configurable on a
* per-file basis. To ensure consistent and correct behavior across platforms,
* it is strongly recommended that the locks provided by this API be used as if
* they were advisory locks.
*
* <p> On some systems, acquiring a mandatory lock on a region of a file
* prevents that region from being {@link java.nio.channels.FileChannel#map
* <i>mapped into memory</i>}, and vice versa. Programs that combine
* locking and mapping should be prepared for this combination to fail.
*
* <p> On some systems, closing a channel releases all locks held by the Java
* virtual machine on the underlying file regardless of whether the locks were
* acquired via that channel or via another channel open on the same file. It
* is strongly recommended that, within a program, a unique channel be used to
* acquire all locks on any given file.
*
* <p> Some network filesystems permit file locking to be used with
* memory-mapped files only when the locked regions are page-aligned and a
* whole multiple of the underlying hardware's page size. Some network
* filesystems do not implement file locks on regions that extend past a
* certain position, often 2<sup>30</sup> or 2<sup>31</sup>. In general, great
* care should be taken when locking files that reside on network filesystems.
*
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public abstract class FileLock implements AutoCloseable {
private final Channel channel;
private final long position;
private final long size;
private final boolean shared;
/**
* Initializes a new instance of this class.
*
* @param channel
* The file channel upon whose file this lock is held
*
* @param position
* The position within the file at which the locked region starts;
* must be non-negative
*
* @param size
* The size of the locked region; must be non-negative, and the sum
* {@code position}&nbsp;+&nbsp;{@code size} must be non-negative
*
* @param shared
* {@code true} if this lock is shared,
* {@code false} if it is exclusive
*
* @throws IllegalArgumentException
* If the preconditions on the parameters do not hold
*/
protected FileLock(FileChannel channel,
long position, long size, boolean shared)
{
Objects.requireNonNull(channel, "Null channel");
if (position < 0)
throw new IllegalArgumentException("Negative position");
if (size < 0)
throw new IllegalArgumentException("Negative size");
if (position + size < 0)
throw new IllegalArgumentException("Negative position + size");
this.channel = channel;
this.position = position;
this.size = size;
this.shared = shared;
}
/**
* Initializes a new instance of this class.
*
* @param channel
* The channel upon whose file this lock is held
*
* @param position
* The position within the file at which the locked region starts;
* must be non-negative
*
* @param size
* The size of the locked region; must be non-negative, and the sum
* {@code position}&nbsp;+&nbsp;{@code size} must be non-negative
*
* @param shared
* {@code true} if this lock is shared,
* {@code false} if it is exclusive
*
* @throws IllegalArgumentException
* If the preconditions on the parameters do not hold
*
* @since 1.7
*/
protected FileLock(AsynchronousFileChannel channel,
long position, long size, boolean shared)
{
Objects.requireNonNull(channel, "Null channel");
if (position < 0)
throw new IllegalArgumentException("Negative position");
if (size < 0)
throw new IllegalArgumentException("Negative size");
if (position + size < 0)
throw new IllegalArgumentException("Negative position + size");
this.channel = channel;
this.position = position;
this.size = size;
this.shared = shared;
}
/**
* Returns the file channel upon whose file this lock was acquired.
*
* <p> This method has been superseded by the {@link #acquiredBy acquiredBy}
* method.
*
* @return The file channel, or {@code null} if the file lock was not
* acquired by a file channel.
*/
public final FileChannel channel() {
return (channel instanceof FileChannel) ? (FileChannel)channel : null;
}
/**
* Returns the channel upon whose file this lock was acquired.
*
* @return The channel upon whose file this lock was acquired.
*
* @since 1.7
*/
public Channel acquiredBy() {
return channel;
}
/**
* Returns the position within the file of the first byte of the locked
* region.
*
* <p> A locked region need not be contained within, or even overlap, the
* actual underlying file, so the value returned by this method may exceed
* the file's current size. </p>
*
* @return The position
*/
public final long position() {
return position;
}
/**
* Returns the size of the locked region in bytes.
*
* <p> A locked region need not be contained within, or even overlap, the
* actual underlying file, so the value returned by this method may exceed
* the file's current size. </p>
*
* @return The size of the locked region
*/
public final long size() {
return size;
}
/**
* Tells whether this lock is shared.
*
* @return {@code true} if lock is shared,
* {@code false} if it is exclusive
*/
public final boolean isShared() {
return shared;
}
/**
* Tells whether or not this lock overlaps the given lock range.
*
* @param position
* The starting position of the lock range
* @param size
* The size of the lock range
*
* @return {@code true} if, and only if, this lock and the given lock
* range overlap by at least one byte
*/
public final boolean overlaps(long position, long size) {
if (position + size <= this.position)
return false; // That is below this
if (this.position + this.size <= position)
return false; // This is below that
return true;
}
/**
* Tells whether or not this lock is valid.
*
* <p> A lock object remains valid until it is released or the associated
* file channel is closed, whichever comes first. </p>
*
* @return {@code true} if, and only if, this lock is valid
*/
public abstract boolean isValid();
/**
* Releases this lock.
*
* <p> If this lock object is valid then invoking this method releases the
* lock and renders the object invalid. If this lock object is invalid
* then invoking this method has no effect. </p>
*
* @throws ClosedChannelException
* If the channel that was used to acquire this lock
* is no longer open
*
* @throws IOException
* If an I/O error occurs
*/
public abstract void release() throws IOException;
/**
* This method invokes the {@link #release} method. It was added
* to the class so that it could be used in conjunction with the
* automatic resource management block construct.
*
* @since 1.7
*/
public final void close() throws IOException {
release();
}
/**
* Returns a string describing the range, type, and validity of this lock.
*
* @return A descriptive string
*/
public final String toString() {
return (this.getClass().getName()
+ "[" + position
+ ":" + size
+ " " + (shared ? "shared" : "exclusive")
+ " " + (isValid() ? "valid" : "invalid")
+ "]");
}
}

View file

@ -0,0 +1,166 @@
/*
* Copyright (c) 2000, 2001, 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;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* A channel that can write bytes from a sequence of buffers.
*
* <p> A <i>gathering</i> write operation writes, in a single invocation, a
* sequence of bytes from one or more of a given sequence of buffers.
* Gathering writes are often useful when implementing network protocols or
* file formats that, for example, group data into segments consisting of one
* or more fixed-length headers followed by a variable-length body. Similar
* <i>scattering</i> read operations are defined in the {@link
* ScatteringByteChannel} interface. </p>
*
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public interface GatheringByteChannel
extends WritableByteChannel
{
/**
* Writes a sequence of bytes to this channel from a subsequence of the
* given buffers.
*
* <p> An attempt is made to write up to <i>r</i> bytes to this channel,
* where <i>r</i> is the total number of bytes remaining in the specified
* subsequence of the given buffer array, that is,
*
* <blockquote><pre>
* srcs[offset].remaining()
* + srcs[offset+1].remaining()
* + ... + srcs[offset+length-1].remaining()</pre></blockquote>
*
* at the moment that this method is invoked.
*
* <p> Suppose that a byte sequence of length <i>n</i> is written, where
* {@code 0}&nbsp;{@code <=}&nbsp;<i>n</i>&nbsp;{@code <=}&nbsp;<i>r</i>.
* Up to the first {@code srcs[offset].remaining()} bytes of this sequence
* are written from buffer {@code srcs[offset]}, up to the next
* {@code srcs[offset+1].remaining()} bytes are written from buffer
* {@code srcs[offset+1]}, and so forth, until the entire byte sequence is
* written. As many bytes as possible are written from each buffer, hence
* the final position of each updated buffer, except the last updated
* buffer, is guaranteed to be equal to that buffer's limit.
*
* <p> Unless otherwise specified, a write operation will return only after
* writing all of the <i>r</i> requested bytes. Some types of channels,
* depending upon their state, may write only some of the bytes or possibly
* none at all. A socket channel in non-blocking mode, for example, cannot
* write any more bytes than are free in the socket's output buffer.
*
* <p> This method may be invoked at any time. If another thread has
* already initiated a write operation upon this channel, however, then an
* invocation of this method will block until the first operation is
* complete. </p>
*
* @param srcs
* The buffers from which bytes are to be retrieved
*
* @param offset
* The offset within the buffer array of the first buffer from
* which bytes are to be retrieved; must be non-negative and no
* larger than {@code srcs.length}
*
* @param length
* The maximum number of buffers to be accessed; must be
* non-negative and no larger than
* {@code srcs.length}&nbsp;-&nbsp;{@code offset}
*
* @return The number of bytes written, possibly zero
*
* @throws IndexOutOfBoundsException
* If the preconditions on the {@code offset} and {@code length}
* parameters do not hold
*
* @throws NonWritableChannelException
* If this channel was not opened for writing
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws AsynchronousCloseException
* If another thread closes this channel
* while the write operation is in progress
*
* @throws ClosedByInterruptException
* If another thread interrupts the current thread
* while the write operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws IOException
* If some other I/O error occurs
*/
public long write(ByteBuffer[] srcs, int offset, int length)
throws IOException;
/**
* Writes a sequence of bytes to this channel from the given buffers.
*
* <p> An invocation of this method of the form {@code c.write(srcs)}
* behaves in exactly the same manner as the invocation
*
* <blockquote><pre>
* c.write(srcs, 0, srcs.length);</pre></blockquote>
*
* @param srcs
* The buffers from which bytes are to be retrieved
*
* @return The number of bytes written, possibly zero
*
* @throws NonWritableChannelException
* If this channel was not opened for writing
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws AsynchronousCloseException
* If another thread closes this channel
* while the write operation is in progress
*
* @throws ClosedByInterruptException
* If another thread interrupts the current thread
* while the write operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws IOException
* If some other I/O error occurs
*/
public long write(ByteBuffer[] srcs) throws IOException;
}

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2001, 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;
import java.io.IOException;
/**
* A channel that can be asynchronously closed and interrupted.
*
* <p> A channel that implements this interface is <i>asynchronously
* closeable:</i> If a thread is blocked in an I/O operation on an
* interruptible channel then another thread may invoke the channel's {@link
* #close close} method. This will cause the blocked thread to receive an
* {@link AsynchronousCloseException}.
*
* <p> A channel that implements this interface is also <i>interruptible:</i>
* If a thread is blocked in an I/O operation on an interruptible channel then
* another thread may invoke the blocked thread's {@link Thread#interrupt()
* interrupt} method. This will cause the channel to be closed, the blocked
* thread to receive a {@link ClosedByInterruptException}, and the blocked
* thread's interrupt status to be set.
*
* <p> If a thread's interrupt status is already set and it invokes a blocking
* I/O operation upon a channel then the channel will be closed and the thread
* will immediately receive a {@link ClosedByInterruptException}; its interrupt
* status will remain set.
*
* <p> A channel supports asynchronous closing and interruption if, and only
* if, it implements this interface. This can be tested at runtime, if
* necessary, via the {@code instanceof} operator.
*
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public interface InterruptibleChannel
extends Channel
{
/**
* Closes this channel.
*
* <p> Any thread currently blocked in an I/O operation upon this channel
* will receive an {@link AsynchronousCloseException}.
*
* <p> This method otherwise behaves exactly as specified by the {@link
* Channel#close Channel} interface. </p>
*
* @throws IOException If an I/O error occurs
*/
public void close() throws IOException;
}

View file

@ -0,0 +1,177 @@
/*
* 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;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.io.IOException;
/**
* A token representing the membership of an Internet Protocol (IP) multicast
* group.
*
* <p> A membership key may represent a membership to receive all datagrams sent
* to the group, or it may be <em>source-specific</em>, meaning that it
* represents a membership that receives only datagrams from a specific source
* address. Whether or not a membership key is source-specific may be determined
* by invoking its {@link #sourceAddress() sourceAddress} method.
*
* <p> A membership key is valid upon creation and remains valid until the
* membership is dropped by invoking the {@link #drop() drop} method, or
* the channel is closed. The validity of the membership key may be tested
* by invoking its {@link #isValid() isValid} method.
*
* <p> Where a membership key is not source-specific and the underlying operation
* system supports source filtering, then the {@link #block block} and {@link
* #unblock unblock} methods can be used to block or unblock multicast datagrams
* from particular source addresses.
*
* @see MulticastChannel
*
* @since 1.7
*/
public abstract class MembershipKey {
/**
* Initializes a new instance of this class.
*/
protected MembershipKey() {
}
/**
* Tells whether or not this membership is valid.
*
* <p> A multicast group membership is valid upon creation and remains
* valid until the membership is dropped by invoking the {@link #drop() drop}
* method, or the channel is closed.
*
* @return {@code true} if this membership key is valid, {@code false}
* otherwise
*/
public abstract boolean isValid();
/**
* Drop membership.
*
* <p> If the membership key represents a membership to receive all datagrams
* then the membership is dropped and the channel will no longer receive any
* datagrams sent to the group. If the membership key is source-specific
* then the channel will no longer receive datagrams sent to the group from
* that source address.
*
* <p> After membership is dropped it may still be possible to receive
* datagrams sent to the group. This can arise when datagrams are waiting to
* be received in the socket's receive buffer. After membership is dropped
* then the channel may {@link MulticastChannel#join join} the group again
* in which case a new membership key is returned.
*
* <p> Upon return, this membership object will be {@link #isValid() invalid}.
* If the multicast group membership is already invalid then invoking this
* method has no effect. Once a multicast group membership is invalid,
* it remains invalid forever.
*/
public abstract void drop();
/**
* Block multicast datagrams from the given source address.
*
* <p> If this membership key is not source-specific, and the underlying
* operating system supports source filtering, then this method blocks
* multicast datagrams from the given source address. If the given source
* address is already blocked then this method has no effect.
* After a source address is blocked it may still be possible to receive
* datagrams from that source. This can arise when datagrams are waiting to
* be received in the socket's receive buffer.
*
* @param source
* The source address to block
*
* @return This membership key
*
* @throws IllegalArgumentException
* If the {@code source} parameter is not a unicast address or
* is not the same address type as the multicast group
* @throws IllegalStateException
* If this membership key is source-specific or is no longer valid
* @throws UnsupportedOperationException
* If the underlying operating system does not support source
* filtering
* @throws IOException
* If an I/O error occurs
*/
public abstract MembershipKey block(InetAddress source) throws IOException;
/**
* Unblock multicast datagrams from the given source address that was
* previously blocked using the {@link #block(InetAddress) block} method.
*
* @param source
* The source address to unblock
*
* @return This membership key
*
* @throws IllegalStateException
* If the given source address is not currently blocked or the
* membership key is no longer valid
*/
public abstract MembershipKey unblock(InetAddress source);
/**
* Returns the channel for which this membership key was created. This
* method will continue to return the channel even after the membership
* becomes {@link #isValid invalid}.
*
* @return the channel
*/
public abstract MulticastChannel channel();
/**
* Returns the multicast group for which this membership key was created.
* This method will continue to return the group even after the membership
* becomes {@link #isValid invalid}.
*
* @return the multicast group
*/
public abstract InetAddress group();
/**
* Returns the network interface for which this membership key was created.
* This method will continue to return the network interface even after the
* membership becomes {@link #isValid invalid}.
*
* @return the network interface
*/
public abstract NetworkInterface networkInterface();
/**
* Returns the source address if this membership key is source-specific,
* or {@code null} if this membership is not source-specific.
*
* @return The source address if this membership key is source-specific,
* otherwise {@code null}
*/
public abstract InetAddress sourceAddress();
}

View file

@ -0,0 +1,233 @@
/*
* 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;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.io.IOException;
import java.net.ProtocolFamily; // javadoc
import java.net.StandardProtocolFamily; // javadoc
import java.net.StandardSocketOptions; // javadoc
/**
* A network channel that supports Internet Protocol (IP) multicasting.
*
* <p> IP multicasting is the transmission of IP datagrams to members of
* a <em>group</em> that is zero or more hosts identified by a single destination
* address.
*
* <p> In the case of a channel to an {@link StandardProtocolFamily#INET IPv4} socket,
* the underlying operating system optionally supports
* <a href="http://www.ietf.org/rfc/rfc2236.txt"> <i>RFC&nbsp;2236: Internet Group
* Management Protocol, Version 2 (IGMPv2)</i></a>. When IGMPv2 is supported then
* the operating system may additionally support source filtering as specified by
* <a href="http://www.ietf.org/rfc/rfc3376.txt"> <i>RFC&nbsp;3376: Internet Group
* Management Protocol, Version 3 (IGMPv3)</i></a>.
* For channels to an {@link StandardProtocolFamily#INET6 IPv6} socket, the equivalent
* standards are <a href="http://www.ietf.org/rfc/rfc2710.txt"> <i>RFC&nbsp;2710:
* Multicast Listener Discovery (MLD) for IPv6</i></a> and <a
* href="http://www.ietf.org/rfc/rfc3810.txt"> <i>RFC&nbsp;3810: Multicast Listener
* Discovery Version 2 (MLDv2) for IPv6</i></a>.
*
* <p> The {@link #join(InetAddress,NetworkInterface)} method is used to
* join a group and receive all multicast datagrams sent to the group. A channel
* may join several multicast groups and may join the same group on several
* {@link NetworkInterface interfaces}. Membership is dropped by invoking the {@link
* MembershipKey#drop drop} method on the returned {@link MembershipKey}. If the
* underlying platform supports source filtering then the {@link MembershipKey#block
* block} and {@link MembershipKey#unblock unblock} methods can be used to block or
* unblock multicast datagrams from particular source addresses.
*
* <p> The {@link #join(InetAddress,NetworkInterface,InetAddress)} method
* is used to begin receiving datagrams sent to a group whose source address matches
* a given source address. This method throws {@link UnsupportedOperationException}
* if the underlying platform does not support source filtering. Membership is
* <em>cumulative</em> and this method may be invoked again with the same group
* and interface to allow receiving datagrams from other source addresses. The
* method returns a {@link MembershipKey} that represents membership to receive
* datagrams from the given source address. Invoking the key's {@link
* MembershipKey#drop drop} method drops membership so that datagrams from the
* source address can no longer be received.
*
* <h2>Platform dependencies</h2>
*
* The multicast implementation is intended to map directly to the native
* multicasting facility. Consequently, the following items should be considered
* when developing an application that receives IP multicast datagrams:
*
* <ol>
*
* <li><p> The creation of the channel should specify the {@link ProtocolFamily}
* that corresponds to the address type of the multicast groups that the channel
* will join. There is no guarantee that a channel to a socket in one protocol
* family can join and receive multicast datagrams when the address of the
* multicast group corresponds to another protocol family. For example, it is
* implementation specific if a channel to an {@link StandardProtocolFamily#INET6 IPv6}
* socket can join an {@link StandardProtocolFamily#INET IPv4} multicast group and receive
* multicast datagrams sent to the group. </p></li>
*
* <li><p> The channel's socket should be bound to the {@link
* InetAddress#isAnyLocalAddress wildcard} address. If the socket is bound to
* a specific address, rather than the wildcard address then it is implementation
* specific if multicast datagrams are received by the socket. </p></li>
*
* <li><p> The {@link StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} option should be
* enabled prior to {@link NetworkChannel#bind binding} the socket. This is
* required to allow multiple members of the group to bind to the same
* address. </p></li>
*
* </ol>
*
* <p> <b>Usage Example:</b>
* <pre>
* // join multicast group on this interface, and also use this
* // interface for outgoing multicast datagrams
* NetworkInterface ni = NetworkInterface.getByName("hme0");
*
* DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET)
* .setOption(StandardSocketOptions.SO_REUSEADDR, true)
* .bind(new InetSocketAddress(5000))
* .setOption(StandardSocketOptions.IP_MULTICAST_IF, ni);
*
* InetAddress group = InetAddress.getByName("225.4.5.6");
*
* MembershipKey key = dc.join(group, ni);
* </pre>
*
* @since 1.7
*/
public interface MulticastChannel
extends NetworkChannel
{
/**
* Closes this channel.
*
* <p> If the channel is a member of a multicast group then the membership
* is {@link MembershipKey#drop dropped}. Upon return, the {@link
* MembershipKey membership-key} will be {@link MembershipKey#isValid
* invalid}.
*
* <p> This method otherwise behaves exactly as specified by the {@link
* Channel} interface.
*
* @throws IOException
* If an I/O error occurs
*/
@Override void close() throws IOException;
/**
* Joins a multicast group to begin receiving all datagrams sent to the group,
* returning a membership key.
*
* <p> If this channel is currently a member of the group on the given
* interface to receive all datagrams then the membership key, representing
* that membership, is returned. Otherwise this channel joins the group and
* the resulting new membership key is returned. The resulting membership key
* is not {@link MembershipKey#sourceAddress source-specific}.
*
* <p> A multicast channel may join several multicast groups, including
* the same group on more than one interface. An implementation may impose a
* limit on the number of groups that may be joined at the same time.
*
* @param group
* The multicast address to join
* @param interf
* The network interface on which to join the group
*
* @return The membership key
*
* @throws IllegalArgumentException
* If the group parameter is not a {@link InetAddress#isMulticastAddress
* multicast} address, or the group parameter is an address type
* that is not supported by this channel
* @throws IllegalStateException
* If the channel already has source-specific membership of the
* group on the interface
* @throws UnsupportedOperationException
* If the channel's socket is not an Internet Protocol socket, or
* the platform does not support multicasting
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If an I/O error occurs
* @throws SecurityException
* If a security manager is set, and its
* {@link SecurityManager#checkMulticast(InetAddress) checkMulticast}
* method denies access to the multiast group
*/
MembershipKey join(InetAddress group, NetworkInterface interf)
throws IOException;
/**
* Joins a multicast group to begin receiving datagrams sent to the group
* from a given source address.
*
* <p> If this channel is currently a member of the group on the given
* interface to receive datagrams from the given source address then the
* membership key, representing that membership, is returned. Otherwise this
* channel joins the group and the resulting new membership key is returned.
* The resulting membership key is {@link MembershipKey#sourceAddress
* source-specific}.
*
* <p> Membership is <em>cumulative</em> and this method may be invoked
* again with the same group and interface to allow receiving datagrams sent
* by other source addresses to the group.
*
* @param group
* The multicast address to join
* @param interf
* The network interface on which to join the group
* @param source
* The source address
*
* @return The membership key
*
* @throws IllegalArgumentException
* If the group parameter is not a {@link
* InetAddress#isMulticastAddress multicast} address, the
* source parameter is not a unicast address, the group
* parameter is an address type that is not supported by this channel,
* or the source parameter is not the same address type as the group
* @throws IllegalStateException
* If the channel is currently a member of the group on the given
* interface to receive all datagrams
* @throws UnsupportedOperationException
* If the channel's socket is not an Internet Protocol socket, or
* source filtering is not supported, or the platform does not
* support multicasting
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If an I/O error occurs
* @throws SecurityException
* If a security manager is set, and its
* {@link SecurityManager#checkMulticast(InetAddress) checkMulticast}
* method denies access to the multiast group
*/
MembershipKey join(InetAddress group, NetworkInterface interf, InetAddress source)
throws IOException;
}

View file

@ -0,0 +1,163 @@
/*
* 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;
import java.net.SocketOption;
import java.net.SocketAddress;
import java.util.Set;
import java.io.IOException;
/**
* A channel to a network socket.
*
* <p> A channel that implements this interface is a channel to a network
* socket. The {@link #bind(SocketAddress) bind} method is used to bind the
* socket to a local {@link SocketAddress address}, the {@link #getLocalAddress()
* getLocalAddress} method returns the address that the socket is bound to, and
* the {@link #setOption(SocketOption,Object) setOption} and {@link
* #getOption(SocketOption) getOption} methods are used to set and query socket
* options. An implementation of this interface should specify the socket options
* that it supports.
*
* <p> The {@link #bind bind} and {@link #setOption setOption} methods that do
* not otherwise have a value to return are specified to return the network
* channel upon which they are invoked. This allows method invocations to be
* chained. Implementations of this interface should specialize the return type
* so that method invocations on the implementation class can be chained.
*
* @since 1.7
*/
public interface NetworkChannel
extends Channel
{
/**
* Binds the channel's socket to a local address.
*
* <p> This method is used to establish an association between the socket and
* a local address. Once an association is established then the socket remains
* bound until the channel is closed. If the {@code local} parameter has the
* value {@code null} then the socket will be bound to an address that is
* assigned automatically.
*
* @param local
* The address to bind the socket, or {@code null} to bind the socket
* to an automatically assigned socket address
*
* @return This channel
*
* @throws AlreadyBoundException
* If the socket is already bound
* @throws UnsupportedAddressTypeException
* If the type of the given address is not supported
* @throws ClosedChannelException
* If the channel is closed
* @throws IOException
* If some other I/O error occurs
* @throws SecurityException
* If a security manager is installed and it denies an unspecified
* permission. An implementation of this interface should specify
* any required permissions.
*
* @see #getLocalAddress
*/
NetworkChannel bind(SocketAddress local) throws IOException;
/**
* Returns the socket address that this channel's socket is bound to.
*
* <p> Where the channel is {@link #bind bound} to an Internet Protocol
* socket address then the return value from this method is of type {@link
* java.net.InetSocketAddress}.
*
* @return The socket address that the socket is bound to, or {@code null}
* if the channel's socket is not bound
*
* @throws ClosedChannelException
* If the channel is closed
* @throws IOException
* If an I/O error occurs
*/
SocketAddress getLocalAddress() throws IOException;
/**
* Sets the value of a socket option.
*
* @param <T>
* The type of the socket option value
* @param name
* The socket option
* @param value
* The value of the socket option. A value of {@code null} may be
* a valid value for some socket options.
*
* @return This channel
*
* @throws UnsupportedOperationException
* If the socket option is not supported by this channel
* @throws IllegalArgumentException
* If the value is not a valid value for this socket option
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If an I/O error occurs
*
* @see java.net.StandardSocketOptions
*/
<T> NetworkChannel setOption(SocketOption<T> name, T value) throws IOException;
/**
* Returns the value of a socket option.
*
* @param <T>
* The type of the socket option value
* @param name
* The socket option
*
* @return The value of the socket option. A value of {@code null} may be
* a valid value for some socket options.
*
* @throws UnsupportedOperationException
* If the socket option is not supported by this channel
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If an I/O error occurs
*
* @see java.net.StandardSocketOptions
*/
<T> T getOption(SocketOption<T> name) throws IOException;
/**
* Returns a set of the socket options supported by this channel.
*
* <p> This method will continue to return the set of options even after the
* channel has been closed.
*
* @return A set of the socket options supported by this channel
*/
Set<SocketOption<?>> supportedOptions();
}

View file

@ -0,0 +1,158 @@
/*
* 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;
import java.io.IOException;
import java.nio.channels.spi.*;
/**
* A pair of channels that implements a unidirectional pipe.
*
* <p> A pipe consists of a pair of channels: A writable {@link
* Pipe.SinkChannel sink} channel and a readable {@link Pipe.SourceChannel source}
* channel. Once some bytes are written to the sink channel they can be read
* from the source channel in exactly the order in which they were written.
*
* <p> Whether or not a thread writing bytes to a pipe will block until another
* thread reads those bytes, or some previously-written bytes, from the pipe is
* system-dependent and therefore unspecified. Many pipe implementations will
* buffer up to a certain number of bytes between the sink and source channels,
* but such buffering should not be assumed. </p>
*
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public abstract class Pipe {
/**
* A channel representing the readable end of a {@link Pipe}.
*
* @since 1.4
*/
public abstract static class SourceChannel
extends AbstractSelectableChannel
implements ReadableByteChannel, ScatteringByteChannel
{
/**
* Constructs a new instance of this class.
*
* @param provider
* The selector provider
*/
protected SourceChannel(SelectorProvider provider) {
super(provider);
}
/**
* Returns an operation set identifying this channel's supported
* operations.
*
* <p> Pipe-source channels only support reading, so this method
* returns {@link SelectionKey#OP_READ}. </p>
*
* @return The valid-operation set
*/
public final int validOps() {
return SelectionKey.OP_READ;
}
}
/**
* A channel representing the writable end of a {@link Pipe}.
*
* @since 1.4
*/
public abstract static class SinkChannel
extends AbstractSelectableChannel
implements WritableByteChannel, GatheringByteChannel
{
/**
* Initializes a new instance of this class.
*
* @param provider
* The selector provider
*/
protected SinkChannel(SelectorProvider provider) {
super(provider);
}
/**
* Returns an operation set identifying this channel's supported
* operations.
*
* <p> Pipe-sink channels only support writing, so this method returns
* {@link SelectionKey#OP_WRITE}. </p>
*
* @return The valid-operation set
*/
public final int validOps() {
return SelectionKey.OP_WRITE;
}
}
/**
* Initializes a new instance of this class.
*/
protected Pipe() { }
/**
* Returns this pipe's source channel.
*
* @return This pipe's source channel
*/
public abstract SourceChannel source();
/**
* Returns this pipe's sink channel.
*
* @return This pipe's sink channel
*/
public abstract SinkChannel sink();
/**
* Opens a pipe.
*
* <p> The new pipe is created by invoking the {@link
* java.nio.channels.spi.SelectorProvider#openPipe openPipe} method of the
* system-wide default {@link java.nio.channels.spi.SelectorProvider}
* object. </p>
*
* @return A new pipe
*
* @throws IOException
* If an I/O error occurs
*/
public static Pipe open() throws IOException {
return SelectorProvider.provider().openPipe();
}
}

View file

@ -0,0 +1,108 @@
/*
* Copyright (c) 2000, 2001, 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;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* A channel that can read bytes.
*
* <p> Only one read operation upon a readable channel may be in progress at
* any given time. If one thread initiates a read operation upon a channel
* then any other thread that attempts to initiate another read operation will
* block until the first operation is complete. Whether or not other kinds of
* I/O operations may proceed concurrently with a read operation depends upon
* the type of the channel. </p>
*
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public interface ReadableByteChannel extends Channel {
/**
* Reads a sequence of bytes from this channel into the given buffer.
*
* <p> An attempt is made to read up to <i>r</i> bytes from the channel,
* where <i>r</i> is the number of bytes remaining in the buffer, that is,
* {@code dst.remaining()}, at the moment this method is invoked.
*
* <p> Suppose that a byte sequence of length <i>n</i> is read, where
* {@code 0}&nbsp;{@code <=}&nbsp;<i>n</i>&nbsp;{@code <=}&nbsp;<i>r</i>.
* This byte sequence will be transferred into the buffer so that the first
* byte in the sequence is at index <i>p</i> and the last byte is at index
* <i>p</i>&nbsp;{@code +}&nbsp;<i>n</i>&nbsp;{@code -}&nbsp;{@code 1},
* where <i>p</i> is the buffer's position at the moment this method is
* invoked. Upon return the buffer's position will be equal to
* <i>p</i>&nbsp;{@code +}&nbsp;<i>n</i>; its limit will not have changed.
*
* <p> A read operation might not fill the buffer, and in fact it might not
* read any bytes at all. Whether or not it does so depends upon the
* nature and state of the channel. A socket channel in non-blocking mode,
* for example, cannot read any more bytes than are immediately available
* from the socket's input buffer; similarly, a file channel cannot read
* any more bytes than remain in the file. It is guaranteed, however, that
* if a channel is in blocking mode and there is at least one byte
* remaining in the buffer then this method will block until at least one
* byte is read.
*
* <p> This method may be invoked at any time. If another thread has
* already initiated a read operation upon this channel, however, then an
* invocation of this method will block until the first operation is
* complete. </p>
*
* @param dst
* The buffer into which bytes are to be transferred
*
* @return The number of bytes read, possibly zero, or {@code -1} if the
* channel has reached end-of-stream
*
* @throws NonReadableChannelException
* If this channel was not opened for reading
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws AsynchronousCloseException
* If another thread closes this channel
* while the read operation is in progress
*
* @throws ClosedByInterruptException
* If another thread interrupts the current thread
* while the read operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws IOException
* If some other I/O error occurs
*/
public int read(ByteBuffer dst) throws IOException;
}

View file

@ -0,0 +1,162 @@
/*
* Copyright (c) 2000, 2006, 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;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* A channel that can read bytes into a sequence of buffers.
*
* <p> A <i>scattering</i> read operation reads, in a single invocation, a
* sequence of bytes into one or more of a given sequence of buffers.
* Scattering reads are often useful when implementing network protocols or
* file formats that, for example, group data into segments consisting of one
* or more fixed-length headers followed by a variable-length body. Similar
* <i>gathering</i> write operations are defined in the {@link
* GatheringByteChannel} interface. </p>
*
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public interface ScatteringByteChannel
extends ReadableByteChannel
{
/**
* Reads a sequence of bytes from this channel into a subsequence of the
* given buffers.
*
* <p> An invocation of this method attempts to read up to <i>r</i> bytes
* from this channel, where <i>r</i> is the total number of bytes remaining
* the specified subsequence of the given buffer array, that is,
*
* <blockquote><pre>
* dsts[offset].remaining()
* + dsts[offset+1].remaining()
* + ... + dsts[offset+length-1].remaining()</pre></blockquote>
*
* at the moment that this method is invoked.
*
* <p> Suppose that a byte sequence of length <i>n</i> is read, where
* {@code 0}&nbsp;{@code <=}&nbsp;<i>n</i>&nbsp;{@code <=}&nbsp;<i>r</i>.
* Up to the first {@code dsts[offset].remaining()} bytes of this sequence
* are transferred into buffer {@code dsts[offset]}, up to the next
* {@code dsts[offset+1].remaining()} bytes are transferred into buffer
* {@code dsts[offset+1]}, and so forth, until the entire byte sequence
* is transferred into the given buffers. As many bytes as possible are
* transferred into each buffer, hence the final position of each updated
* buffer, except the last updated buffer, is guaranteed to be equal to
* that buffer's limit.
*
* <p> This method may be invoked at any time. If another thread has
* already initiated a read operation upon this channel, however, then an
* invocation of this method will block until the first operation is
* complete. </p>
*
* @param dsts
* The buffers into which bytes are to be transferred
*
* @param offset
* The offset within the buffer array of the first buffer into
* which bytes are to be transferred; must be non-negative and no
* larger than {@code dsts.length}
*
* @param length
* The maximum number of buffers to be accessed; must be
* non-negative and no larger than
* {@code dsts.length}&nbsp;-&nbsp;{@code offset}
*
* @return The number of bytes read, possibly zero,
* or {@code -1} if the channel has reached end-of-stream
*
* @throws IndexOutOfBoundsException
* If the preconditions on the {@code offset} and {@code length}
* parameters do not hold
*
* @throws NonReadableChannelException
* If this channel was not opened for reading
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws AsynchronousCloseException
* If another thread closes this channel
* while the read operation is in progress
*
* @throws ClosedByInterruptException
* If another thread interrupts the current thread
* while the read operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws IOException
* If some other I/O error occurs
*/
public long read(ByteBuffer[] dsts, int offset, int length)
throws IOException;
/**
* Reads a sequence of bytes from this channel into the given buffers.
*
* <p> An invocation of this method of the form {@code c.read(dsts)}
* behaves in exactly the same manner as the invocation
*
* <blockquote><pre>
* c.read(dsts, 0, dsts.length);</pre></blockquote>
*
* @param dsts
* The buffers into which bytes are to be transferred
*
* @return The number of bytes read, possibly zero,
* or {@code -1} if the channel has reached end-of-stream
*
* @throws NonReadableChannelException
* If this channel was not opened for reading
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws AsynchronousCloseException
* If another thread closes this channel
* while the read operation is in progress
*
* @throws ClosedByInterruptException
* If another thread interrupts the current thread
* while the read operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws IOException
* If some other I/O error occurs
*/
public long read(ByteBuffer[] dsts) throws IOException;
}

View file

@ -0,0 +1,168 @@
/*
* Copyright (c) 2007, 2011, 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;
import java.nio.ByteBuffer;
import java.io.IOException;
/**
* A byte channel that maintains a current <i>position</i> and allows the
* position to be changed.
*
* <p> A seekable byte channel is connected to an entity, typically a file,
* that contains a variable-length sequence of bytes that can be read and
* written. The current position can be {@link #position() <i>queried</i>} and
* {@link #position(long) <i>modified</i>}. The channel also provides access to
* the current <i>size</i> of the entity to which the channel is connected. The
* size increases when bytes are written beyond its current size; the size
* decreases when it is {@link #truncate <i>truncated</i>}.
*
* <p> The {@link #position(long) position} and {@link #truncate truncate} methods
* which do not otherwise have a value to return are specified to return the
* channel upon which they are invoked. This allows method invocations to be
* chained. Implementations of this interface should specialize the return type
* so that method invocations on the implementation class can be chained.
*
* @since 1.7
* @see java.nio.file.Files#newByteChannel
*/
public interface SeekableByteChannel
extends ByteChannel
{
/**
* Reads a sequence of bytes from this channel into the given buffer.
*
* <p> Bytes are read starting at this channel's current position, and
* then the position is updated with the number of bytes actually read.
* Otherwise this method behaves exactly as specified in the {@link
* ReadableByteChannel} interface.
*/
@Override
int read(ByteBuffer dst) throws IOException;
/**
* Writes a sequence of bytes to this channel from the given buffer.
*
* <p> Bytes are written starting at this channel's current position, unless
* the channel is connected to an entity such as a file that is opened with
* the {@link java.nio.file.StandardOpenOption#APPEND APPEND} option, in
* which case the position is first advanced to the end. The entity to which
* the channel is connected is grown, if necessary, to accommodate the
* written bytes, and then the position is updated with the number of bytes
* actually written. Otherwise this method behaves exactly as specified by
* the {@link WritableByteChannel} interface.
*/
@Override
int write(ByteBuffer src) throws IOException;
/**
* Returns this channel's position.
*
* @return This channel's position,
* a non-negative integer counting the number of bytes
* from the beginning of the entity to the current position
*
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If some other I/O error occurs
*/
long position() throws IOException;
/**
* Sets this channel's position.
*
* <p> Setting the position to a value that is greater than the current size
* is legal but does not change the size of the entity. A later attempt to
* read bytes at such a position will immediately return an end-of-file
* indication. A later attempt to write bytes at such a position will cause
* the entity to grow to accommodate the new bytes; the values of any bytes
* between the previous end-of-file and the newly-written bytes are
* unspecified.
*
* <p> Setting the channel's position is not recommended when connected to
* an entity, typically a file, that is opened with the {@link
* java.nio.file.StandardOpenOption#APPEND APPEND} option. When opened for
* append, the position is first advanced to the end before writing.
*
* @param newPosition
* The new position, a non-negative integer counting
* the number of bytes from the beginning of the entity
*
* @return This channel
*
* @throws ClosedChannelException
* If this channel is closed
* @throws IllegalArgumentException
* If the new position is negative
* @throws IOException
* If some other I/O error occurs
*/
SeekableByteChannel position(long newPosition) throws IOException;
/**
* Returns the current size of entity to which this channel is connected.
*
* @return The current size, measured in bytes
*
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If some other I/O error occurs
*/
long size() throws IOException;
/**
* Truncates the entity, to which this channel is connected, to the given
* size.
*
* <p> If the given size is less than the current size then the entity is
* truncated, discarding any bytes beyond the new end. If the given size is
* greater than or equal to the current size then the entity is not modified.
* In either case, if the current position is greater than the given size
* then it is set to that size.
*
* <p> An implementation of this interface may prohibit truncation when
* connected to an entity, typically a file, opened with the {@link
* java.nio.file.StandardOpenOption#APPEND APPEND} option.
*
* @param size
* The new size, a non-negative byte count
*
* @return This channel
*
* @throws NonWritableChannelException
* If this channel was not opened for writing
* @throws ClosedChannelException
* If this channel is closed
* @throws IllegalArgumentException
* If the new size is negative
* @throws IOException
* If some other I/O error occurs
*/
SeekableByteChannel truncate(long size) throws IOException;
}

View file

@ -0,0 +1,344 @@
/*
* 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;
import java.io.IOException;
import java.nio.channels.spi.AbstractInterruptibleChannel;
import java.nio.channels.spi.SelectorProvider;
/**
* A channel that can be multiplexed via a {@link Selector}.
*
* <p> In order to be used with a selector, an instance of this class must
* first be <i>registered</i> via the {@link #register(Selector,int,Object)
* register} method. This method returns a new {@link SelectionKey} object
* that represents the channel's registration with the selector.
*
* <p> Once registered with a selector, a channel remains registered until it
* is <i>deregistered</i>. This involves deallocating whatever resources were
* allocated to the channel by the selector.
*
* <p> A channel cannot be deregistered directly; instead, the key representing
* its registration must be <i>cancelled</i>. Cancelling a key requests that
* the channel be deregistered during the selector's next selection operation.
* A key may be cancelled explicitly by invoking its {@link
* SelectionKey#cancel() cancel} method. All of a channel's keys are cancelled
* implicitly when the channel is closed, whether by invoking its {@link
* Channel#close close} method or by interrupting a thread blocked in an I/O
* operation upon the channel.
*
* <p> If the selector itself is closed then the channel will be deregistered,
* and the key representing its registration will be invalidated, without
* further delay.
*
* <p> A channel may be registered at most once with any particular selector.
*
* <p> Whether or not a channel is registered with one or more selectors may be
* determined by invoking the {@link #isRegistered isRegistered} method.
*
* <p> Selectable channels are safe for use by multiple concurrent
* threads. </p>
*
*
* <a id="bm"></a>
* <h2>Blocking mode</h2>
*
* A selectable channel is either in <i>blocking</i> mode or in
* <i>non-blocking</i> mode. In blocking mode, every I/O operation invoked
* upon the channel will block until it completes. In non-blocking mode an I/O
* operation will never block and may transfer fewer bytes than were requested
* or possibly no bytes at all. The blocking mode of a selectable channel may
* be determined by invoking its {@link #isBlocking isBlocking} method.
*
* <p> Newly-created selectable channels are always in blocking mode.
* Non-blocking mode is most useful in conjunction with selector-based
* multiplexing. A channel must be placed into non-blocking mode before being
* registered with a selector, and may not be returned to blocking mode until
* it has been deregistered.
*
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*
* @see SelectionKey
* @see Selector
*/
public abstract class SelectableChannel
extends AbstractInterruptibleChannel
implements Channel
{
/**
* Initializes a new instance of this class.
*/
protected SelectableChannel() { }
/**
* Returns the provider that created this channel.
*
* @return The provider that created this channel
*/
public abstract SelectorProvider provider();
/**
* Returns an <a href="SelectionKey.html#opsets">operation set</a>
* identifying this channel's supported operations. The bits that are set
* in this integer value denote exactly the operations that are valid for
* this channel. This method always returns the same value for a given
* concrete channel class.
*
* @return The valid-operation set
*/
public abstract int validOps();
// Internal state:
// keySet, may be empty but is never null, typ. a tiny array
// boolean isRegistered, protected by key set
// regLock, lock object to prevent duplicate registrations
// boolean isBlocking, protected by regLock
/**
* Tells whether or not this channel is currently registered with any
* selectors. A newly-created channel is not registered.
*
* <p> Due to the inherent delay between key cancellation and channel
* deregistration, a channel may remain registered for some time after all
* of its keys have been cancelled. A channel may also remain registered
* for some time after it is closed. </p>
*
* @return {@code true} if, and only if, this channel is registered
*/
public abstract boolean isRegistered();
//
// sync(keySet) { return isRegistered; }
/**
* Retrieves the key representing the channel's registration with the given
* selector.
*
* @param sel
* The selector
*
* @return The key returned when this channel was last registered with the
* given selector, or {@code null} if this channel is not
* currently registered with that selector
*/
public abstract SelectionKey keyFor(Selector sel);
//
// sync(keySet) { return findKey(sel); }
/**
* Registers this channel with the given selector, returning a selection
* key.
*
* <p> If this channel is currently registered with the given selector then
* the selection key representing that registration is returned. The key's
* interest set will have been changed to {@code ops}, as if by invoking
* the {@link SelectionKey#interestOps(int) interestOps(int)} method. If
* the {@code att} argument is not {@code null} then the key's attachment
* will have been set to that value. A {@link CancelledKeyException} will
* be thrown if the key has already been cancelled.
*
* <p> Otherwise this channel has not yet been registered with the given
* selector, so it is registered and the resulting new key is returned.
* The key's initial interest set will be {@code ops} and its attachment
* will be {@code att}.
*
* <p> This method may be invoked at any time. If this method is invoked
* while another invocation of this method or of the {@link
* #configureBlocking(boolean) configureBlocking} method is in progress
* then it will first block until the other operation is complete. This
* method will then synchronize on the selector's key set and therefore may
* block if invoked concurrently with another registration or selection
* operation involving the same selector. </p>
*
* <p> If this channel is closed while this operation is in progress then
* the key returned by this method will have been cancelled and will
* therefore be invalid. </p>
*
* @param sel
* The selector with which this channel is to be registered
*
* @param ops
* The interest set for the resulting key
*
* @param att
* The attachment for the resulting key; may be {@code null}
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws ClosedSelectorException
* If the selector is closed
*
* @throws IllegalBlockingModeException
* If this channel is in blocking mode
*
* @throws IllegalSelectorException
* If this channel was not created by the same provider
* as the given selector
*
* @throws CancelledKeyException
* If this channel is currently registered with the given selector
* but the corresponding key has already been cancelled
*
* @throws IllegalArgumentException
* If a bit in the {@code ops} set does not correspond to an
* operation that is supported by this channel, that is, if
* {@code set & ~validOps() != 0}
*
* @return A key representing the registration of this channel with
* the given selector
*/
public abstract SelectionKey register(Selector sel, int ops, Object att)
throws ClosedChannelException;
//
// sync(regLock) {
// sync(keySet) { look for selector }
// if (channel found) { set interest ops -- may block in selector;
// return key; }
// create new key -- may block somewhere in selector;
// sync(keySet) { add key; }
// attach(attachment);
// return key;
// }
/**
* Registers this channel with the given selector, returning a selection
* key.
*
* <p> An invocation of this convenience method of the form
*
* <blockquote>{@code sc.register(sel, ops)}</blockquote>
*
* behaves in exactly the same way as the invocation
*
* <blockquote>{@code sc.}{@link
* #register(java.nio.channels.Selector,int,java.lang.Object)
* register(sel, ops, null)}</blockquote>
*
* @param sel
* The selector with which this channel is to be registered
*
* @param ops
* The interest set for the resulting key
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws ClosedSelectorException
* If the selector is closed
*
* @throws IllegalBlockingModeException
* If this channel is in blocking mode
*
* @throws IllegalSelectorException
* If this channel was not created by the same provider
* as the given selector
*
* @throws CancelledKeyException
* If this channel is currently registered with the given selector
* but the corresponding key has already been cancelled
*
* @throws IllegalArgumentException
* If a bit in {@code ops} does not correspond to an operation
* that is supported by this channel, that is, if {@code set &
* ~validOps() != 0}
*
* @return A key representing the registration of this channel with
* the given selector
*/
public final SelectionKey register(Selector sel, int ops)
throws ClosedChannelException
{
return register(sel, ops, null);
}
/**
* Adjusts this channel's blocking mode.
*
* <p> If this channel is registered with one or more selectors then an
* attempt to place it into blocking mode will cause an {@link
* IllegalBlockingModeException} to be thrown.
*
* <p> This method may be invoked at any time. The new blocking mode will
* only affect I/O operations that are initiated after this method returns.
* For some implementations this may require blocking until all pending I/O
* operations are complete.
*
* <p> If this method is invoked while another invocation of this method or
* of the {@link #register(Selector, int) register} method is in progress
* then it will first block until the other operation is complete. </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
*
* @return This selectable channel
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws IllegalBlockingModeException
* If {@code block} is {@code true} and this channel is
* registered with one or more selectors
*
* @throws IOException
* If an I/O error occurs
*/
public abstract SelectableChannel configureBlocking(boolean block)
throws IOException;
//
// sync(regLock) {
// sync(keySet) { throw IBME if block && isRegistered; }
// change mode;
// }
/**
* Tells whether or not every I/O operation on this channel will block
* until it completes. A newly-created channel is always in blocking mode.
*
* <p> If this channel is closed then the value returned by this method is
* not specified. </p>
*
* @return {@code true} if, and only if, this channel is in blocking mode
*/
public abstract boolean isBlocking();
/**
* Retrieves the object upon which the {@link #configureBlocking
* configureBlocking} and {@link #register register} methods synchronize.
* This is often useful in the implementation of adaptors that require a
* specific blocking mode to be maintained for a short period of time.
*
* @return The blocking-mode lock object
*/
public abstract Object blockingLock();
}

View file

@ -0,0 +1,399 @@
/*
* 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;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
/**
* A token representing the registration of a {@link SelectableChannel} with a
* {@link Selector}.
*
* <p> A selection key is created each time a channel is registered with a
* selector. A key remains valid until it is <i>cancelled</i> by invoking its
* {@link #cancel cancel} method, by closing its channel, or by closing its
* selector. Cancelling a key does not immediately remove it from its
* selector; it is instead added to the selector's <a
* href="Selector.html#ks"><i>cancelled-key set</i></a> for removal during the
* next selection operation. The validity of a key may be tested by invoking
* its {@link #isValid isValid} method.
*
* <a id="opsets"></a>
*
* <p> A selection key contains two <i>operation sets</i> represented as
* integer values. Each bit of an operation set denotes a category of
* selectable operations that are supported by the key's channel.
*
* <ul>
*
* <li><p> The <i>interest set</i> determines which operation categories will
* be tested for readiness the next time one of the selector's selection
* methods is invoked. The interest set is initialized with the value given
* when the key is created; it may later be changed via the {@link
* #interestOps(int)} method. </p></li>
*
* <li><p> The <i>ready set</i> identifies the operation categories for which
* the key's channel has been detected to be ready by the key's selector.
* The ready set is initialized to zero when the key is created; it may later
* be updated by the selector during a selection operation, but it cannot be
* updated directly. </p></li>
*
* </ul>
*
* <p> That a selection key's ready set indicates that its channel is ready for
* some operation category is a hint, but not a guarantee, that an operation in
* such a category may be performed by a thread without causing the thread to
* block. A ready set is most likely to be accurate immediately after the
* completion of a selection operation. It is likely to be made inaccurate by
* external events and by I/O operations that are invoked upon the
* corresponding channel.
*
* <p> This class defines all known operation-set bits, but precisely which
* bits are supported by a given channel depends upon the type of the channel.
* Each subclass of {@link SelectableChannel} defines an {@link
* SelectableChannel#validOps() validOps()} method which returns a set
* identifying just those operations that are supported by the channel. An
* attempt to set or test an operation-set bit that is not supported by a key's
* channel will result in an appropriate run-time exception.
*
* <p> It is often necessary to associate some application-specific data with a
* selection key, for example an object that represents the state of a
* higher-level protocol and handles readiness notifications in order to
* implement that protocol. Selection keys therefore support the
* <i>attachment</i> of a single arbitrary object to a key. An object can be
* attached via the {@link #attach attach} method and then later retrieved via
* the {@link #attachment() attachment} method.
*
* <p> Selection keys are safe for use by multiple concurrent threads. The
* operations of reading and writing the interest set will, in general, be
* synchronized with certain operations of the selector. Exactly how this
* synchronization is performed is implementation-dependent: In a naive
* implementation, reading or writing the interest set may block indefinitely
* if a selection operation is already in progress; in a high-performance
* implementation, reading or writing the interest set may block briefly, if at
* all. In any case, a selection operation will always use the interest-set
* value that was current at the moment that the operation began. </p>
*
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*
* @see SelectableChannel
* @see Selector
*/
public abstract class SelectionKey {
/**
* Constructs an instance of this class.
*/
protected SelectionKey() { }
// -- Channel and selector operations --
/**
* Returns the channel for which this key was created. This method will
* continue to return the channel even after the key is cancelled.
*
* @return This key's channel
*/
public abstract SelectableChannel channel();
/**
* Returns the selector for which this key was created. This method will
* continue to return the selector even after the key is cancelled.
*
* @return This key's selector
*/
public abstract Selector selector();
/**
* Tells whether or not this key is valid.
*
* <p> A key is valid upon creation and remains so until it is cancelled,
* its channel is closed, or its selector is closed. </p>
*
* @return {@code true} if, and only if, this key is valid
*/
public abstract boolean isValid();
/**
* Requests that the registration of this key's channel with its selector
* be cancelled. Upon return the key will be invalid and will have been
* added to its selector's cancelled-key set. The key will be removed from
* all of the selector's key sets during the next selection operation.
*
* <p> If this key has already been cancelled then invoking this method has
* no effect. Once cancelled, a key remains forever invalid. </p>
*
* <p> This method may be invoked at any time. It synchronizes on the
* selector's cancelled-key set, and therefore may block briefly if invoked
* concurrently with a cancellation or selection operation involving the
* same selector. </p>
*/
public abstract void cancel();
// -- Operation-set accessors --
/**
* Retrieves this key's interest set.
*
* <p> It is guaranteed that the returned set will only contain operation
* bits that are valid for this key's channel.
*
* <p> This method may be invoked at any time. Whether or not it blocks,
* and for how long, is implementation-dependent. </p>
*
* @return This key's interest set
*
* @throws CancelledKeyException
* If this key has been cancelled
*/
public abstract int interestOps();
/**
* Sets this key's interest set to the given value.
*
* <p> This method may be invoked at any time. Whether or not it blocks,
* and for how long, is implementation-dependent. </p>
*
* @param ops The new interest set
*
* @return This selection key
*
* @throws IllegalArgumentException
* If a bit in the set does not correspond to an operation that
* is supported by this key's channel, that is, if
* {@code (ops & ~channel().validOps()) != 0}
*
* @throws CancelledKeyException
* If this key has been cancelled
*/
public abstract SelectionKey interestOps(int ops);
/**
* Retrieves this key's ready-operation set.
*
* <p> It is guaranteed that the returned set will only contain operation
* bits that are valid for this key's channel. </p>
*
* @return This key's ready-operation set
*
* @throws CancelledKeyException
* If this key has been cancelled
*/
public abstract int readyOps();
// -- Operation bits and bit-testing convenience methods --
/**
* Operation-set bit for read operations.
*
* <p> Suppose that a selection key's interest set contains
* {@code OP_READ} at the start of a <a
* href="Selector.html#selop">selection operation</a>. If the selector
* detects that the corresponding channel is ready for reading, has reached
* end-of-stream, has been remotely shut down for further reading, or has
* an error pending, then it will add {@code OP_READ} to the key's
* ready-operation set and add the key to its selected-key&nbsp;set. </p>
*/
public static final int OP_READ = 1 << 0;
/**
* Operation-set bit for write operations.
*
* <p> Suppose that a selection key's interest set contains
* {@code OP_WRITE} at the start of a <a
* href="Selector.html#selop">selection operation</a>. If the selector
* detects that the corresponding channel is ready for writing, has been
* remotely shut down for further writing, or has an error pending, then it
* will add {@code OP_WRITE} to the key's ready set and add the key to its
* selected-key&nbsp;set. </p>
*/
public static final int OP_WRITE = 1 << 2;
/**
* Operation-set bit for socket-connect operations.
*
* <p> Suppose that a selection key's interest set contains
* {@code OP_CONNECT} at the start of a <a
* href="Selector.html#selop">selection operation</a>. If the selector
* detects that the corresponding socket channel is ready to complete its
* connection sequence, or has an error pending, then it will add
* {@code OP_CONNECT} to the key's ready set and add the key to its
* selected-key&nbsp;set. </p>
*/
public static final int OP_CONNECT = 1 << 3;
/**
* Operation-set bit for socket-accept operations.
*
* <p> Suppose that a selection key's interest set contains
* {@code OP_ACCEPT} at the start of a <a
* href="Selector.html#selop">selection operation</a>. If the selector
* detects that the corresponding server-socket channel is ready to accept
* another connection, or has an error pending, then it will add
* {@code OP_ACCEPT} to the key's ready set and add the key to its
* selected-key&nbsp;set. </p>
*/
public static final int OP_ACCEPT = 1 << 4;
/**
* Tests whether this key's channel is ready for reading.
*
* <p> An invocation of this method of the form {@code k.isReadable()}
* behaves in exactly the same way as the expression
*
* <blockquote><pre>{@code
* k.readyOps() & OP_READ != 0
* }</pre></blockquote>
*
* <p> If this key's channel does not support read operations then this
* method always returns {@code false}. </p>
*
* @return {@code true} if, and only if,
{@code readyOps() & OP_READ} is nonzero
*
* @throws CancelledKeyException
* If this key has been cancelled
*/
public final boolean isReadable() {
return (readyOps() & OP_READ) != 0;
}
/**
* Tests whether this key's channel is ready for writing.
*
* <p> An invocation of this method of the form {@code k.isWritable()}
* behaves in exactly the same way as the expression
*
* <blockquote><pre>{@code
* k.readyOps() & OP_WRITE != 0
* }</pre></blockquote>
*
* <p> If this key's channel does not support write operations then this
* method always returns {@code false}. </p>
*
* @return {@code true} if, and only if,
* {@code readyOps() & OP_WRITE} is nonzero
*
* @throws CancelledKeyException
* If this key has been cancelled
*/
public final boolean isWritable() {
return (readyOps() & OP_WRITE) != 0;
}
/**
* Tests whether this key's channel has either finished, or failed to
* finish, its socket-connection operation.
*
* <p> An invocation of this method of the form {@code k.isConnectable()}
* behaves in exactly the same way as the expression
*
* <blockquote><pre>{@code
* k.readyOps() & OP_CONNECT != 0
* }</pre></blockquote>
*
* <p> If this key's channel does not support socket-connect operations
* then this method always returns {@code false}. </p>
*
* @return {@code true} if, and only if,
* {@code readyOps() & OP_CONNECT} is nonzero
*
* @throws CancelledKeyException
* If this key has been cancelled
*/
public final boolean isConnectable() {
return (readyOps() & OP_CONNECT) != 0;
}
/**
* Tests whether this key's channel is ready to accept a new socket
* connection.
*
* <p> An invocation of this method of the form {@code k.isAcceptable()}
* behaves in exactly the same way as the expression
*
* <blockquote><pre>{@code
* k.readyOps() & OP_ACCEPT != 0
* }</pre></blockquote>
*
* <p> If this key's channel does not support socket-accept operations then
* this method always returns {@code false}. </p>
*
* @return {@code true} if, and only if,
* {@code readyOps() & OP_ACCEPT} is nonzero
*
* @throws CancelledKeyException
* If this key has been cancelled
*/
public final boolean isAcceptable() {
return (readyOps() & OP_ACCEPT) != 0;
}
// -- Attachments --
private volatile Object attachment;
private static final AtomicReferenceFieldUpdater<SelectionKey,Object>
attachmentUpdater = AtomicReferenceFieldUpdater.newUpdater(
SelectionKey.class, Object.class, "attachment"
);
/**
* Attaches the given object to this key.
*
* <p> An attached object may later be retrieved via the {@link #attachment()
* attachment} method. Only one object may be attached at a time; invoking
* this method causes any previous attachment to be discarded. The current
* attachment may be discarded by attaching {@code null}. </p>
*
* @param ob
* The object to be attached; may be {@code null}
*
* @return The previously-attached object, if any,
* otherwise {@code null}
*/
public final Object attach(Object ob) {
return attachmentUpdater.getAndSet(this, ob);
}
/**
* Retrieves the current attachment.
*
* @return The object currently attached to this key,
* or {@code null} if there is no attachment
*/
public final Object attachment() {
return attachment;
}
}

View file

@ -0,0 +1,396 @@
/*
* 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;
import java.io.Closeable;
import java.io.IOException;
import java.nio.channels.spi.SelectorProvider;
import java.util.Set;
/**
* A multiplexor of {@link SelectableChannel} objects.
*
* <p> A selector may be created by invoking the {@link #open open} method of
* this class, which will use the system's default {@link
* java.nio.channels.spi.SelectorProvider selector provider} to
* create a new selector. A selector may also be created by invoking the
* {@link java.nio.channels.spi.SelectorProvider#openSelector openSelector}
* method of a custom selector provider. A selector remains open until it is
* closed via its {@link #close close} method.
*
* <a id="ks"></a>
*
* <p> A selectable channel's registration with a selector is represented by a
* {@link SelectionKey} object. A selector maintains three sets of selection
* keys:
*
* <ul>
*
* <li><p> The <i>key set</i> contains the keys representing the current
* channel registrations of this selector. This set is returned by the
* {@link #keys() keys} method. </p></li>
*
* <li><p> The <i>selected-key set</i> is the set of keys such that each
* key's channel was detected to be ready for at least one of the operations
* identified in the key's interest set during a prior selection operation.
* This set is returned by the {@link #selectedKeys() selectedKeys} method.
* The selected-key set is always a subset of the key set. </p></li>
*
* <li><p> The <i>cancelled-key</i> set is the set of keys that have been
* cancelled but whose channels have not yet been deregistered. This set is
* not directly accessible. The cancelled-key set is always a subset of the
* key set. </p></li>
*
* </ul>
*
* <p> All three sets are empty in a newly-created selector.
*
* <p> A key is added to a selector's key set as a side effect of registering a
* channel via the channel's {@link SelectableChannel#register(Selector,int)
* register} method. Cancelled keys are removed from the key set during
* selection operations. The key set itself is not directly modifiable.
*
* <p> A key is added to its selector's cancelled-key set when it is cancelled,
* whether by closing its channel or by invoking its {@link SelectionKey#cancel
* cancel} method. Cancelling a key will cause its channel to be deregistered
* during the next selection operation, at which time the key will removed from
* all of the selector's key sets.
*
* <a id="sks"></a><p> Keys are added to the selected-key set by selection
* operations. A key may be removed directly from the selected-key set by
* invoking the set's {@link java.util.Set#remove(java.lang.Object) remove}
* method or by invoking the {@link java.util.Iterator#remove() remove} method
* of an {@link java.util.Iterator iterator} obtained from the
* set. Keys are never removed from the selected-key set in any other way;
* they are not, in particular, removed as a side effect of selection
* operations. Keys may not be added directly to the selected-key set. </p>
*
*
* <a id="selop"></a>
* <h2>Selection</h2>
*
* <p> During each selection operation, keys may be added to and removed from a
* selector's selected-key set and may be removed from its key and
* cancelled-key sets. Selection is performed by the {@link #select()}, {@link
* #select(long)}, and {@link #selectNow()} methods, and involves three steps:
* </p>
*
* <ol>
*
* <li><p> Each key in the cancelled-key set is removed from each key set of
* which it is a member, and its channel is deregistered. This step leaves
* the cancelled-key set empty. </p></li>
*
* <li><p> The underlying operating system is queried for an update as to the
* readiness of each remaining channel to perform any of the operations
* identified by its key's interest set as of the moment that the selection
* operation began. For a channel that is ready for at least one such
* operation, one of the following two actions is performed: </p>
*
* <ol>
*
* <li><p> If the channel's key is not already in the selected-key set then
* it is added to that set and its ready-operation set is modified to
* identify exactly those operations for which the channel is now reported
* to be ready. Any readiness information previously recorded in the ready
* set is discarded. </p></li>
*
* <li><p> Otherwise the channel's key is already in the selected-key set,
* so its ready-operation set is modified to identify any new operations
* for which the channel is reported to be ready. Any readiness
* information previously recorded in the ready set is preserved; in other
* words, the ready set returned by the underlying system is
* bitwise-disjoined into the key's current ready set. </p></li>
*
* </ol>
*
* If all of the keys in the key set at the start of this step have empty
* interest sets then neither the selected-key set nor any of the keys'
* ready-operation sets will be updated.
*
* <li><p> If any keys were added to the cancelled-key set while step (2) was
* in progress then they are processed as in step (1). </p></li>
*
* </ol>
*
* <p> Whether or not a selection operation blocks to wait for one or more
* channels to become ready, and if so for how long, is the only essential
* difference between the three selection methods. </p>
*
*
* <h2>Concurrency</h2>
*
* <p> Selectors are themselves safe for use by multiple concurrent threads;
* their key sets, however, are not.
*
* <p> The selection operations synchronize on the selector itself, on the key
* set, and on the selected-key set, in that order. They also synchronize on
* the cancelled-key set during steps (1) and (3) above.
*
* <p> Changes made to the interest sets of a selector's keys while a
* selection operation is in progress have no effect upon that operation; they
* will be seen by the next selection operation.
*
* <p> Keys may be cancelled and channels may be closed at any time. Hence the
* presence of a key in one or more of a selector's key sets does not imply
* that the key is valid or that its channel is open. Application code should
* be careful to synchronize and check these conditions as necessary if there
* is any possibility that another thread will cancel a key or close a channel.
*
* <p> A thread blocked in one of the {@link #select()} or {@link
* #select(long)} methods may be interrupted by some other thread in one of
* three ways:
*
* <ul>
*
* <li><p> By invoking the selector's {@link #wakeup wakeup} method,
* </p></li>
*
* <li><p> By invoking the selector's {@link #close close} method, or
* </p></li>
*
* <li><p> By invoking the blocked thread's {@link
* java.lang.Thread#interrupt() interrupt} method, in which case its
* interrupt status will be set and the selector's {@link #wakeup wakeup}
* method will be invoked. </p></li>
*
* </ul>
*
* <p> The {@link #close close} method synchronizes on the selector and all
* three key sets in the same order as in a selection operation.
*
* <a id="ksc"></a>
*
* <p> A selector's key and selected-key sets are not, in general, safe for use
* by multiple concurrent threads. If such a thread might modify one of these
* sets directly then access should be controlled by synchronizing on the set
* itself. The iterators returned by these sets' {@link
* java.util.Set#iterator() iterator} methods are <i>fail-fast:</i> If the set
* is modified after the iterator is created, in any way except by invoking the
* iterator's own {@link java.util.Iterator#remove() remove} method, then a
* {@link java.util.ConcurrentModificationException} will be thrown. </p>
*
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*
* @see SelectableChannel
* @see SelectionKey
*/
public abstract class Selector implements Closeable {
/**
* Initializes a new instance of this class.
*/
protected Selector() { }
/**
* Opens a selector.
*
* <p> The new selector is created by invoking the {@link
* java.nio.channels.spi.SelectorProvider#openSelector openSelector} method
* of the system-wide default {@link
* java.nio.channels.spi.SelectorProvider} object. </p>
*
* @return A new selector
*
* @throws IOException
* If an I/O error occurs
*/
public static Selector open() throws IOException {
return SelectorProvider.provider().openSelector();
}
/**
* Tells whether or not this selector is open.
*
* @return {@code true} if, and only if, this selector is open
*/
public abstract boolean isOpen();
/**
* Returns the provider that created this channel.
*
* @return The provider that created this channel
*/
public abstract SelectorProvider provider();
/**
* Returns this selector's key set.
*
* <p> The key set is not directly modifiable. A key is removed only after
* it has been cancelled and its channel has been deregistered. Any
* attempt to modify the key set will cause an {@link
* UnsupportedOperationException} to be thrown.
*
* <p> The key set is <a href="#ksc">not thread-safe</a>. </p>
*
* @return This selector's key set
*
* @throws ClosedSelectorException
* If this selector is closed
*/
public abstract Set<SelectionKey> keys();
/**
* Returns this selector's selected-key set.
*
* <p> Keys may be removed from, but not directly added to, the
* selected-key set. Any attempt to add an object to the key set will
* cause an {@link UnsupportedOperationException} to be thrown.
*
* <p> The selected-key set is <a href="#ksc">not thread-safe</a>. </p>
*
* @return This selector's selected-key set
*
* @throws ClosedSelectorException
* If this selector is closed
*/
public abstract Set<SelectionKey> selectedKeys();
/**
* Selects a set of keys whose corresponding channels are ready for I/O
* operations.
*
* <p> This method performs a non-blocking <a href="#selop">selection
* operation</a>. If no channels have become selectable since the previous
* selection operation then this method immediately returns zero.
*
* <p> Invoking this method clears the effect of any previous invocations
* of the {@link #wakeup wakeup} method. </p>
*
* @return The number of keys, possibly zero, whose ready-operation sets
* were updated by the selection operation
*
* @throws IOException
* If an I/O error occurs
*
* @throws ClosedSelectorException
* If this selector is closed
*/
public abstract int selectNow() throws IOException;
/**
* Selects a set of keys whose corresponding channels are ready for I/O
* operations.
*
* <p> This method performs a blocking <a href="#selop">selection
* operation</a>. It returns only after at least one channel is selected,
* this selector's {@link #wakeup wakeup} method is invoked, the current
* thread is interrupted, or the given timeout period expires, whichever
* comes first.
*
* <p> This method does not offer real-time guarantees: It schedules the
* timeout as if by invoking the {@link Object#wait(long)} method. </p>
*
* @param timeout If positive, block for up to {@code timeout}
* milliseconds, more or less, while waiting for a
* channel to become ready; if zero, block indefinitely;
* must not be negative
*
* @return The number of keys, possibly zero,
* whose ready-operation sets were updated
*
* @throws IOException
* If an I/O error occurs
*
* @throws ClosedSelectorException
* If this selector is closed
*
* @throws IllegalArgumentException
* If the value of the timeout argument is negative
*/
public abstract int select(long timeout)
throws IOException;
/**
* Selects a set of keys whose corresponding channels are ready for I/O
* operations.
*
* <p> This method performs a blocking <a href="#selop">selection
* operation</a>. It returns only after at least one channel is selected,
* this selector's {@link #wakeup wakeup} method is invoked, or the current
* thread is interrupted, whichever comes first. </p>
*
* @return The number of keys, possibly zero,
* whose ready-operation sets were updated
*
* @throws IOException
* If an I/O error occurs
*
* @throws ClosedSelectorException
* If this selector is closed
*/
public abstract int select() throws IOException;
/**
* Causes the first selection operation that has not yet returned to return
* immediately.
*
* <p> If another thread is currently blocked in an invocation of the
* {@link #select()} or {@link #select(long)} methods then that invocation
* will return immediately. If no selection operation is currently in
* progress then the next invocation of one of these methods will return
* immediately unless the {@link #selectNow()} method is invoked in the
* meantime. In any case the value returned by that invocation may be
* non-zero. Subsequent invocations of the {@link #select()} or {@link
* #select(long)} methods will block as usual unless this method is invoked
* again in the meantime.
*
* <p> Invoking this method more than once between two successive selection
* operations has the same effect as invoking it just once. </p>
*
* @return This selector
*/
public abstract Selector wakeup();
/**
* Closes this selector.
*
* <p> If a thread is currently blocked in one of this selector's selection
* methods then it is interrupted as if by invoking the selector's {@link
* #wakeup wakeup} method.
*
* <p> Any uncancelled keys still associated with this selector are
* invalidated, their channels are deregistered, and any other resources
* associated with this selector are released.
*
* <p> If this selector is already closed then invoking this method has no
* effect.
*
* <p> After a selector is closed, any further attempt to use it, except by
* invoking this method or the {@link #wakeup wakeup} method, will cause a
* {@link ClosedSelectorException} to be thrown. </p>
*
* @throws IOException
* If an I/O error occurs
*/
public abstract void close() throws IOException;
}

View file

@ -0,0 +1,297 @@
/*
* 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;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.SocketOption;
import java.net.SocketAddress;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.SelectorProvider;
/**
* A selectable channel for stream-oriented listening sockets.
*
* <p> A server-socket channel is created by invoking the {@link #open() open}
* method of this class. It is not possible to create a channel for an arbitrary,
* pre-existing {@link ServerSocket}. A newly-created server-socket channel is
* open but not yet bound. An attempt to invoke the {@link #accept() accept}
* method of an unbound server-socket channel will cause a {@link NotYetBoundException}
* to be thrown. A server-socket channel can be bound by invoking one of the
* {@link #bind(java.net.SocketAddress,int) bind} methods defined by this class.
*
* <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
* setOption} method. Server-socket channels support the following options:
* <blockquote>
* <table class="striped">
* <caption style="display:none">Socket options</caption>
* <thead>
* <tr>
* <th scope="col">Option Name</th>
* <th scope="col">Description</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </th>
* <td> The size of the socket receive buffer </td>
* </tr>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </th>
* <td> Re-use address </td>
* </tr>
* </tbody>
* </table>
* </blockquote>
* Additional (implementation specific) options may also be supported.
*
* <p> Server-socket channels are safe for use by multiple concurrent threads.
* </p>
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public abstract class ServerSocketChannel
extends AbstractSelectableChannel
implements NetworkChannel
{
/**
* Initializes a new instance of this class.
*
* @param provider
* The provider that created this channel
*/
protected ServerSocketChannel(SelectorProvider provider) {
super(provider);
}
/**
* Opens a server-socket channel.
*
* <p> The new channel is created by invoking the {@link
* java.nio.channels.spi.SelectorProvider#openServerSocketChannel
* openServerSocketChannel} method of the system-wide default {@link
* java.nio.channels.spi.SelectorProvider} object.
*
* <p> The new channel's socket is initially unbound; it must be bound to a
* specific address via one of its socket's {@link
* java.net.ServerSocket#bind(SocketAddress) bind} methods before
* connections can be accepted. </p>
*
* @return A new socket channel
*
* @throws IOException
* If an I/O error occurs
*/
public static ServerSocketChannel open() throws IOException {
return SelectorProvider.provider().openServerSocketChannel();
}
/**
* Returns an operation set identifying this channel's supported
* operations.
*
* <p> Server-socket channels only support the accepting of new
* connections, so this method returns {@link SelectionKey#OP_ACCEPT}.
* </p>
*
* @return The valid-operation set
*/
public final int validOps() {
return SelectionKey.OP_ACCEPT;
}
// -- ServerSocket-specific operations --
/**
* Binds the channel's socket to a local address and configures the socket
* to listen for connections.
*
* <p> An invocation of this method is equivalent to the following:
* <blockquote><pre>
* bind(local, 0);
* </pre></blockquote>
*
* @param local
* The local address to bind the socket, or {@code null} to bind
* to an automatically assigned socket address
*
* @return This channel
*
* @throws AlreadyBoundException {@inheritDoc}
* @throws UnsupportedAddressTypeException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
* @throws SecurityException
* If a security manager has been installed and its {@link
* SecurityManager#checkListen checkListen} method denies the
* operation
*
* @since 1.7
*/
public final ServerSocketChannel bind(SocketAddress local)
throws IOException
{
return bind(local, 0);
}
/**
* Binds the channel's socket to a local address and configures the socket to
* listen for connections.
*
* <p> This method is used to establish an association between the socket and
* a local address. Once an association is established then the socket remains
* bound until the channel is closed.
*
* <p> The {@code backlog} parameter is the maximum number of pending
* connections on the socket. Its exact semantics are implementation specific.
* In particular, an implementation may impose a maximum length or may choose
* to ignore the parameter altogther. If the {@code backlog} parameter has
* the value {@code 0}, or a negative value, then an implementation specific
* default is used.
*
* @param local
* The address to bind the socket, or {@code null} to bind to an
* automatically assigned socket address
* @param backlog
* The maximum number of pending connections
*
* @return This channel
*
* @throws AlreadyBoundException
* If the socket is already bound
* @throws UnsupportedAddressTypeException
* If the type of the given address is not supported
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If some other I/O error occurs
* @throws SecurityException
* If a security manager has been installed and its {@link
* SecurityManager#checkListen checkListen} method denies the
* operation
*
* @since 1.7
*/
public abstract ServerSocketChannel bind(SocketAddress local, int backlog)
throws IOException;
/**
* @throws UnsupportedOperationException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
*
* @since 1.7
*/
public abstract <T> ServerSocketChannel setOption(SocketOption<T> name, T value)
throws IOException;
/**
* Retrieves a server socket associated with this channel.
*
* <p> The returned object will not declare any public methods that are not
* declared in the {@link java.net.ServerSocket} class. </p>
*
* @return A server socket associated with this channel
*/
public abstract ServerSocket socket();
/**
* Accepts a connection made to this channel's socket.
*
* <p> If this channel is in non-blocking mode then this method will
* immediately return {@code null} if there are no pending connections.
* Otherwise it will block indefinitely until a new connection is available
* or an I/O error occurs.
*
* <p> The socket channel returned by this method, if any, will be in
* blocking mode regardless of the blocking mode of this channel.
*
* <p> This method performs exactly the same security checks as the {@link
* java.net.ServerSocket#accept accept} method of the {@link
* java.net.ServerSocket} class. That is, if a security manager has been
* installed then for each new connection this method verifies that the
* address and port number of the connection's remote endpoint are
* permitted by the security manager's {@link
* java.lang.SecurityManager#checkAccept checkAccept} method. </p>
*
* @return The socket channel for the new connection,
* or {@code null} if this channel is in non-blocking mode
* and no connection is available to be accepted
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws AsynchronousCloseException
* If another thread closes this channel
* while the accept operation is in progress
*
* @throws ClosedByInterruptException
* If another thread interrupts the current thread
* while the accept operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws NotYetBoundException
* If this channel's socket has not yet been bound
*
* @throws SecurityException
* If a security manager has been installed
* and it does not permit access to the remote endpoint
* of the new connection
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract SocketChannel accept() throws IOException;
/**
* {@inheritDoc}
* <p>
* If there is a security manager set, its {@code checkConnect} method is
* called with the local address and {@code -1} as its arguments to see
* if the operation is allowed. If the operation is not allowed,
* a {@code SocketAddress} representing the
* {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
* local port of the channel's socket is returned.
*
* @return The {@code SocketAddress} that the socket is bound to, or the
* {@code SocketAddress} representing the loopback address if
* denied by the security manager, or {@code null} if the
* channel's socket is not bound
*
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
*/
@Override
public abstract SocketAddress getLocalAddress() throws IOException;
}

View file

@ -0,0 +1,531 @@
/*
* 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;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketOption;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.SelectorProvider;
/**
* A selectable channel for stream-oriented connecting sockets.
*
* <p> A socket channel is created by invoking one of the {@link #open open}
* methods of this class. It is not possible to create a channel for an arbitrary,
* pre-existing socket. A newly-created socket channel is open but not yet
* connected. An attempt to invoke an I/O operation upon an unconnected
* channel will cause a {@link NotYetConnectedException} to be thrown. A
* socket channel can be connected by invoking its {@link #connect connect}
* method; once connected, a socket channel remains connected until it is
* closed. Whether or not a socket channel is connected may be determined by
* invoking its {@link #isConnected isConnected} method.
*
* <p> Socket channels support <i>non-blocking connection:</i>&nbsp;A socket
* channel may be created and the process of establishing the link to the
* remote socket may be initiated via the {@link #connect connect} method for
* later completion by the {@link #finishConnect finishConnect} method.
* Whether or not a connection operation is in progress may be determined by
* invoking the {@link #isConnectionPending isConnectionPending} method.
*
* <p> Socket channels support <i>asynchronous shutdown,</i> which is similar
* to the asynchronous close operation specified in the {@link Channel} class.
* If the input side of a socket is shut down by one thread while another
* thread is blocked in a read operation on the socket's channel, then the read
* operation in the blocked thread will complete without reading any bytes and
* will return {@code -1}. If the output side of a socket is shut down by one
* thread while another thread is blocked in a write operation on the socket's
* channel, then the blocked thread will receive an {@link
* AsynchronousCloseException}.
*
* <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
* setOption} method. Socket channels support the following options:
* <blockquote>
* <table class="striped">
* <caption style="display:none">Socket options</caption>
* <thead>
* <tr>
* <th scope="col">Option Name</th>
* <th scope="col">Description</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#SO_SNDBUF SO_SNDBUF} </th>
* <td> The size of the socket send buffer </td>
* </tr>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </th>
* <td> The size of the socket receive buffer </td>
* </tr>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#SO_KEEPALIVE SO_KEEPALIVE} </th>
* <td> Keep connection alive </td>
* </tr>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </th>
* <td> Re-use address </td>
* </tr>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#SO_LINGER SO_LINGER} </th>
* <td> Linger on close if data is present (when configured in blocking mode
* only) </td>
* </tr>
* <tr>
* <th scope="row"> {@link java.net.StandardSocketOptions#TCP_NODELAY TCP_NODELAY} </th>
* <td> Disable the Nagle algorithm </td>
* </tr>
* </tbody>
* </table>
* </blockquote>
* Additional (implementation specific) options may also be supported.
*
* <p> Socket channels are safe for use by multiple concurrent threads. They
* support concurrent reading and writing, though at most one thread may be
* reading and at most one thread may be writing at any given time. The {@link
* #connect connect} and {@link #finishConnect finishConnect} methods are
* mutually synchronized against each other, and an attempt to initiate a read
* or write operation while an invocation of one of these methods is in
* progress will block until that invocation is complete. </p>
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public abstract class SocketChannel
extends AbstractSelectableChannel
implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, NetworkChannel
{
/**
* Initializes a new instance of this class.
*
* @param provider
* The provider that created this channel
*/
protected SocketChannel(SelectorProvider provider) {
super(provider);
}
/**
* Opens a socket channel.
*
* <p> The new channel is created by invoking the {@link
* java.nio.channels.spi.SelectorProvider#openSocketChannel
* openSocketChannel} method of the system-wide default {@link
* java.nio.channels.spi.SelectorProvider} object. </p>
*
* @return A new socket channel
*
* @throws IOException
* If an I/O error occurs
*/
public static SocketChannel open() throws IOException {
return SelectorProvider.provider().openSocketChannel();
}
/**
* Opens a socket channel and connects it to a remote address.
*
* <p> This convenience method works as if by invoking the {@link #open()}
* method, invoking the {@link #connect(SocketAddress) connect} method upon
* the resulting socket channel, passing it {@code remote}, and then
* returning that channel. </p>
*
* @param remote
* The remote address to which the new channel is to be connected
*
* @return A new, and connected, socket channel
*
* @throws AsynchronousCloseException
* If another thread closes this channel
* while the connect operation is in progress
*
* @throws ClosedByInterruptException
* If another thread interrupts the current thread
* while the connect operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws UnresolvedAddressException
* If the given remote address is not fully resolved
*
* @throws UnsupportedAddressTypeException
* If the type of the given remote address is not supported
*
* @throws SecurityException
* If a security manager has been installed
* and it does not permit access to the given remote endpoint
*
* @throws IOException
* If some other I/O error occurs
*/
public static SocketChannel open(SocketAddress remote)
throws IOException
{
SocketChannel sc = open();
try {
sc.connect(remote);
} catch (Throwable x) {
try {
sc.close();
} catch (Throwable suppressed) {
x.addSuppressed(suppressed);
}
throw x;
}
assert sc.isConnected();
return sc;
}
/**
* Returns an operation set identifying this channel's supported
* operations.
*
* <p> Socket channels support connecting, reading, and writing, so this
* method returns {@code (}{@link SelectionKey#OP_CONNECT}
* {@code |}&nbsp;{@link SelectionKey#OP_READ} {@code |}&nbsp;{@link
* SelectionKey#OP_WRITE}{@code )}.
*
* @return The valid-operation set
*/
public final int validOps() {
return (SelectionKey.OP_READ
| SelectionKey.OP_WRITE
| SelectionKey.OP_CONNECT);
}
// -- Socket-specific operations --
/**
* @throws ConnectionPendingException
* If a non-blocking connect operation is already in progress on
* this channel
* @throws AlreadyBoundException {@inheritDoc}
* @throws UnsupportedAddressTypeException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
* @throws SecurityException
* If a security manager has been installed and its
* {@link SecurityManager#checkListen checkListen} method denies
* the operation
*
* @since 1.7
*/
@Override
public abstract SocketChannel bind(SocketAddress local)
throws IOException;
/**
* @throws UnsupportedOperationException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
*
* @since 1.7
*/
@Override
public abstract <T> SocketChannel setOption(SocketOption<T> name, T value)
throws IOException;
/**
* Shutdown the connection for reading without closing the channel.
*
* <p> Once shutdown for reading then further reads on the channel will
* return {@code -1}, the end-of-stream indication. If the input side of the
* connection is already shutdown then invoking this method has no effect.
*
* @return The channel
*
* @throws NotYetConnectedException
* If this channel is not yet connected
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If some other I/O error occurs
*
* @since 1.7
*/
public abstract SocketChannel shutdownInput() throws IOException;
/**
* Shutdown the connection for writing without closing the channel.
*
* <p> Once shutdown for writing then further attempts to write to the
* channel will throw {@link ClosedChannelException}. If the output side of
* the connection is already shutdown then invoking this method has no
* effect.
*
* @return The channel
*
* @throws NotYetConnectedException
* If this channel is not yet connected
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If some other I/O error occurs
*
* @since 1.7
*/
public abstract SocketChannel shutdownOutput() throws IOException;
/**
* Retrieves a socket associated with this channel.
*
* <p> The returned object will not declare any public methods that are not
* declared in the {@link java.net.Socket} class. </p>
*
* @return A socket associated with this channel
*/
public abstract Socket socket();
/**
* Tells whether or not this channel's network socket is connected.
*
* @return {@code true} if, and only if, this channel's network socket
* is {@link #isOpen open} and connected
*/
public abstract boolean isConnected();
/**
* Tells whether or not a connection operation is in progress on this
* channel.
*
* @return {@code true} if, and only if, a connection operation has been
* initiated on this channel but not yet completed by invoking the
* {@link #finishConnect finishConnect} method
*/
public abstract boolean isConnectionPending();
/**
* Connects this channel's socket.
*
* <p> If this channel is in non-blocking mode then an invocation of this
* method initiates a non-blocking connection operation. If the connection
* is established immediately, as can happen with a local connection, then
* this method returns {@code true}. Otherwise this method returns
* {@code false} and the connection operation must later be completed by
* invoking the {@link #finishConnect finishConnect} method.
*
* <p> If this channel is in blocking mode then an invocation of this
* method will block until the connection is established or an I/O error
* occurs.
*
* <p> This method performs exactly the same security checks as the {@link
* java.net.Socket} class. That is, if a security manager has been
* installed then this method verifies that its {@link
* java.lang.SecurityManager#checkConnect checkConnect} method permits
* connecting to the address and port number of the given remote endpoint.
*
* <p> This method may be invoked at any time. If a read or write
* operation upon this channel is invoked while an invocation of this
* method is in progress then that operation will first block until this
* invocation is complete. If a connection attempt is initiated but fails,
* that is, if an invocation of this method throws a checked exception,
* then the channel will be closed. </p>
*
* @param remote
* The remote address to which this channel is to be connected
*
* @return {@code true} if a connection was established,
* {@code false} if this channel is in non-blocking mode
* and the connection operation is in progress
*
* @throws AlreadyConnectedException
* If this channel is already connected
*
* @throws ConnectionPendingException
* If a non-blocking connection operation is already in progress
* on this channel
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws AsynchronousCloseException
* If another thread closes this channel
* while the connect operation is in progress
*
* @throws ClosedByInterruptException
* If another thread interrupts the current thread
* while the connect operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws UnresolvedAddressException
* If the given remote address is not fully resolved
*
* @throws UnsupportedAddressTypeException
* If the type of the given remote address is not supported
*
* @throws SecurityException
* If a security manager has been installed
* and it does not permit access to the given remote endpoint
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract boolean connect(SocketAddress remote) throws IOException;
/**
* Finishes the process of connecting a socket channel.
*
* <p> A non-blocking connection operation is initiated by placing a socket
* channel in non-blocking mode and then invoking its {@link #connect
* connect} method. Once the connection is established, or the attempt has
* failed, the socket channel will become connectable and this method may
* be invoked to complete the connection sequence. If the connection
* operation failed then invoking this method will cause an appropriate
* {@link java.io.IOException} to be thrown.
*
* <p> If this channel is already connected then this method will not block
* and will immediately return {@code true}. If this channel is in
* non-blocking mode then this method will return {@code false} if the
* connection process is not yet complete. If this channel is in blocking
* mode then this method will block until the connection either completes
* or fails, and will always either return {@code true} or throw a checked
* exception describing the failure.
*
* <p> This method may be invoked at any time. If a read or write
* operation upon this channel is invoked while an invocation of this
* method is in progress then that operation will first block until this
* invocation is complete. If a connection attempt fails, that is, if an
* invocation of this method throws a checked exception, then the channel
* will be closed. </p>
*
* @return {@code true} if, and only if, this channel's socket is now
* connected
*
* @throws NoConnectionPendingException
* If this channel is not connected and a connection operation
* has not been initiated
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws AsynchronousCloseException
* If another thread closes this channel
* while the connect operation is in progress
*
* @throws ClosedByInterruptException
* If another thread interrupts the current thread
* while the connect operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract boolean finishConnect() throws IOException;
/**
* Returns the remote address to which this channel's socket is connected.
*
* <p> Where the channel is bound and connected to an Internet Protocol
* socket address then the return value from this method is of type {@link
* java.net.InetSocketAddress}.
*
* @return The remote address; {@code null} if the channel's socket is not
* connected
*
* @throws ClosedChannelException
* If the channel is closed
* @throws IOException
* If an I/O error occurs
*
* @since 1.7
*/
public abstract SocketAddress getRemoteAddress() throws IOException;
// -- ByteChannel operations --
/**
* @throws NotYetConnectedException
* If this channel is not yet connected
*/
public abstract int read(ByteBuffer dst) throws IOException;
/**
* @throws NotYetConnectedException
* If this channel is not yet connected
*/
public abstract long read(ByteBuffer[] dsts, int offset, int length)
throws IOException;
/**
* @throws NotYetConnectedException
* If this channel is not yet connected
*/
public final long read(ByteBuffer[] dsts) throws IOException {
return read(dsts, 0, dsts.length);
}
/**
* @throws NotYetConnectedException
* If this channel is not yet connected
*/
public abstract int write(ByteBuffer src) throws IOException;
/**
* @throws NotYetConnectedException
* If this channel is not yet connected
*/
public abstract long write(ByteBuffer[] srcs, int offset, int length)
throws IOException;
/**
* @throws NotYetConnectedException
* If this channel is not yet connected
*/
public final long write(ByteBuffer[] srcs) throws IOException {
return write(srcs, 0, srcs.length);
}
/**
* {@inheritDoc}
* <p>
* If there is a security manager set, its {@code checkConnect} method is
* called with the local address and {@code -1} as its arguments to see
* if the operation is allowed. If the operation is not allowed,
* a {@code SocketAddress} representing the
* {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
* local port of the channel's socket is returned.
*
* @return The {@code SocketAddress} that the socket is bound to, or the
* {@code SocketAddress} representing the loopback address if
* denied by the security manager, or {@code null} if the
* channel's socket is not bound
*
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
*/
@Override
public abstract SocketAddress getLocalAddress() throws IOException;
}

View file

@ -0,0 +1,105 @@
/*
* Copyright (c) 2000, 2005, 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;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* A channel that can write bytes.
*
* <p> Only one write operation upon a writable channel may be in progress at
* any given time. If one thread initiates a write operation upon a channel
* then any other thread that attempts to initiate another write operation will
* block until the first operation is complete. Whether or not other kinds of
* I/O operations may proceed concurrently with a write operation depends upon
* the type of the channel. </p>
*
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public interface WritableByteChannel
extends Channel
{
/**
* Writes a sequence of bytes to this channel from the given buffer.
*
* <p> An attempt is made to write up to <i>r</i> bytes to the channel,
* where <i>r</i> is the number of bytes remaining in the buffer, that is,
* {@code src.remaining()}, at the moment this method is invoked.
*
* <p> Suppose that a byte sequence of length <i>n</i> is written, where
* {@code 0}&nbsp;{@code <=}&nbsp;<i>n</i>&nbsp;{@code <=}&nbsp;<i>r</i>.
* This byte sequence will be transferred from the buffer starting at index
* <i>p</i>, where <i>p</i> is the buffer's position at the moment this
* method is invoked; the index of the last byte written will be
* <i>p</i>&nbsp;{@code +}&nbsp;<i>n</i>&nbsp;{@code -}&nbsp;{@code 1}.
* Upon return the buffer's position will be equal to
* <i>p</i>&nbsp;{@code +}&nbsp;<i>n</i>; its limit will not have changed.
*
* <p> Unless otherwise specified, a write operation will return only after
* writing all of the <i>r</i> requested bytes. Some types of channels,
* depending upon their state, may write only some of the bytes or possibly
* none at all. A socket channel in non-blocking mode, for example, cannot
* write any more bytes than are free in the socket's output buffer.
*
* <p> This method may be invoked at any time. If another thread has
* already initiated a write operation upon this channel, however, then an
* invocation of this method will block until the first operation is
* complete. </p>
*
* @param src
* The buffer from which bytes are to be retrieved
*
* @return The number of bytes written, possibly zero
*
* @throws NonWritableChannelException
* If this channel was not opened for writing
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws AsynchronousCloseException
* If another thread closes this channel
* while the write operation is in progress
*
* @throws ClosedByInterruptException
* If another thread interrupts the current thread
* while the write operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws IOException
* If some other I/O error occurs
*/
public int write(ByteBuffer src) throws IOException;
}

View file

@ -0,0 +1,194 @@
#
# 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.
#
# Generated exception classes for java.nio.channels
SINCE=1.4
PACKAGE=java.nio.channels
# This year should only change if the generated source is modified.
COPYRIGHT_YEARS="2000, 2007,"
SUPER=java.io.IOException
gen ClosedChannelException "
* Checked exception thrown when an attempt is made to invoke or complete an
* I/O operation upon channel that is closed, or at least closed to that
* operation. That this exception is thrown does not necessarily imply that
* the channel is completely closed. A socket channel whose write half has
* been shut down, for example, may still be open for reading." \
882777185433553857L
gen FileLockInterruptionException "
* Checked exception received by a thread when another thread interrupts it
* while it is waiting to acquire a file lock. Before this exception is thrown
* the interrupt status of the previously-blocked thread will have been set." \
7104080643653532383L
SUPER=ClosedChannelException
gen AsynchronousCloseException "
* Checked exception received by a thread when another thread closes the
* channel or the part of the channel upon which it is blocked in an I/O
* operation." \
6891178312432313966L
SUPER=AsynchronousCloseException
gen ClosedByInterruptException "
* Checked exception received by a thread when another thread interrupts it
* while it is blocked in an I/O operation upon a channel. Before this
* exception is thrown the channel will have been closed and the interrupt
* status of the previously-blocked thread will have been set." \
-4488191543534286750L
SUPER=IllegalArgumentException
gen IllegalSelectorException "
* Unchecked exception thrown when an attempt is made to register a channel
* with a selector that was not created by the provider that created the
* channel." \
-8406323347253320987L
gen UnresolvedAddressException "
* Unchecked exception thrown when an attempt is made to invoke a network
* operation upon an unresolved socket address." \
6136959093620794148L
gen UnsupportedAddressTypeException "
* Unchecked exception thrown when an attempt is made to bind or connect
* to a socket address of a type that is not supported." \
-2964323842829700493L
SUPER=IllegalStateException
gen AlreadyConnectedException "
* Unchecked exception thrown when an attempt is made to connect a {@link
* SocketChannel} that is already connected." \
-7331895245053773357L
gen ConnectionPendingException "
* Unchecked exception thrown when an attempt is made to connect a {@link
* SocketChannel} for which a non-blocking connection operation is already in
* progress." \
2008393366501760879L
gen ClosedSelectorException "
* Unchecked exception thrown when an attempt is made to invoke an I/O
* operation upon a closed selector." \
6466297122317847835L
gen CancelledKeyException "
* Unchecked exception thrown when an attempt is made to use
* a selection key that is no longer valid." \
-8438032138028814268L
gen IllegalBlockingModeException "
* Unchecked exception thrown when a blocking-mode-specific operation
* is invoked upon a channel in the incorrect blocking mode." \
-3335774961855590474L
gen NoConnectionPendingException "
* Unchecked exception thrown when the {@link SocketChannel#finishConnect
* finishConnect} method of a {@link SocketChannel} is invoked without first
* successfully invoking its {@link SocketChannel#connect connect} method." \
-8296561183633134743L
gen NonReadableChannelException "
* Unchecked exception thrown when an attempt is made to read
* from a channel that was not originally opened for reading." \
-3200915679294993514L
gen NonWritableChannelException "
* Unchecked exception thrown when an attempt is made to write
* to a channel that was not originally opened for writing." \
-7071230488279011621L
gen NotYetBoundException "
* Unchecked exception thrown when an attempt is made to invoke an I/O
* operation upon a server socket channel that is not yet bound." \
4640999303950202242L
gen NotYetConnectedException "
* Unchecked exception thrown when an attempt is made to invoke an I/O
* operation upon a socket channel that is not yet connected." \
4697316551909513464L
gen OverlappingFileLockException "
* Unchecked exception thrown when an attempt is made to acquire a lock on a
* region of a file that overlaps a region already locked by the same Java
* virtual machine, or when another thread is already waiting to lock an
* overlapping region of the same file." \
2047812138163068433L
SINCE=1.7
SUPER=java.io.IOException
gen InterruptedByTimeoutException "
* Checked exception received by a thread when a timeout elapses before an
* asynchronous operation completes." \
-4268008601014042947L
SUPER=IllegalArgumentException
gen IllegalChannelGroupException "
* Unchecked exception thrown when an attempt is made to open a channel
* in a group that was not created by the same provider. " \
-2495041211157744253L
SUPER=IllegalStateException
gen AlreadyBoundException "
* Unchecked exception thrown when an attempt is made to bind the socket a
* network oriented channel that is already bound." \
6796072983322737592L
gen AcceptPendingException "
* Unchecked exception thrown when an attempt is made to initiate an accept
* operation on a channel and a previous accept operation has not completed." \
2721339977965416421L
gen ReadPendingException "
* Unchecked exception thrown when an attempt is made to read from an
* asynchronous socket channel and a previous read has not completed." \
1986315242191227217L
gen WritePendingException "
* Unchecked exception thrown when an attempt is made to write to an
* asynchronous socket channel and a previous write has not completed." \
7031871839266032276L
gen ShutdownChannelGroupException "
* Unchecked exception thrown when an attempt is made to construct a channel in
* a group that is shutdown or the completion handler for an I/O operation
* cannot be invoked because the channel group has terminated." \
-3903801676350154157L

View file

@ -0,0 +1,340 @@
/*
* Copyright (c) 2001, 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.
*/
/**
* Defines channels, which represent connections to entities that are capable of
* performing I/O operations, such as files and sockets; defines selectors, for
* multiplexed, non-blocking I/O operations.
*
* <a id="channels"></a>
*
* <table class="striped" style="text-align:left; margin-left:2em">
* <caption style="display:none">Lists channels and their descriptions</caption>
* <thead>
* <tr><th scope="col">Channels</th>
* <th scope="col">Description</th></tr>
* </thead>
* <tbody>
* <tr><th scope="row"><i>{@link java.nio.channels.Channel}</i></th>
* <td>A nexus for I/O operations</td></tr>
* <tr><th scope="row">
* <span style="padding-left:1em"><i>{@link java.nio.channels.ReadableByteChannel}</i></span></th>
* <td>Can read into a buffer</td></tr>
* <tr><th scope="row">
* <span style="padding-left:2em"><i>{@link java.nio.channels.ScatteringByteChannel}</i></span></th>
* <td>Can read into a sequence of buffers</td></tr>
* <tr><th scope="row">
* <span style="padding-left:1em"><i>{@link java.nio.channels.WritableByteChannel}</i></span></th>
* <td>Can write from a buffer</td></tr>
* <tr><th scope="row">
* <span style="padding-left:2em"><i>{@link java.nio.channels.GatheringByteChannel}</i></span></th>
* <td>Can write from a sequence of buffers</td></tr>
* <tr><th scope="row">
* <span style="padding-left:1em"><i>{@link java.nio.channels.ByteChannel}</i></span></th>
* <td>Can read/write to/from a buffer</td></tr>
* <tr><th scope="row">
* <span style="padding-left:2em"><i>{@link java.nio.channels.SeekableByteChannel}</i></span></th>
* <td>A {@code ByteChannel} connected to an entity that contains a variable-length
* sequence of bytes</td></tr>
* <tr><th scope="row">
* <span style="padding-left:1em"><i>{@link java.nio.channels.AsynchronousChannel}</i></span></th>
* <td>Supports asynchronous I/O operations.</td></tr>
* <tr><th scope="row">
* <span style="padding-left:2em"><i>{@link java.nio.channels.AsynchronousByteChannel}</i></span></th>
* <td>Can read and write bytes asynchronously</td></tr>
* <tr><th scope="row">
* <span style="padding-left:1em"><i>{@link java.nio.channels.NetworkChannel}</i></span></th>
* <td>A channel to a network socket</td></tr>
* <tr><th scope="row">
* <span style="padding-left:2em"><i>{@link java.nio.channels.MulticastChannel}</i></span></th>
* <td>Can join Internet Protocol (IP) multicast groups</td></tr>
* <tr><th scope="row">{@link java.nio.channels.Channels}</th>
* <td>Utility methods for channel/stream interoperation</td></tr>
* </tbody>
* </table>
*
* <p> A <i>channel</i> represents an open connection to an entity such as a
* hardware device, a file, a network socket, or a program component that is
* capable of performing one or more distinct I/O operations, for example reading
* or writing. As specified in the {@link java.nio.channels.Channel} interface,
* channels are either open or closed, and they are both <i>asynchronously
* closeable</i> and <i>interruptible</i>.
*
* <p> The {@link java.nio.channels.Channel} interface is extended by several
* other interfaces.
*
* <p> The {@link java.nio.channels.ReadableByteChannel} interface specifies a
* {@link java.nio.channels.ReadableByteChannel#read read} method that reads bytes
* from the channel into a buffer; similarly, the {@link
* java.nio.channels.WritableByteChannel} interface specifies a {@link
* java.nio.channels.WritableByteChannel#write write} method that writes bytes
* from a buffer to the channel. The {@link java.nio.channels.ByteChannel}
* interface unifies these two interfaces for the common case of channels that can
* both read and write bytes. The {@link java.nio.channels.SeekableByteChannel}
* interface extends the {@code ByteChannel} interface with methods to {@link
* java.nio.channels.SeekableByteChannel#position() query} and {@link
* java.nio.channels.SeekableByteChannel#position(long) modify} the channel's
* current position, and its {@link java.nio.channels.SeekableByteChannel#size
* size}.
*
* <p> The {@link java.nio.channels.ScatteringByteChannel} and {@link
* java.nio.channels.GatheringByteChannel} interfaces extend the {@link
* java.nio.channels.ReadableByteChannel} and {@link
* java.nio.channels.WritableByteChannel} interfaces, respectively, adding {@link
* java.nio.channels.ScatteringByteChannel#read read} and {@link
* java.nio.channels.GatheringByteChannel#write write} methods that take a
* sequence of buffers rather than a single buffer.
*
* <p> The {@link java.nio.channels.NetworkChannel} interface specifies methods
* to {@link java.nio.channels.NetworkChannel#bind bind} the channel's socket,
* obtain the address to which the socket is bound, and methods to {@link
* java.nio.channels.NetworkChannel#getOption get} and {@link
* java.nio.channels.NetworkChannel#setOption set} socket options. The {@link
* java.nio.channels.MulticastChannel} interface specifies methods to join
* Internet Protocol (IP) multicast groups.
*
* <p> The {@link java.nio.channels.Channels} utility class defines static methods
* that support the interoperation of the stream classes of the {@link
* java.io} package with the channel classes of this package. An appropriate
* channel can be constructed from an {@link java.io.InputStream} or an {@link
* java.io.OutputStream}, and conversely an {@link java.io.InputStream} or an
* {@link java.io.OutputStream} can be constructed from a channel. A {@link
* java.io.Reader} can be constructed that uses a given charset to decode bytes
* from a given readable byte channel, and conversely a {@link java.io.Writer} can
* be constructed that uses a given charset to encode characters into bytes and
* write them to a given writable byte channel.
*
* <table class="striped" style="margin-left:2em; text-align:left">
* <caption style="display:none">
* Lists file channels and their descriptions</caption>
* <thead>
* <tr><th scope="col">File channels</th>
* <th scope="col">Description</th></tr>
* </thead>
* <tbody>
* <tr><th scope="row">
* {@link java.nio.channels.FileChannel}</th>
* <td>Reads, writes, maps, and manipulates files</td></tr>
* <tr><th scope="row">
* {@link java.nio.channels.FileLock}</th>
* <td>A lock on a (region of a) file</td></tr>
* <tr><th scope="row">
* {@link java.nio.MappedByteBuffer}</th>
* <td>A direct byte buffer mapped to a region of a file</td></tr>
* </tbody>
* </table>
*
* <p> The {@link java.nio.channels.FileChannel} class supports the usual
* operations of reading bytes from, and writing bytes to, a channel connected to
* a file, as well as those of querying and modifying the current file position
* and truncating the file to a specific size. It defines methods for acquiring
* locks on the whole file or on a specific region of a file; these methods return
* instances of the {@link java.nio.channels.FileLock} class. Finally, it defines
* methods for forcing updates to the file to be written to the storage device that
* contains it, for efficiently transferring bytes between the file and other
* channels, and for mapping a region of the file directly into memory.
*
* <p> A {@code FileChannel} is created by invoking one of its static {@link
* java.nio.channels.FileChannel#open open} methods, or by invoking the {@code
* getChannel} method of a {@link java.io.FileInputStream}, {@link
* java.io.FileOutputStream}, or {@link java.io.RandomAccessFile} to return a
* file channel connected to the same underlying file as the {@link java.io}
* class.
*
* <a id="multiplex"></a>
* <table class="striped" style="margin-left:2em; text-align:left">
* <caption style="display:none">
* Lists multiplexed, non-blocking channels and their descriptions</caption>
* <thead>
* <tr><th scope="col">Multiplexed, non-blocking I/O</th>
* <th scope="col">Description</th></tr>
* </thead>
* <tbody>
* <tr><th scope="row">{@link java.nio.channels.SelectableChannel}</th>
* <td>A channel that can be multiplexed</td></tr>
* <tr><th scope="row">
* <span style="padding-left:2em">{@link java.nio.channels.DatagramChannel}</span></th>
* <td>A channel to a datagram-oriented socket</td></tr>
* <tr><th scope="row">
* <span style="padding-left:2em">{@link java.nio.channels.Pipe.SinkChannel}</span></th>
* <td>The write end of a pipe</td></tr>
* <tr><th scope="row">
* <span style="padding-left:2em">{@link java.nio.channels.Pipe.SourceChannel}</span></th>
* <td>The read end of a pipe</td></tr>
* <tr><th scope="row">
* <span style="padding-left:2em">{@link java.nio.channels.ServerSocketChannel}</span></th>
* <td>A channel to a stream-oriented listening socket</td></tr>
* <tr><th scope="row">
* <span style="padding-left:2em">{@link java.nio.channels.SocketChannel}</span></th>
* <td>A channel for a stream-oriented connecting socket</td></tr>
* <tr><th scope="row">{@link java.nio.channels.Selector}</th>
* <td>A multiplexor of selectable channels</td></tr>
* <tr><th scope="row">{@link java.nio.channels.SelectionKey}</th>
* <td>A token representing the registration of a channel
* with a selector</td></tr>
* <tr><th scope="row">{@link java.nio.channels.Pipe}</th>
* <td>Two channels that form a unidirectional pipe</td></tr>
* </tbody>
* </table>
*
* <p> Multiplexed, non-blocking I/O, which is much more scalable than
* thread-oriented, blocking I/O, is provided by <i>selectors</i>, <i>selectable
* channels</i>, and <i>selection keys</i>.
*
* <p> A <a href="Selector.html"><i>selector</i></a> is a multiplexor of <a
* href="SelectableChannel.html"><i>selectable channels</i></a>, which in turn are
* a special type of channel that can be put into <a
* href="SelectableChannel.html#bm"><i>non-blocking mode</i></a>. To perform
* multiplexed I/O operations, one or more selectable channels are first created,
* put into non-blocking mode, and {@link
* java.nio.channels.SelectableChannel#register <i>registered</i>}
* with a selector. Registering a channel specifies the set of I/O operations
* that will be tested for readiness by the selector, and returns a <a
* href="SelectionKey.html"><i>selection key</i></a> that represents the
* registration.
*
* <p> Once some channels have been registered with a selector, a <a
* href="Selector.html#selop"><i>selection operation</i></a> can be performed in
* order to discover which channels, if any, have become ready to perform one or
* more of the operations in which interest was previously declared. If a channel
* is ready then the key returned when it was registered will be added to the
* selector's <i>selected-key set</i>. The key set, and the keys within it, can
* be examined in order to determine the operations for which each channel is
* ready. From each key one can retrieve the corresponding channel in order to
* perform whatever I/O operations are required.
*
* <p> That a selection key indicates that its channel is ready for some operation
* is a hint, but not a guarantee, that such an operation can be performed by a
* thread without causing the thread to block. It is imperative that code that
* performs multiplexed I/O be written so as to ignore these hints when they prove
* to be incorrect.
*
* <p> This package defines selectable-channel classes corresponding to the {@link
* java.net.DatagramSocket}, {@link java.net.ServerSocket}, and {@link
* java.net.Socket} classes defined in the {@link java.net} package.
* Minor changes to these classes have been made in order to support sockets that
* are associated with channels. This package also defines a simple class that
* implements unidirectional pipes. In all cases, a new selectable channel is
* created by invoking the static {@code open} method of the corresponding class.
* If a channel needs an associated socket then a socket will be created as a side
* effect of this operation.
*
* <p> The implementation of selectors, selectable channels, and selection keys
* can be replaced by "plugging in" an alternative definition or instance of the
* {@link java.nio.channels.spi.SelectorProvider} class defined in the {@link
* java.nio.channels.spi} package. It is not expected that many developers
* will actually make use of this facility; it is provided primarily so that
* sophisticated users can take advantage of operating-system-specific
* I/O-multiplexing mechanisms when very high performance is required.
*
* <p> Much of the bookkeeping and synchronization required to implement the
* multiplexed-I/O abstractions is performed by the {@link
* java.nio.channels.spi.AbstractInterruptibleChannel}, {@link
* java.nio.channels.spi.AbstractSelectableChannel}, {@link
* java.nio.channels.spi.AbstractSelectionKey}, and {@link
* java.nio.channels.spi.AbstractSelector} classes in the {@link
* java.nio.channels.spi} package. When defining a custom selector provider,
* only the {@link java.nio.channels.spi.AbstractSelector} and {@link
* java.nio.channels.spi.AbstractSelectionKey} classes should be subclassed
* directly; custom channel classes should extend the appropriate {@link
* java.nio.channels.SelectableChannel} subclasses defined in this package.
*
* <a id="async"></a>
*
* <table class="striped" style="padding-left:2em; text-align:left">
* <caption style="display:none">
* Lists asynchronous channels and their descriptions</caption>
* <thead>
* <tr><th scope="col">Asynchronous I/O</th>
* <th scope="col">Description</th></tr>
* </thead>
* <tbody>
* <tr><th scope="row">
* {@link java.nio.channels.AsynchronousFileChannel}</th>
* <td>An asynchronous channel for reading, writing, and manipulating a file</td></tr>
* <tr><th scope="row">
* {@link java.nio.channels.AsynchronousSocketChannel}</th>
* <td>An asynchronous channel to a stream-oriented connecting socket</td></tr>
* <tr><th scope="row">
* {@link java.nio.channels.AsynchronousServerSocketChannel}</th>
* <td>An asynchronous channel to a stream-oriented listening socket</td></tr>
* <tr><th scope="row">
* {@link java.nio.channels.CompletionHandler}</th>
* <td>A handler for consuming the result of an asynchronous operation</td></tr>
* <tr><th scope="row">
* {@link java.nio.channels.AsynchronousChannelGroup}</th>
* <td>A grouping of asynchronous channels for the purpose of resource sharing</td></tr>
* </tbody>
* </table>
*
* <p> {@link java.nio.channels.AsynchronousChannel Asynchronous channels} are a
* special type of channel capable of asynchronous I/O operations. Asynchronous
* channels are non-blocking and define methods to initiate asynchronous
* operations, returning a {@link java.util.concurrent.Future} representing the
* pending result of each operation. The {@code Future} can be used to poll or
* wait for the result of the operation. Asynchronous I/O operations can also
* specify a {@link java.nio.channels.CompletionHandler} to invoke when the
* operation completes. A completion handler is user provided code that is executed
* to consume the result of I/O operation.
*
* <p> This package defines asynchronous-channel classes that are connected to
* a stream-oriented connecting or listening socket, or a datagram-oriented socket.
* It also defines the {@link java.nio.channels.AsynchronousFileChannel} class
* for asynchronous reading, writing, and manipulating a file. As with the {@link
* java.nio.channels.FileChannel} it supports operations to truncate the file
* to a specific size, force updates to the file to be written to the storage
* device, or acquire locks on the whole file or on a specific region of the file.
* Unlike the {@code FileChannel} it does not define methods for mapping a
* region of the file directly into memory. Where memory mapped I/O is required,
* then a {@code FileChannel} can be used.
*
* <p> Asynchronous channels are bound to an asynchronous channel group for the
* purpose of resource sharing. A group has an associated {@link
* java.util.concurrent.ExecutorService} to which tasks are submitted to handle
* I/O events and dispatch to completion handlers that consume the result of
* asynchronous operations performed on channels in the group. The group can
* optionally be specified when creating the channel or the channel can be bound
* to a <em>default group</em>. Sophisticated users may wish to create their
* own asynchronous channel groups or configure the {@code ExecutorService}
* that will be used for the default group.
*
* <p> As with selectors, the implementation of asynchronous channels can be
* replaced by "plugging in" an alternative definition or instance of the {@link
* java.nio.channels.spi.AsynchronousChannelProvider} class defined in the
* {@link java.nio.channels.spi} package. It is not expected that many
* developers will actually make use of this facility; it is provided primarily
* so that sophisticated users can take advantage of operating-system-specific
* asynchronous I/O mechanisms when very high performance is required.
*
* <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;

View file

@ -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}&nbsp;...&nbsp;{@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}&nbsp;...&nbsp;{@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}&nbsp;...&nbsp;{@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);
}
}

View file

@ -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;
}

View file

@ -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);
}
}
}
}

View file

@ -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}&nbsp;...&nbsp;{@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}&nbsp;...&nbsp;{@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}&nbsp;...&nbsp;{@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);
}
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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;