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);
}
}