1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package org.apache.river.jeri.internal.mux; 20 21 import java.io.IOException; 22 import java.nio.ByteBuffer; 23 24 /** 25 * ConnectionIO is an abstraction over a bi-directional byte stream 26 * connection that provides the following features: 27 * 28 * - methods for sending sequences of bytes over the connection atomically 29 * (with respect to other threads) and asynchronously, with the option of 30 * receiving a notification when a given sequence has been written (i.e. 31 * when the buffer used to pass the sequence may again be used) 32 * 33 * - callbacks invoked on the host Mux object to process data that has been 34 * received over the connection, whenever new data arrives 35 * 36 * The ConnectionIO API uses java.nio.ByteBuffer objects to represent 37 * sequences of bytes for writing or reading. 38 * 39 * The abstraction is intended to be implementable for both blocking 40 * streams (requiring separate read and write threads per connection) and 41 * non-blocking selectable channels (using a select-based I/O event handler 42 * for completing I/O operations that would otherwise block). 43 * 44 * @author Sun Microsystems, Inc. 45 * 46 */ 47 abstract class ConnectionIO { 48 49 /** the Mux object associated with this instance */ 50 final Mux mux; 51 52 /** 53 * Constructs a new instance. The supplied Mux object is used in 54 * the following ways: 55 * 56 * - its processIncomingData method is invoked whenever new data is 57 * received over the connection. 58 * 59 * - its muxLock field is used for mutual exclusion of instance state, 60 * as well as for notification of state changes. This lock is shared 61 * so that the muxDown field, and notifications of changes to it, are 62 * integrated with other state change notifications. 63 */ 64 ConnectionIO(Mux mux) { 65 this.mux = mux; 66 } 67 68 /** 69 * Start whatever asynchronous activities are required for implementing 70 * this instance. This method must be invoked before invoking any of the 71 * "send" methods, and data read from the connection will only be 72 * dispatched to the Mux object after this method has been invoked. 73 */ 74 abstract void start() throws IOException; 75 76 /** 77 * Sends the sequence of bytes contained in the supplied buffer to the 78 * underlying connection. The sequence of bytes is the contents of the 79 * buffer between its current position and its limit. This sequence is 80 * guaranteed to be written atomically with respect to other threads 81 * invoking this instance's "send" methods. 82 * 83 * The actual writing to the underlying connection, including access to 84 * the buffer's contents and other state, is asynchronous with the 85 * invocation of this method; therefore, the supplied buffer must not 86 * be mutated even after this method has returned. 87 */ 88 abstract void asyncSend(ByteBuffer buffer); 89 90 /** 91 * Sends the sequence of bytes contained in the supplied buffers to the 92 * underlying connection. The sequence of bytes is the contents of the 93 * first buffer between its current position and its limit, followed by 94 * the contents of the second buffer between its current position and 95 * its limit. This sequence is guaranteed to be written atomically with 96 * respect to other threads invoking this instance's "send" methods. 97 * 98 * The actual writing to the underlying connection, including access to 99 * the buffers' contents and other state, is asynchronous with the 100 * invocation of this method; therefore, the supplied buffers must not 101 * be mutated even after this method has returned. 102 */ 103 abstract void asyncSend(ByteBuffer first, ByteBuffer second); 104 105 /** 106 * Sends the sequence of bytes contained in the supplied buffers to the 107 * underlying connection. The sequence of bytes is the contents of the 108 * first buffer between its current position and its limit, followed by 109 * the contents of the second buffer between its current position and 110 * its limit. This sequence is guaranteed to be written atomically with 111 * respect to other threads invoking this instance's "send" methods. 112 * 113 * The actual writing to the underlying connection, including access to 114 * the buffers' contents and other state, is asynchronous with the 115 * invocation of this method; therefore, the supplied buffers must not 116 * be mutated even after this method has returned, until it is guaranteed 117 * that use of the buffers has completed. 118 * 119 * The returned IOFuture object can be used to wait until the write has 120 * definitely completed (or will definitely not complete due to some 121 * failure). After the write has completed, each buffers' position will 122 * have been incremented to its limit (which will not have changed). 123 */ 124 abstract IOFuture futureSend(ByteBuffer first, ByteBuffer second); 125 }