package net.i2p.client.streaming.impl; import net.i2p.I2PAppContext; /** * <p>Scheduler used for after both sides have had their close packets * ACKed, but the final timeout hasn't passed.</p> * * <h2>Entry conditions:</h2> * <ul> * <li>Both sides have closed and ACKed.</li> * <li>Less than the final timeout period has passed since the last ACK.</li> * </ul> * * <h2>Events:</h2> * <ul> * <li>Packets received</li> * <li>RESET received</li> * <li>Message sending fails (error talking to the session)</li> * </ul> * * <h2>Next states:</h2> * <ul> * <li>{@link SchedulerDead dead} - after the final timeout passes</li> * </ul> * * */ class SchedulerClosed extends SchedulerImpl { public SchedulerClosed(I2PAppContext ctx) { super(ctx); } public boolean accept(Connection con) { if (con == null) return false; long timeSinceClose = _context.clock().now() - con.getCloseSentOn(); boolean ok = (con.getCloseSentOn() > 0) && (con.getCloseReceivedOn() > 0) && //(con.getUnackedPacketsReceived() <= 0) && (con.getUnackedPacketsSent() <= 0) && (!con.getResetReceived()) && (timeSinceClose < Connection.DISCONNECT_TIMEOUT); boolean conTimeout = (con.getOptions().getConnectTimeout() < con.getLifetime()) && con.getSendStreamId() <= 0 && con.getLifetime() < Connection.DISCONNECT_TIMEOUT; return (ok || conTimeout); } public void eventOccurred(Connection con) { // noop. we do the timeout through the simpleTimer anyway //long timeLeft = con.getCloseSentOn() + Connection.DISCONNECT_TIMEOUT - _context.clock().now(); //reschedule(timeLeft, con); } }