1 //
2 // ========================================================================
3 // Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
4 // ------------------------------------------------------------------------
5 // All rights reserved. This program and the accompanying materials
6 // are made available under the terms of the Eclipse Public License v1.0
7 // and Apache License v2.0 which accompanies this distribution.
8 //
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
11 //
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
14 //
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
17 //
18
19 package org.eclipse.jetty.io;
20
21 import java.io.Closeable;
22 import java.io.IOException;
23 import java.net.InetSocketAddress;
24 import java.nio.ByteBuffer;
25 import java.nio.channels.ReadPendingException;
26 import java.nio.channels.WritePendingException;
27
28 import org.eclipse.jetty.util.Callback;
29 import org.eclipse.jetty.util.ExecutorCallback;
30 import org.eclipse.jetty.util.FutureCallback;
31
32
33
34 /**
35 *
36 * A transport EndPoint
37 *
38 * <h3>Asynchronous Methods</h3>
39 * <p>The asynchronous scheduling methods of {@link EndPoint}
40 * has been influenced by NIO.2 Futures and Completion
41 * handlers, but does not use those actual interfaces because they have
42 * some inefficiencies.</p>
43 * <p>This class will frequently be used in conjunction with some of the utility
44 * implementations of {@link Callback}, such as {@link FutureCallback} and
45 * {@link ExecutorCallback}. Examples are:</p>
46 *
47 * <h3>Blocking Read</h3>
48 * <p>A FutureCallback can be used to block until an endpoint is ready to be filled
49 * from:
50 * <blockquote><pre>
51 * FutureCallback<String> future = new FutureCallback<>();
52 * endpoint.fillInterested("ContextObj",future);
53 * ...
54 * String context = future.get(); // This blocks
55 * int filled=endpoint.fill(mybuffer);
56 * </pre></blockquote></p>
57 *
58 * <h3>Dispatched Read</h3>
59 * <p>By using a different callback, the read can be done asynchronously in its own dispatched thread:
60 * <blockquote><pre>
61 * endpoint.fillInterested("ContextObj",new ExecutorCallback<String>(executor)
62 * {
63 * public void onCompleted(String context)
64 * {
65 * int filled=endpoint.fill(mybuffer);
66 * ...
67 * }
68 * public void onFailed(String context,Throwable cause) {...}
69 * });
70 * </pre></blockquote></p>
71 * <p>The executor callback can also be customized to not dispatch in some circumstances when
72 * it knows it can use the callback thread and does not need to dispatch.</p>
73 *
74 * <h3>Blocking Write</h3>
75 * <p>The write contract is that the callback complete is not called until all data has been
76 * written or there is a failure. For blocking this looks like:
77 * <blockquote><pre>
78 * FutureCallback<String> future = new FutureCallback<>();
79 * endpoint.write("ContextObj",future,headerBuffer,contentBuffer);
80 * String context = future.get(); // This blocks
81 * </pre></blockquote></p>
82 *
83 * <h3>Dispatched Write</h3>
84 * <p>Note also that multiple buffers may be passed in write so that gather writes
85 * can be done:
86 * <blockquote><pre>
87 * endpoint.write("ContextObj",new ExecutorCallback<String>(executor)
88 * {
89 * public void onCompleted(String context)
90 * {
91 * int filled=endpoint.fill(mybuffer);
92 * ...
93 * }
94 * public void onFailed(String context,Throwable cause) {...}
95 * },headerBuffer,contentBuffer);
96 * </pre></blockquote></p>
97 */
98 public interface EndPoint extends Closeable
99 {
100 /* ------------------------------------------------------------ */
101 /**
102 * @return The local Inet address to which this <code>EndPoint</code> is bound, or <code>null</code>
103 * if this <code>EndPoint</code> does not represent a network connection.
104 */
105 InetSocketAddress getLocalAddress();
106
107 /* ------------------------------------------------------------ */
108 /**
109 * @return The remote Inet address to which this <code>EndPoint</code> is bound, or <code>null</code>
110 * if this <code>EndPoint</code> does not represent a network connection.
111 */
112 InetSocketAddress getRemoteAddress();
113
114 /* ------------------------------------------------------------ */
115 boolean isOpen();
116
117 /* ------------------------------------------------------------ */
118 long getCreatedTimeStamp();
119
120 /* ------------------------------------------------------------ */
121 /** Shutdown the output.
122 * <p>This call indicates that no more data will be sent on this endpoint that
123 * that the remote end should read an EOF once all previously sent data has been
124 * consumed. Shutdown may be done either at the TCP/IP level, as a protocol exchange (Eg
125 * TLS close handshake) or both.
126 * <p>
127 * If the endpoint has {@link #isInputShutdown()} true, then this call has the same effect
128 * as {@link #close()}.
129 */
130 void shutdownOutput();
131
132 /* ------------------------------------------------------------ */
133 /** Test if output is shutdown.
134 * The output is shutdown by a call to {@link #shutdownOutput()}
135 * or {@link #close()}.
136 * @return true if the output is shutdown or the endpoint is closed.
137 */
138 boolean isOutputShutdown();
139
140 /* ------------------------------------------------------------ */
141 /** Test if the input is shutdown.
142 * The input is shutdown if an EOF has been read while doing
143 * a {@link #fill(ByteBuffer)}. Once the input is shutdown, all calls to
144 * {@link #fill(ByteBuffer)} will return -1, until such time as the
145 * end point is close, when they will return {@link EofException}.
146 * @return True if the input is shutdown or the endpoint is closed.
147 */
148 boolean isInputShutdown();
149
150 /**
151 * Close any backing stream associated with the endpoint
152 */
153 void close();
154
155 /**
156 * Fill the passed buffer with data from this endpoint. The bytes are appended to any
157 * data already in the buffer by writing from the buffers limit up to it's capacity.
158 * The limit is updated to include the filled bytes.
159 *
160 * @param buffer The buffer to fill. The position and limit are modified during the fill. After the
161 * operation, the position is unchanged and the limit is increased to reflect the new data filled.
162 * @return an <code>int</code> value indicating the number of bytes
163 * filled or -1 if EOF is read or the input is shutdown.
164 * @throws EofException If the endpoint is closed.
165 */
166 int fill(ByteBuffer buffer) throws IOException;
167
168
169 /**
170 * Flush data from the passed header/buffer to this endpoint. As many bytes as can be consumed
171 * are taken from the header/buffer position up until the buffer limit. The header/buffers position
172 * is updated to indicate how many bytes have been consumed.
173 * @return True IFF all the buffers have been consumed and the endpoint has flushed the data to its
174 * destination (ie is not buffering any data).
175 *
176 * @throws EofException If the endpoint is closed or output is shutdown.
177 */
178 boolean flush(ByteBuffer... buffer) throws IOException;
179
180 /* ------------------------------------------------------------ */
181 /**
182 * @return The underlying transport object (socket, channel, etc.)
183 */
184 Object getTransport();
185
186 /* ------------------------------------------------------------ */
187 /** Get the max idle time in ms.
188 * <p>The max idle time is the time the endpoint can be idle before
189 * extraordinary handling takes place.
190 * @return the max idle time in ms or if ms <= 0 implies an infinite timeout
191 */
192 long getIdleTimeout();
193
194 /* ------------------------------------------------------------ */
195 /** Set the idle timeout.
196 * @param idleTimeout the idle timeout in MS. Timeout <= 0 implies an infinite timeout
197 */
198 void setIdleTimeout(long idleTimeout);
199
200
201 /**
202 * <p>Requests callback methods to be invoked when a call to {@link #fill(ByteBuffer)} would return data or EOF.</p>
203 *
204 * @param context the context to return via the callback
205 * @param callback the callback to call when an error occurs or we are readable.
206 * @throws ReadPendingException if another read operation is concurrent.
207 */
208 <C> void fillInterested(C context, Callback<C> callback) throws ReadPendingException;
209
210 /**
211 * <p>Writes the given buffers via {@link #flush(ByteBuffer...)} and invokes callback methods when either
212 * all the data has been flushed or an error occurs.</p>
213 *
214 * @param context the context to return via the callback
215 * @param callback the callback to call when an error occurs or the write completed.
216 * @param buffers one or more {@link ByteBuffer}s that will be flushed.
217 * @throws WritePendingException if another write operation is concurrent.
218 */
219 <C> void write(C context, Callback<C> callback, ByteBuffer... buffers) throws WritePendingException;
220
221 /**
222 * @return the {@link Connection} associated with this {@link EndPoint}
223 * @see #setConnection(Connection)
224 */
225 Connection getConnection();
226
227 /**
228 * @param connection the {@link Connection} associated with this {@link EndPoint}
229 * @see #getConnection()
230 */
231 void setConnection(Connection connection);
232
233 /**
234 * <p>Callback method invoked when this {@link EndPoint} is opened.</p>
235 * @see #onClose()
236 */
237 void onOpen();
238
239 /**
240 * <p>Callback method invoked when this {@link EndPoint} is close.</p>
241 * @see #onOpen()
242 */
243 void onClose();
244
245
246 }