View Javadoc
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 }