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 }