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.
|
* The buffer may chose to do a compact before filling.
|
||||||
* @return an <code>int</code> value indicating the number of bytes
|
* @return an <code>int</code> value indicating the number of bytes
|
||||||
* filled or -1 if EOF is reached.
|
* filled or -1 if EOF is reached.
|
||||||
|
* @throws EofException If input is shutdown or the endpoint is closed.
|
||||||
*/
|
*/
|
||||||
int fill(Buffer buffer) throws IOException;
|
int fill(Buffer buffer) throws IOException;
|
||||||
|
|
||||||
|
@ -59,6 +60,7 @@ public interface EndPoint
|
||||||
*
|
*
|
||||||
* @param buffer The buffer to flush. This buffers getIndex is updated.
|
* @param buffer The buffer to flush. This buffers getIndex is updated.
|
||||||
* @return the number of bytes written
|
* @return the number of bytes written
|
||||||
|
* @throws EofException If the endpoint is closed or output is shutdown.
|
||||||
*/
|
*/
|
||||||
int flush(Buffer buffer) throws IOException;
|
int flush(Buffer buffer) throws IOException;
|
||||||
|
|
||||||
|
@ -157,7 +159,7 @@ public interface EndPoint
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** Flush any buffered output.
|
/** Flush any buffered output.
|
||||||
* May fail to write all data if endpoint is non-blocking
|
* 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;
|
public void flush() throws IOException;
|
||||||
|
|
||||||
|
|
|
@ -38,21 +38,42 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
|
||||||
|
|
||||||
private final SelectorManager.SelectSet _selectSet;
|
private final SelectorManager.SelectSet _selectSet;
|
||||||
private final SelectorManager _manager;
|
private final SelectorManager _manager;
|
||||||
|
private SelectionKey _key;
|
||||||
private final Runnable _handler = new Runnable()
|
private final Runnable _handler = new Runnable()
|
||||||
{
|
{
|
||||||
public void run() { handle(); }
|
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;
|
private volatile Connection _connection;
|
||||||
|
|
||||||
|
/** true if a thread has been dispatched to handle this endpoint */
|
||||||
private boolean _dispatched = false;
|
private boolean _dispatched = false;
|
||||||
|
|
||||||
|
/** true if a non IO dispatch (eg async resume) is outstanding */
|
||||||
private boolean _redispatched = false;
|
private boolean _redispatched = false;
|
||||||
|
|
||||||
|
/** true if the last write operation succeed and wrote all offered bytes */
|
||||||
private volatile boolean _writable = true;
|
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;
|
private boolean _readBlocked;
|
||||||
|
|
||||||
|
/** True if a thread has is blocked in {@link #blockWritable(long)} */
|
||||||
private boolean _writeBlocked;
|
private boolean _writeBlocked;
|
||||||
|
|
||||||
|
/** true if {@link SelectSet#destroyEndPoint(SelectChannelEndPoint)} has not been called */
|
||||||
private boolean _open;
|
private boolean _open;
|
||||||
|
|
||||||
private volatile long _idleTimestamp;
|
private volatile long _idleTimestamp;
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
|
|
@ -14,9 +14,15 @@
|
||||||
package org.eclipse.jetty.io;
|
package org.eclipse.jetty.io;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
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.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
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.eclipse.jetty.util.IO;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -42,4 +48,88 @@ public class IOTest
|
||||||
out.toString(),
|
out.toString(),
|
||||||
"The quick brown fox jumped over the lazy dog");
|
"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