blob: 830fc5ce961714eb677f9b44bb55ac93d1617b04 [file] [log] [blame]
/*-
* Copyright (C) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This file was distributed by Oracle as part of a version of Oracle Berkeley
* DB Java Edition made available at:
*
* http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
*
* Please see the LICENSE file included in the top-level directory of the
* appropriate version of Oracle Berkeley DB Java Edition for a copy of the
* license and additional information.
*/
package com.sleepycat.je.rep.net;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.ByteChannel;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.channels.SocketChannel;
/**
* @hidden
* An interface that associates a delegate socketChannel for network I/O, which
* provides ByteChannel, GatheringByteChannel, and ScatteringByteChannel,
* interfaces for callers.
*
* The interface supports both blocking/non-blocking socketChannel as well as
* normal and SSL connection, which complicates the semantics of its methods.
*/
public interface DataChannel extends ByteChannel,
GatheringByteChannel,
ScatteringByteChannel {
/**
* Checks whether the channel is connected.
*
* @return {@code true} if the channel is connected
*/
public boolean isConnected();
/**
* Retrieves a socket associated with this channel.
*
* @return a socket associated with this channel.
*/
public Socket socket();
/**
* Returns the remote address to which this channel's socket is connected.
*/
public SocketAddress getRemoteAddress() throws IOException;
/**
* Adjusts this channel's blocking mode.
*/
public void configureBlocking(boolean block) throws IOException;
/**
* Tells whether or not every I/O operation on this channel will block
* until it completes.
*/
public boolean isBlocking();
/**
* Checks whether the channel encrypted.
*
* @return true if the data channel provides network privacy
*/
public boolean isSecure();
/**
* Checks whether the channel capable of determining peer trust.
*
* @return true if the data channel implementation has the capability
* to determine trust.
*/
public boolean isTrustCapable();
/**
* Checks whether the channel peer is trusted.
*
* @return true if the channel has determined that the peer is trusted.
*/
public boolean isTrusted();
/**
* The status of the flush method.
*/
public enum FlushStatus {
/** Flushes are not being used. */
DISABLED,
/** Nothing needs to be flushed. */
DONE,
/** Flush not complete because there is something left to flush. */
AGAIN,
/** Flush not complete because socket is busy. */
SO_WAIT_WRITE,
/** Flush not complete due to a concurrent competing operation. */
CONTENTION,
}
/**
* Reads a sequence of bytes from this channel into a subsequence of the
* given buffers.
*
* <p>The method throws {@link ClosedChannelException} after channel is
* closed. The channel is closed if any of the {@link #close}, {@link
* #closeForcefully} or {@link #closeAsync} was called (regardless of
* the return value or exception thrown). The method may throw {@link
* AsynchronousCloseException} when another thread is closing the channel
* concurrently.
*
* <p>The method should not block any of the close methods.
*/
@Override
public long read(ByteBuffer[] dsts, int offset, int length)
throws IOException;
/**
* Writes a sequence of bytes to this channel from a subsequence of the
* given buffers.
*
* <p>The behavior w.r.t the {@link #flush} method:
* <ul>
* <li>If the channel is configured blocking, the method should flush the
* written data before it normally exits.</li>
*
* <li>If the channel is configured non-blocking, the write method does not
* guarantee the written data is flushed. The caller should call the flush
* method, or close the socket with close or closeAsync, if it needs to
* make sure that the data has been completely written.</li>
* </ul>
*
* <p>The behavior w.r.t the channel-close methods:
*
* <ul>
* <li>The method throws {@link ClosedChannelException} after channel is
* closed. The channel is closed if any of the {@link #close}, {@link
* #closeForcefully} or {@link #closeAsync} was called and exited
* (regardless of the return value or exception thrown). The method may
* throw {@link AsynchronousCloseException} when another thread is closing
* the channel concurrently.</li>
*
* <li>The method should not block any of the close methods.</li>
* </ul>
*/
@Override
public long write(ByteBuffer[] srcs, int offset, int length)
throws IOException;
/**
* Attempts to flush any pending writes to the underlying socket buffer.
*
* <p>Calling this method is not needed in cases where {@link #write}
* itself will push the data to the transport. In such cases, the method is
* equivalent to a no-op method and should return {@link
* FlushStatus#DISABLED}.
*
* <p>The method throws {@link ClosedChannelException} after channel is
* closed. The channel is closed if any of the {@link #close}, {@link
* #closeForcefully} or {@link #closeAsync} was called (regardless of
* the return value or exception thrown). The method may throw {@link
* AsynchronousCloseException} when another thread is closing the channel
* concurrently.
*
* @return the flush status
*/
public FlushStatus flush() throws IOException;
/**
* Closes this channel, which should be a blocking channel.
*
* <p>It is considered a coding error to call this method if the channel is
* configured as non-blocking: use {@link #closeAsync} or {@link
* #closeForcefully} instead. If called for a non-blocking channel, this
* method closes the channel forcefully and throws {@link
* IllegalStateException}.
*
* <p>The method cleanly closes the channel, blocking if necessary. The
* method should only be blocked for its own connection operations (i.e.,
* not by concurrent {@link #read},{@link #write}, {@link #flush} methods
* or lock acquisitions, etc). The method throws {@link IOException} if the
* connection is unresponsive and timed out.
*
* <p>If the method detects a concurrent {@link #read}, {@link #write} or
* {@link #flush} method being called, the method throws {@link
* IOException}.
*
* <p>Implementations of this method should flush written data before
* closing the channel.
*
* <p>If an error occurs, the method attempts to forcefully close the
* channel, before throwing the exception. Only the first encountered
* exception is thrown.
*
* <p>The channel is closed (i.e., {@link isOpen} returns {@code false})
* after this method returns, even if an exception is thrown. The {@link
* #read}, {@link #write} and {@link #flush} methods will throw {@link
* ClosedChannelException} when the channel is closed. These methods may
* throw {@link AsynchronousCloseException} if called concurrently with
* this method.
*
* @throws IOException if an error occurs
*/
@Override
public void close() throws IOException;
/**
* The status of the close async method.
*/
public enum CloseAsyncStatus {
/* Close not complete waiting for a read. */
SO_WAIT_READ,
/* Close not complete waiting for a write. */
SO_WAIT_WRITE,
/* Close complete. */
DONE,
}
/**
* Closes this channel, which should be a non-blocking channel.
*
* <p>It is considered a coding error to call this method if the channel is
* configured as blocking: use {@link #close} or {@link #closeForcefully}
* instead. If called for a blocking channel, this method closes the
* channel forcefully and throws {@link IllegalStateException}.
*
* <p>The method cleanly closes the channel in a non-blocking manner. The
* channel is closed (i.e., {@link isOpen} returns {@code false}) once the
* method is called (regardless of return value or exception thrown). The
* caller, however, should keep calling this method until it returns {@code
* true} or throws exception. The channel is cleanly closed if the method
* returns {@code true} or forcefully closed if the method throws
* exception.
*
* <p>Implementations of this method should flush written data before
* closing the channel.
*
* <p>If the method detects a concurrent {@link #read}, {@link #write} or
* {@link #flush} method being called, the method throws {@link
* IOException}.
*
* <p>If an error occurs, the method attempts to forcefully close the
* channel, before throwing the exception. Only the first encountered
* exception is thrown.
*
* <p> The {@link #read}, {@link #write} and {@link #flush} methods will
* throw {@link ClosedChannelException} when the channel is closed. These
* methods may throw {@link AsynchronousCloseException} if called
* concurrently with this method.
*
* @return {@code true} if the channel is cleanly closed
* @throws IOException if there is an error
*/
public CloseAsyncStatus closeAsync() throws IOException;
/**
* Closes this channel forcefully.
*
* <p>The method returns immediately, i.e., it should not be blocked by
* concurrent {@link #read}, {@link #write} or {@link #flush} methods, nor
* should it be blocked by socket operations.
*
* <p>The method does not guarantee to flush written data before closing
* the channel, nor does it guarantee to do any procedure required for a
* clean close.
*
* <p>The channel is closed (i.e., {@link isOpen} returns {@code false})
* after this method returns. The {@link #read}, {@link #write} and {@link
* #flush} methods will throw {@link ClosedChannelException} when the
* channel is closed. These methods may throw {@link
* AsynchronousCloseException} if called concurrently with this method.
*
* @throws IOException if an error occurs
*/
public void closeForcefully() throws IOException;
/**
* Accessor for the underlying SocketChannel.
*
* Use of this accessor is discouraged. An implementation may have special
* treatment for methods in SocketChannel. For example, SSLDataChannel
* caches the blocking mode to avoid some blocking issue. Therefore, using
* the above wrap methods are preferrable.
*
* @return the socket channel underlying this data channel instance
*/
public SocketChannel getSocketChannel();
}