/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.sun.jini.jeri.internal.mux; import java.io.IOException; import java.nio.ByteBuffer; /** * ConnectionIO is an abstraction over a bi-directional byte stream * connection that provides the following features: * * - methods for sending sequences of bytes over the connection atomically * (with respect to other threads) and asynchronously, with the option of * receiving a notification when a given sequence has been written (i.e. * when the buffer used to pass the sequence may again be used) * * - callbacks invoked on the host Mux object to process data that has been * received over the connection, whenever new data arrives * * The ConnectionIO API uses java.nio.ByteBuffer objects to represent * sequences of bytes for writing or reading. * * The abstraction is intended to be implementable for both blocking * streams (requiring separate read and write threads per connection) and * non-blocking selectable channels (using a select-based I/O event handler * for completing I/O operations that would otherwise block). * * @author Sun Microsystems, Inc. * */ abstract class ConnectionIO { /** the Mux object associated with this instance */ final Mux mux; /** * Constructs a new instance. The supplied Mux object is used in * the following ways: * * - its processIncomingData method is invoked whenever new data is * received over the connection. * * - its muxLock field is used for mutual exclusion of instance state, * as well as for notification of state changes. This lock is shared * so that the muxDown field, and notifications of changes to it, are * integrated with other state change notifications. */ ConnectionIO(Mux mux) { this.mux = mux; } /** * Start whatever asynchronous activities are required for implementing * this instance. This method must be invoked before invoking any of the * "send" methods, and data read from the connection will only be * dispatched to the Mux object after this method has been invoked. */ abstract void start() throws IOException; /** * Sends the sequence of bytes contained in the supplied buffer to the * underlying connection. The sequence of bytes is the contents of the * buffer between its current position and its limit. This sequence is * guaranteed to be written atomically with respect to other threads * invoking this instance's "send" methods. * * The actual writing to the underlying connection, including access to * the buffer's contents and other state, is asynchronous with the * invocation of this method; therefore, the supplied buffer must not * be mutated even after this method has returned. */ abstract void asyncSend(ByteBuffer buffer); /** * Sends the sequence of bytes contained in the supplied buffers to the * underlying connection. The sequence of bytes is the contents of the * first buffer between its current position and its limit, followed by * the contents of the second buffer between its current position and * its limit. This sequence is guaranteed to be written atomically with * respect to other threads invoking this instance's "send" methods. * * The actual writing to the underlying connection, including access to * the buffers' contents and other state, is asynchronous with the * invocation of this method; therefore, the supplied buffers must not * be mutated even after this method has returned. */ abstract void asyncSend(ByteBuffer first, ByteBuffer second); /** * Sends the sequence of bytes contained in the supplied buffers to the * underlying connection. The sequence of bytes is the contents of the * first buffer between its current position and its limit, followed by * the contents of the second buffer between its current position and * its limit. This sequence is guaranteed to be written atomically with * respect to other threads invoking this instance's "send" methods. * * The actual writing to the underlying connection, including access to * the buffers' contents and other state, is asynchronous with the * invocation of this method; therefore, the supplied buffers must not * be mutated even after this method has returned, until it is guaranteed * that use of the buffers has completed. * * The returned IOFuture object can be used to wait until the write has * definitely completed (or will definitely not complete due to some * failure). After the write has completed, each buffers' position will * have been incremented to its limit (which will not have changed). */ abstract IOFuture futureSend(ByteBuffer first, ByteBuffer second); }