package net.i2p.util; import java.io.IOException; import java.net.Socket; import java.text.SimpleDateFormat; import java.util.Date; /** * This should be deprecated. * It is only used by EepGet and Syndie. * The only advantage seems to be a total timeout period, which is the second * argument to EepGet.fetch(headerTimeout, totalTimeout, inactivityTimeout), * which is most likely always set to -1. * * Use socket.setsotimeout instead? */ public class SocketTimeout extends SimpleTimer2.TimedEvent { private volatile Socket _targetSocket; private final long _startTime; private volatile long _inactivityDelay; private volatile long _lastActivity; private volatile long _totalTimeoutTime; private volatile boolean _cancelled; private volatile Runnable _command; public SocketTimeout(long delay) { this(null, delay); } public SocketTimeout(Socket socket, long delay) { super(SimpleTimer2.getInstance()); _inactivityDelay = delay; _targetSocket = socket; _cancelled = false; _lastActivity = _startTime = System.currentTimeMillis(); _totalTimeoutTime = -1; schedule(delay); } public void timeReached() { if (_cancelled) return; if ( ( (_totalTimeoutTime > 0) && (_totalTimeoutTime <= System.currentTimeMillis()) ) || (_inactivityDelay + _lastActivity <= System.currentTimeMillis()) ) { if (_targetSocket != null) { try { if (!_targetSocket.isClosed()) _targetSocket.close(); } catch (IOException ioe) {} } if (_command != null) _command.run(); } else { schedule(_inactivityDelay); } } /** * Change in return value from void to boolean in * 0.9.3 accidentally broke Syndie, sorry. * Recompile Syndie to fix it. */ public boolean cancel() { _cancelled = true; return super.cancel(); } public void setSocket(Socket s) { _targetSocket = s; } public void resetTimer() { _lastActivity = System.currentTimeMillis(); } public void setInactivityTimeout(long timeout) { _inactivityDelay = timeout; } public void setTotalTimeoutPeriod(long timeoutPeriod) { if (timeoutPeriod > 0) _totalTimeoutTime = _startTime + timeoutPeriod; else _totalTimeoutTime = -1; } public void setTimeoutCommand(Runnable job) { _command = job; } private static final SimpleDateFormat _fmt = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss.SSS"); private static String ts(long when) { synchronized (_fmt) { return _fmt.format(new Date(when)); } } @Override public String toString() { StringBuilder buf = new StringBuilder(); buf.append("SocketTimeout started on "); buf.append(ts(_startTime)); buf.append(" idle for "); buf.append(System.currentTimeMillis() - _lastActivity); buf.append("ms "); if (_totalTimeoutTime > 0) buf.append("total timeout at ").append(ts(_totalTimeoutTime)); buf.append("cancelled? ").append(_cancelled); return buf.toString(); } }