From ed9d9a0a33cdf08db75d09d638f9b76d007d97aa Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 6 Oct 2011 16:39:14 +1100 Subject: [PATCH] javadoc --- .../java/org/eclipse/jetty/io/EndPoint.java | 4 +- .../jetty/io/nio/SelectChannelEndPoint.java | 25 +++++- .../java/org/eclipse/jetty/io/IOTest.java | 90 +++++++++++++++++++ 3 files changed, 116 insertions(+), 3 deletions(-) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java index 21919c5fe12..6940991f387 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java @@ -47,6 +47,7 @@ public interface EndPoint * The buffer may chose to do a compact before filling. * @return an int value indicating the number of bytes * filled or -1 if EOF is reached. + * @throws EofException If input is shutdown or the endpoint is closed. */ int fill(Buffer buffer) throws IOException; @@ -59,6 +60,7 @@ public interface EndPoint * * @param buffer The buffer to flush. This buffers getIndex is updated. * @return the number of bytes written + * @throws EofException If the endpoint is closed or output is shutdown. */ int flush(Buffer buffer) throws IOException; @@ -157,7 +159,7 @@ public interface EndPoint /* ------------------------------------------------------------ */ /** Flush any buffered output. * May fail to write all data if endpoint is non-blocking - * @throws IOException + * @throws EofException If the endpoint is closed or output is shutdown. */ public void flush() throws IOException; diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java index 5bf00235e0c..a318543f647 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java @@ -38,21 +38,42 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo private final SelectorManager.SelectSet _selectSet; private final SelectorManager _manager; + private SelectionKey _key; private final Runnable _handler = new Runnable() { public void run() { handle(); } }; + /** The desired value for {@link SelectionKey#interestOps()} */ + private int _interestOps; + + /** + * The connection instance is the handler for any IO activity on the endpoint. + * There is a different type of connection for HTTP, AJP, WebSocket and + * ProxyConnect. The connection may change for an SCEP as it is upgraded + * from HTTP to proxy connect or websocket. + */ private volatile Connection _connection; + + /** true if a thread has been dispatched to handle this endpoint */ private boolean _dispatched = false; + + /** true if a non IO dispatch (eg async resume) is outstanding */ private boolean _redispatched = false; + + /** true if the last write operation succeed and wrote all offered bytes */ private volatile boolean _writable = true; - private SelectionKey _key; - private int _interestOps; + + /** True if a thread has is blocked in {@link #blockReadable(long)} */ private boolean _readBlocked; + + /** True if a thread has is blocked in {@link #blockWritable(long)} */ private boolean _writeBlocked; + + /** true if {@link SelectSet#destroyEndPoint(SelectChannelEndPoint)} has not been called */ private boolean _open; + private volatile long _idleTimestamp; /* ------------------------------------------------------------ */ diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java index 72fd8e35d00..1ca3b75fdfc 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java @@ -14,9 +14,15 @@ package org.eclipse.jetty.io; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.Reader; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketException; import org.eclipse.jetty.util.IO; import org.junit.Test; @@ -42,4 +48,88 @@ public class IOTest out.toString(), "The quick brown fox jumped over the lazy dog"); } + + @Test + public void testHalfCloses() throws Exception + { + ServerSocket connector = new ServerSocket(0); + + Socket client = new Socket("localhost",connector.getLocalPort()); + System.err.println(client); + Socket server = connector.accept(); + System.err.println(server); + + // we can write both ways + client.getOutputStream().write(1); + assertEquals(1,server.getInputStream().read()); + server.getOutputStream().write(1); + assertEquals(1,client.getInputStream().read()); + + // shutdown output results in read -1 + client.shutdownOutput(); + assertEquals(-1,server.getInputStream().read()); + + // Even though EOF has been read, the server input is not seen as shutdown + assertFalse(server.isInputShutdown()); + + // and we can read -1 again + assertEquals(-1,server.getInputStream().read()); + + // but cannot write + try { client.getOutputStream().write(1); assertTrue(false); } catch (SocketException e) {} + + // but can still write in opposite direction. + server.getOutputStream().write(1); + assertEquals(1,client.getInputStream().read()); + + + // server can shutdown input to match the shutdown out of client + server.shutdownInput(); + + // now we EOF instead of reading -1 + try { server.getInputStream().read(); assertTrue(false); } catch (SocketException e) {} + + + // but can still write in opposite direction. + server.getOutputStream().write(1); + assertEquals(1,client.getInputStream().read()); + + // client can shutdown input + client.shutdownInput(); + + // now we EOF instead of reading -1 + try { client.getInputStream().read(); assertTrue(false); } catch (SocketException e) {} + + // But we can still write at the server (data which will never be read) + server.getOutputStream().write(1); + + // and the server output is not shutdown + assertFalse( server.isOutputShutdown() ); + + // until we explictly shut it down + server.shutdownOutput(); + + // and now we can't write + try { server.getOutputStream().write(1); assertTrue(false); } catch (SocketException e) {} + + // but the sockets are still open + assertFalse(client.isClosed()); + assertFalse(server.isClosed()); + + // but if we close one end + client.close(); + + // it is seen as closed. + assertTrue(client.isClosed()); + + // but not the other end + assertFalse(server.isClosed()); + + // which has to be closed explictly + server.close(); + assertTrue(server.isClosed()); + + + + } }