package net.i2p.client.streaming.impl; import net.i2p.I2PAppContext; import net.i2p.util.Log; /** * <p>Scheduler used for locally created connections where we have not yet * sent the initial SYN packet.</p> * * <h2>Entry conditions:</h2> * <ul> * <li>Locally created</li> * <li>No packets sent or received</li> * </ul> * * <h2>Events:</h2> * <ul> * <li>Message flush (explicitly, through a full buffer, or stream closure)</li> * <li>Initial delay timeout (causing implicit flush of any data available)</li> * </ul> * * <h2>Next states:</h2> * <ul> * <li>{@link SchedulerConnecting connecting} - after sending a packet</li> * </ul> */ class SchedulerPreconnect extends SchedulerImpl { public SchedulerPreconnect(I2PAppContext ctx) { super(ctx); } public boolean accept(Connection con) { return (con != null) && (con.getSendStreamId() <= 0) && (con.getLastSendId() < 0); } public void eventOccurred(Connection con) { if (con.getNextSendTime() < 0) con.setNextSendTime(_context.clock().now() + con.getOptions().getConnectDelay()); long timeTillSend = con.getNextSendTime() - _context.clock().now(); if (timeTillSend <= 0) { if (_log.shouldLog(Log.DEBUG)) _log.debug("Send available for the SYN on " + con); con.sendAvailable(); con.setNextSendTime(-1); } else { if (_log.shouldLog(Log.DEBUG)) _log.debug("Wait " + timeTillSend + " before sending the SYN on " + con); reschedule(timeTillSend, con); } } }