merge of '40606168f4086dbe122e96b533df4f24b5e4d87d'
and '44a775450f24ec5d2e921ab01b94546968f81851'
This commit is contained in:
@ -30,6 +30,37 @@ public interface I2PServerSocket {
|
||||
*/
|
||||
public I2PSocket accept() throws I2PException, ConnectException, SocketTimeoutException;
|
||||
|
||||
/**
|
||||
* accept(timeout) waits timeout ms for a socket connecting. If a socket is
|
||||
* not available during the timeout, return null. accept(0) behaves like accept()
|
||||
*
|
||||
* @param timeout in ms
|
||||
*
|
||||
* @return a connected I2PSocket, or null
|
||||
*
|
||||
* @throws I2PException if there is a problem with reading a new socket
|
||||
* from the data available (aka the I2PSession closed, etc)
|
||||
* @throws ConnectException if the I2PServerSocket is closed
|
||||
* @throws InterruptedException if thread is interrupted while waiting
|
||||
*/
|
||||
public I2PSocket accept(long timeout) throws I2PException, ConnectException, InterruptedException;
|
||||
|
||||
/**
|
||||
* Wait until there is a socket waiting for acception or the timeout is
|
||||
* reached.
|
||||
*
|
||||
* @param timeoutMs timeout in ms. If ms is 0, wait forever.
|
||||
*
|
||||
* @return true if a socket is available, false if not
|
||||
*
|
||||
* @throws I2PException if there is a problem with reading a new socket
|
||||
* from the data available (aka the I2PSession closed, etc)
|
||||
* @throws ConnectException if the I2PServerSocket is closed
|
||||
* @throws InterruptedException if the thread is interrupted before
|
||||
* completion
|
||||
*/
|
||||
public void waitIncoming(long timeoutMs) throws I2PException, ConnectException, InterruptedException;
|
||||
|
||||
/**
|
||||
* Set Sock Option accept timeout
|
||||
* @param x timeout in ms
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.i2p.client.streaming;
|
||||
|
||||
import java.net.ConnectException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -20,7 +21,7 @@ class I2PServerSocketImpl implements I2PServerSocket {
|
||||
private final static Log _log = new Log(I2PServerSocketImpl.class);
|
||||
private I2PSocketManager mgr;
|
||||
/** list of sockets waiting for the client to accept them */
|
||||
private List pendingSockets = Collections.synchronizedList(new ArrayList(4));
|
||||
private List<I2PSocket> pendingSockets = Collections.synchronizedList(new ArrayList<I2PSocket>(4));
|
||||
|
||||
/** have we been closed */
|
||||
private volatile boolean closing = false;
|
||||
@ -50,6 +51,82 @@ class I2PServerSocketImpl implements I2PServerSocket {
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits until there is a socket waiting for acception or the timeout is
|
||||
* reached.
|
||||
*
|
||||
* @param timeoutMs timeout in ms. A negative value waits forever.
|
||||
*
|
||||
* @throws I2PException if there is a problem with reading a new socket
|
||||
* from the data available (aka the I2PSession closed, etc)
|
||||
* @throws ConnectException if the I2PServerSocket is closed
|
||||
* @throws InterruptedException if thread is interrupted while waiting
|
||||
*/
|
||||
public void waitIncoming(long timeoutMs) throws I2PException, ConnectException, InterruptedException {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("waitIncoming() called, pending: " + pendingSockets.size());
|
||||
|
||||
boolean isTimed = (timeoutMs>0);
|
||||
if (isTimed) {
|
||||
Clock clock = I2PAppContext.getGlobalContext().clock();
|
||||
long now = clock.now();
|
||||
long end = now + timeoutMs;
|
||||
while (pendingSockets.size() <= 0 && now<end) {
|
||||
if (closing) throw new ConnectException("I2PServerSocket closed");
|
||||
synchronized(socketAddedLock) {
|
||||
socketAddedLock.wait(end - now);
|
||||
}
|
||||
now = clock.now();
|
||||
}
|
||||
} else {
|
||||
while (pendingSockets.size() <= 0) {
|
||||
if (closing) throw new ConnectException("I2PServerSocket closed");
|
||||
try {
|
||||
synchronized(socketAddedLock) {
|
||||
socketAddedLock.wait();
|
||||
}
|
||||
} catch (InterruptedException ie) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* accept(timeout) waits timeout ms for a socket connecting. If a socket is
|
||||
* not available during the timeout, return null. accept(0) behaves like accept()
|
||||
*
|
||||
* @param timeout in ms
|
||||
*
|
||||
* @return a connected I2PSocket, or null
|
||||
*
|
||||
* @throws I2PException if there is a problem with reading a new socket
|
||||
* from the data available (aka the I2PSession closed, etc)
|
||||
* @throws ConnectException if the I2PServerSocket is closed
|
||||
* @throws InterruptedException if thread is interrupted while waiting
|
||||
*/
|
||||
public I2PSocket accept(long timeout) throws I2PException, ConnectException, InterruptedException {
|
||||
I2PSocket ret = null;
|
||||
|
||||
if (timeout<=0) {
|
||||
ret = accept();
|
||||
} else {
|
||||
long now = I2PAppContext.getGlobalContext().clock().now();
|
||||
long expiration = timeout + now ;
|
||||
synchronized (pendingSockets) {
|
||||
while (pendingSockets.size() == 0 && expiration>now) {
|
||||
pendingSockets.wait(expiration-now);
|
||||
now = I2PAppContext.getGlobalContext().clock().now();
|
||||
}
|
||||
ret = (I2PSocket)pendingSockets.remove(0);
|
||||
}
|
||||
if (ret != null) {
|
||||
synchronized (socketAcceptedLock) {
|
||||
socketAcceptedLock.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the next socket connecting. If a remote user tried to make a
|
||||
* connection and the local application wasn't .accept()ing new connections,
|
||||
* they should get refused (if .accept() doesnt occur in some small period -
|
||||
@ -68,24 +145,12 @@ class I2PServerSocketImpl implements I2PServerSocket {
|
||||
I2PSocket ret = null;
|
||||
|
||||
while ( (ret == null) && (!closing) ){
|
||||
while (pendingSockets.size() <= 0) {
|
||||
if (closing) throw new ConnectException("I2PServerSocket closed");
|
||||
try {
|
||||
synchronized(socketAddedLock) {
|
||||
socketAddedLock.wait();
|
||||
}
|
||||
} catch (InterruptedException ie) {}
|
||||
}
|
||||
synchronized (pendingSockets) {
|
||||
if (pendingSockets.size() > 0) {
|
||||
ret = (I2PSocket)pendingSockets.remove(0);
|
||||
}
|
||||
}
|
||||
if (ret != null) {
|
||||
synchronized (socketAcceptedLock) {
|
||||
socketAcceptedLock.notifyAll();
|
||||
}
|
||||
}
|
||||
try {
|
||||
this.waitIncoming(0);
|
||||
ret = accept(1);
|
||||
} catch (InterruptedException e) {
|
||||
throw new I2PException("Thread interrupted") ;
|
||||
}
|
||||
}
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
|
@ -350,7 +350,6 @@ class I2PSocketImpl implements I2PSocket {
|
||||
read = bc.startToByteArray(len);
|
||||
bc.notifyAll();
|
||||
}
|
||||
boolean timedOut = false;
|
||||
|
||||
while ( (read.length == 0) && (!inStreamClosed) ) {
|
||||
synchronized (flagLock) {
|
||||
|
@ -13,7 +13,6 @@ import net.i2p.client.I2PClient;
|
||||
import net.i2p.client.I2PClientFactory;
|
||||
import net.i2p.client.I2PSession;
|
||||
import net.i2p.client.I2PSessionException;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
|
@ -43,12 +43,12 @@ class I2PSocketManagerImpl implements I2PSocketManager, I2PSessionListener {
|
||||
private I2PSession _session;
|
||||
private I2PServerSocketImpl _serverSocket = null;
|
||||
private Object lock = new Object(); // for locking socket lists
|
||||
private HashMap _outSockets;
|
||||
private HashMap _inSockets;
|
||||
private HashMap<String,I2PSocket> _outSockets;
|
||||
private HashMap<String,I2PSocket> _inSockets;
|
||||
private I2PSocketOptions _defaultOptions;
|
||||
private long _acceptTimeout;
|
||||
private String _name;
|
||||
private List _listeners;
|
||||
private List<DisconnectListener> _listeners;
|
||||
private static int __managerId = 0;
|
||||
|
||||
public static final short ACK = 0x51;
|
||||
@ -76,10 +76,10 @@ class I2PSocketManagerImpl implements I2PSocketManager, I2PSessionListener {
|
||||
_name = name;
|
||||
_context = context;
|
||||
_log = _context.logManager().getLog(I2PSocketManager.class);
|
||||
_inSockets = new HashMap(16);
|
||||
_outSockets = new HashMap(16);
|
||||
_inSockets = new HashMap<String,I2PSocket>(16);
|
||||
_outSockets = new HashMap<String,I2PSocket>(16);
|
||||
_acceptTimeout = ACCEPT_TIMEOUT_DEFAULT;
|
||||
_listeners = new ArrayList(1);
|
||||
_listeners = new ArrayList<DisconnectListener>(1);
|
||||
setSession(session);
|
||||
setDefaultOptions(buildOptions(opts));
|
||||
_context.statManager().createRateStat("streaming.lifetime", "How long before the socket is closed?", "streaming", new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
|
||||
@ -113,9 +113,9 @@ class I2PSocketManagerImpl implements I2PSocketManager, I2PSessionListener {
|
||||
public void disconnected(I2PSession session) {
|
||||
_log.info(getName() + ": Disconnected from the session");
|
||||
destroySocketManager();
|
||||
List listeners = null;
|
||||
List<DisconnectListener> listeners = null;
|
||||
synchronized (_listeners) {
|
||||
listeners = new ArrayList(_listeners);
|
||||
listeners = new ArrayList<DisconnectListener>(_listeners);
|
||||
_listeners.clear();
|
||||
}
|
||||
for (int i = 0; i < listeners.size(); i++) {
|
||||
@ -130,7 +130,6 @@ class I2PSocketManagerImpl implements I2PSocketManager, I2PSessionListener {
|
||||
|
||||
public void messageAvailable(I2PSession session, int msgId, long size) {
|
||||
try {
|
||||
I2PSocketImpl s;
|
||||
byte msg[] = session.receiveMessage(msgId);
|
||||
if (msg.length == 1 && msg[0] == -1) {
|
||||
_log.debug(getName() + ": Ping received");
|
||||
@ -660,7 +659,7 @@ class I2PSocketManagerImpl implements I2PSocketManager, I2PSessionListener {
|
||||
*
|
||||
*/
|
||||
public Set listSockets() {
|
||||
Set sockets = new HashSet(8);
|
||||
Set<I2PSocket> sockets = new HashSet<I2PSocket>(8);
|
||||
synchronized (lock) {
|
||||
sockets.addAll(_inSockets.values());
|
||||
sockets.addAll(_outSockets.values());
|
||||
|
@ -28,6 +28,10 @@ public class TestSwarm {
|
||||
private String _conOptions; // unused? used elsewhere?
|
||||
private boolean _dead; // unused? used elsewhere?
|
||||
|
||||
public void antiCompilationWarnings() {
|
||||
_log.debug(""+_conOptions+_dead);
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
if (args.length < 1) {
|
||||
System.err.println("Usage: TestSwarm myDestFile [peerDestFile ]*");
|
||||
@ -131,6 +135,14 @@ public class TestSwarm {
|
||||
_context.statManager().createRateStat("swarm." + _connectionId + ".lifetime", "How long we talk to a peer", "swarm", new long[] { 5*60*1000 });
|
||||
}
|
||||
|
||||
public void antiCompilationWarnings() {
|
||||
_log.debug(""+this._lastReceived+this._lastReceivedOn+this._started);
|
||||
}
|
||||
public void antiCompilationWarnings(long x, long y) {
|
||||
if (false)
|
||||
_log.debug(""+x+y);
|
||||
}
|
||||
|
||||
public Flooder(I2PSocket socket) {
|
||||
_socket = socket;
|
||||
_remoteDestination = socket.getPeerDestination();
|
||||
@ -154,6 +166,8 @@ public class TestSwarm {
|
||||
_context.random().nextBytes(data);
|
||||
long value = 0;
|
||||
long lastSend = _context.clock().now();
|
||||
this.antiCompilationWarnings(value, lastSend);
|
||||
|
||||
if (_socket == null) {
|
||||
try {
|
||||
_socket = _manager.connect(_remoteDestination);
|
||||
|
Reference in New Issue
Block a user