javadoc
This commit is contained in:
parent
76cdf9badb
commit
ed9d9a0a33
|
@ -47,6 +47,7 @@ public interface EndPoint
|
|||
* The buffer may chose to do a compact before filling.
|
||||
* @return an <code>int</code> 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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue