I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit 2e8fd23f authored by zzz's avatar zzz
Browse files

concurrent

parent 3eef403b
No related branches found
No related tags found
No related merge requests found
...@@ -6,6 +6,7 @@ import java.util.Iterator; ...@@ -6,6 +6,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicLong;
import net.i2p.I2PAppContext; import net.i2p.I2PAppContext;
import net.i2p.client.I2PSession; import net.i2p.client.I2PSession;
...@@ -29,7 +30,7 @@ public class Connection { ...@@ -29,7 +30,7 @@ public class Connection {
private long _sendStreamId; private long _sendStreamId;
private long _receiveStreamId; private long _receiveStreamId;
private long _lastSendTime; private long _lastSendTime;
private long _lastSendId; private AtomicLong _lastSendId;
private boolean _resetReceived; private boolean _resetReceived;
private boolean _resetSent; private boolean _resetSent;
private long _resetSentOn; private long _resetSentOn;
...@@ -49,7 +50,7 @@ public class Connection { ...@@ -49,7 +50,7 @@ public class Connection {
private boolean _isInbound; private boolean _isInbound;
private boolean _updatedShareOpts; private boolean _updatedShareOpts;
/** Packet ID (Long) to PacketLocal for sent but unacked packets */ /** Packet ID (Long) to PacketLocal for sent but unacked packets */
private final Map _outboundPackets; private final Map<Long, PacketLocal> _outboundPackets;
private PacketQueue _outboundQueue; private PacketQueue _outboundQueue;
private ConnectionPacketHandler _handler; private ConnectionPacketHandler _handler;
private ConnectionOptions _options; private ConnectionOptions _options;
...@@ -102,7 +103,7 @@ public class Connection { ...@@ -102,7 +103,7 @@ public class Connection {
_options = (opts != null ? opts : new ConnectionOptions()); _options = (opts != null ? opts : new ConnectionOptions());
_outputStream.setWriteTimeout((int)_options.getWriteTimeout()); _outputStream.setWriteTimeout((int)_options.getWriteTimeout());
_inputStream.setReadTimeout((int)_options.getReadTimeout()); _inputStream.setReadTimeout((int)_options.getReadTimeout());
_lastSendId = -1; _lastSendId = new AtomicLong(-1);
_nextSendTime = -1; _nextSendTime = -1;
_ackedPackets = 0; _ackedPackets = 0;
_createdOn = _context.clock().now(); _createdOn = _context.clock().now();
...@@ -137,9 +138,7 @@ public class Connection { ...@@ -137,9 +138,7 @@ public class Connection {
} }
public long getNextOutboundPacketNum() { public long getNextOutboundPacketNum() {
synchronized (this) { return _lastSendId.incrementAndGet();
return ++_lastSendId;
}
} }
void closeReceived() { void closeReceived() {
...@@ -175,7 +174,7 @@ public class Connection { ...@@ -175,7 +174,7 @@ public class Connection {
return false; return false;
started = true; started = true;
if ( (_outboundPackets.size() >= _options.getWindowSize()) || (_activeResends > 0) || if ( (_outboundPackets.size() >= _options.getWindowSize()) || (_activeResends > 0) ||
(_lastSendId - _highestAckedThrough > _options.getWindowSize()) ) { (_lastSendId.get() - _highestAckedThrough > _options.getWindowSize()) ) {
if (timeoutMs > 0) { if (timeoutMs > 0) {
if (timeLeft <= 0) { if (timeLeft <= 0) {
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
...@@ -211,10 +210,10 @@ public class Connection { ...@@ -211,10 +210,10 @@ public class Connection {
void ackImmediately() { void ackImmediately() {
PacketLocal packet = null; PacketLocal packet = null;
synchronized (_outboundPackets) { synchronized (_outboundPackets) {
if (_outboundPackets.size() > 0) { if (!_outboundPackets.isEmpty()) {
// ordered, so pick the lowest to retransmit // ordered, so pick the lowest to retransmit
Iterator iter = _outboundPackets.values().iterator(); Iterator<PacketLocal> iter = _outboundPackets.values().iterator();
packet = (PacketLocal)iter.next(); packet = iter.next();
//iter.remove(); //iter.remove();
} }
} }
...@@ -403,10 +402,10 @@ public class Connection { ...@@ -403,10 +402,10 @@ public class Connection {
} }
} }
List acked = null; List<PacketLocal> acked = null;
synchronized (_outboundPackets) { synchronized (_outboundPackets) {
for (Iterator iter = _outboundPackets.keySet().iterator(); iter.hasNext(); ) { for (Iterator<Long> iter = _outboundPackets.keySet().iterator(); iter.hasNext(); ) {
Long id = (Long)iter.next(); Long id = iter.next();
if (id.longValue() <= ackThrough) { if (id.longValue() <= ackThrough) {
boolean nacked = false; boolean nacked = false;
if (nacks != null) { if (nacks != null) {
...@@ -414,7 +413,7 @@ public class Connection { ...@@ -414,7 +413,7 @@ public class Connection {
for (int i = 0; i < nacks.length; i++) { for (int i = 0; i < nacks.length; i++) {
if (nacks[i] == id.longValue()) { if (nacks[i] == id.longValue()) {
nacked = true; nacked = true;
PacketLocal nackedPacket = (PacketLocal)_outboundPackets.get(id); PacketLocal nackedPacket = _outboundPackets.get(id);
nackedPacket.incrementNACKs(); nackedPacket.incrementNACKs();
break; // NACKed break; // NACKed
} }
...@@ -423,7 +422,7 @@ public class Connection { ...@@ -423,7 +422,7 @@ public class Connection {
if (!nacked) { // aka ACKed if (!nacked) { // aka ACKed
if (acked == null) if (acked == null)
acked = new ArrayList(1); acked = new ArrayList(1);
PacketLocal ackedPacket = (PacketLocal)_outboundPackets.get(id); PacketLocal ackedPacket = _outboundPackets.get(id);
ackedPacket.ackReceived(); ackedPacket.ackReceived();
acked.add(ackedPacket); acked.add(ackedPacket);
} }
...@@ -433,7 +432,7 @@ public class Connection { ...@@ -433,7 +432,7 @@ public class Connection {
} }
if (acked != null) { if (acked != null) {
for (int i = 0; i < acked.size(); i++) { for (int i = 0; i < acked.size(); i++) {
PacketLocal p = (PacketLocal)acked.get(i); PacketLocal p = acked.get(i);
_outboundPackets.remove(new Long(p.getSequenceNum())); _outboundPackets.remove(new Long(p.getSequenceNum()));
_ackedPackets++; _ackedPackets++;
if (p.getNumSends() > 1) { if (p.getNumSends() > 1) {
...@@ -443,7 +442,7 @@ public class Connection { ...@@ -443,7 +442,7 @@ public class Connection {
} }
} }
} }
if ( (_outboundPackets.size() <= 0) && (_activeResends != 0) ) { if ( (_outboundPackets.isEmpty()) && (_activeResends != 0) ) {
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info("All outbound packets acked, clearing " + _activeResends); _log.info("All outbound packets acked, clearing " + _activeResends);
_activeResends = 0; _activeResends = 0;
...@@ -570,8 +569,8 @@ public class Connection { ...@@ -570,8 +569,8 @@ public class Connection {
private void killOutstandingPackets() { private void killOutstandingPackets() {
//boolean tagsCancelled = false; //boolean tagsCancelled = false;
synchronized (_outboundPackets) { synchronized (_outboundPackets) {
for (Iterator iter = _outboundPackets.values().iterator(); iter.hasNext(); ) { for (Iterator<PacketLocal> iter = _outboundPackets.values().iterator(); iter.hasNext(); ) {
PacketLocal pl = (PacketLocal)iter.next(); PacketLocal pl = iter.next();
//if ( (pl.getTagsSent() != null) && (pl.getTagsSent().size() > 0) ) //if ( (pl.getTagsSent() != null) && (pl.getTagsSent().size() > 0) )
// tagsCancelled = true; // tagsCancelled = true;
pl.cancelled(); pl.cancelled();
...@@ -652,11 +651,11 @@ public class Connection { ...@@ -652,11 +651,11 @@ public class Connection {
/** What was the last packet Id sent to the peer? /** What was the last packet Id sent to the peer?
* @return The last sent packet ID * @return The last sent packet ID
*/ */
public long getLastSendId() { return _lastSendId; } public long getLastSendId() { return _lastSendId.get(); }
/** Set the packet Id that was sent to a peer. /** Set the packet Id that was sent to a peer.
* @param id The packet ID * @param id The packet ID
*/ */
public void setLastSendId(long id) { _lastSendId = id; } public void setLastSendId(long id) { _lastSendId.set(id); }
/** /**
* Retrieve the current ConnectionOptions. * Retrieve the current ConnectionOptions.
...@@ -783,7 +782,7 @@ public class Connection { ...@@ -783,7 +782,7 @@ public class Connection {
if (_ackSinceCongestion) { if (_ackSinceCongestion) {
_lastCongestionSeenAt = _options.getWindowSize(); _lastCongestionSeenAt = _options.getWindowSize();
_lastCongestionTime = _context.clock().now(); _lastCongestionTime = _context.clock().now();
_lastCongestionHighestUnacked = _lastSendId; _lastCongestionHighestUnacked = _lastSendId.get();
_ackSinceCongestion = false; _ackSinceCongestion = false;
} }
} }
...@@ -1022,7 +1021,7 @@ public class Connection { ...@@ -1022,7 +1021,7 @@ public class Connection {
} }
if (getCloseReceivedOn() > 0) if (getCloseReceivedOn() > 0)
buf.append(" close received ").append(DataHelper.formatDuration(_context.clock().now() - getCloseReceivedOn())).append(" ago"); buf.append(" close received ").append(DataHelper.formatDuration(_context.clock().now() - getCloseReceivedOn())).append(" ago");
buf.append(" sent: ").append(1 + _lastSendId); buf.append(" sent: ").append(1 + _lastSendId.get());
if (_inputStream != null) if (_inputStream != null)
buf.append(" rcvd: ").append(1 + _inputStream.getHighestBlockId() - missing); buf.append(" rcvd: ").append(1 + _inputStream.getHighestBlockId() - missing);
......
package net.i2p.client.streaming; package net.i2p.client.streaming;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import net.i2p.I2PAppContext; import net.i2p.I2PAppContext;
import net.i2p.I2PException; import net.i2p.I2PException;
...@@ -32,14 +32,13 @@ public class ConnectionManager { ...@@ -32,14 +32,13 @@ public class ConnectionManager {
private ConnectionPacketHandler _conPacketHandler; private ConnectionPacketHandler _conPacketHandler;
private TCBShare _tcbShare; private TCBShare _tcbShare;
/** Inbound stream ID (Long) to Connection map */ /** Inbound stream ID (Long) to Connection map */
private Map _connectionByInboundId; private ConcurrentHashMap<Long, Connection> _connectionByInboundId;
/** Ping ID (Long) to PingRequest */ /** Ping ID (Long) to PingRequest */
private final Map _pendingPings; private final Map<Long, PingRequest> _pendingPings;
private boolean _allowIncoming; private boolean _allowIncoming;
private int _maxConcurrentStreams; private int _maxConcurrentStreams;
private ConnectionOptions _defaultOptions; private ConnectionOptions _defaultOptions;
private volatile int _numWaiting; private volatile int _numWaiting;
private final Object _connectionLock;
private long SoTimeout; private long SoTimeout;
public ConnectionManager(I2PAppContext context, I2PSession session, int maxConcurrent, ConnectionOptions defaultOptions) { public ConnectionManager(I2PAppContext context, I2PSession session, int maxConcurrent, ConnectionOptions defaultOptions) {
...@@ -48,9 +47,8 @@ public class ConnectionManager { ...@@ -48,9 +47,8 @@ public class ConnectionManager {
_maxConcurrentStreams = maxConcurrent; _maxConcurrentStreams = maxConcurrent;
_defaultOptions = defaultOptions; _defaultOptions = defaultOptions;
_log = _context.logManager().getLog(ConnectionManager.class); _log = _context.logManager().getLog(ConnectionManager.class);
_connectionByInboundId = new HashMap(32); _connectionByInboundId = new ConcurrentHashMap(32);
_pendingPings = new HashMap(4); _pendingPings = new ConcurrentHashMap(4);
_connectionLock = new Object();
_messageHandler = new MessageHandler(_context, this); _messageHandler = new MessageHandler(_context, this);
_packetHandler = new PacketHandler(_context, this); _packetHandler = new PacketHandler(_context, this);
_connectionHandler = new ConnectionHandler(_context, this); _connectionHandler = new ConnectionHandler(_context, this);
...@@ -77,22 +75,17 @@ public class ConnectionManager { ...@@ -77,22 +75,17 @@ public class ConnectionManager {
} }
Connection getConnectionByInboundId(long id) { Connection getConnectionByInboundId(long id) {
synchronized (_connectionLock) { return _connectionByInboundId.get(Long.valueOf(id));
return (Connection)_connectionByInboundId.get(new Long(id));
}
} }
/** /**
* not guaranteed to be unique, but in case we receive more than one packet * not guaranteed to be unique, but in case we receive more than one packet
* on an inbound connection that we havent ack'ed yet... * on an inbound connection that we havent ack'ed yet...
*/ */
Connection getConnectionByOutboundId(long id) { Connection getConnectionByOutboundId(long id) {
synchronized (_connectionLock) { for (Connection con : _connectionByInboundId.values()) {
for (Iterator iter = _connectionByInboundId.values().iterator(); iter.hasNext(); ) {
Connection con = (Connection)iter.next();
if (DataHelper.eq(con.getSendStreamId(), id)) if (DataHelper.eq(con.getSendStreamId(), id))
return con; return con;
} }
}
return null; return null;
} }
...@@ -135,27 +128,26 @@ public class ConnectionManager { ...@@ -135,27 +128,26 @@ public class ConnectionManager {
boolean reject = false; boolean reject = false;
int active = 0; int active = 0;
int total = 0; int total = 0;
synchronized (_connectionLock) {
total = _connectionByInboundId.size(); // just for the stat
for (Iterator iter = _connectionByInboundId.values().iterator(); iter.hasNext(); ) { //total = _connectionByInboundId.size();
if ( ((Connection)iter.next()).getIsConnected() ) //for (Iterator iter = _connectionByInboundId.values().iterator(); iter.hasNext(); ) {
active++; // if ( ((Connection)iter.next()).getIsConnected() )
} // active++;
//}
if (locked_tooManyStreams()) { if (locked_tooManyStreams()) {
reject = true; reject = true;
} else { } else {
while (true) { while (true) {
Connection oldCon = (Connection)_connectionByInboundId.put(new Long(receiveId), con); Connection oldCon = _connectionByInboundId.putIfAbsent(Long.valueOf(receiveId), con);
if (oldCon == null) { if (oldCon == null) {
break; break;
} else { } else {
_connectionByInboundId.put(new Long(receiveId), oldCon);
// receiveId already taken, try another // receiveId already taken, try another
receiveId = _context.random().nextLong(Packet.MAX_STREAM_ID-1)+1; receiveId = _context.random().nextLong(Packet.MAX_STREAM_ID-1)+1;
} }
} }
} }
}
_context.statManager().addRateData("stream.receiveActive", active, total); _context.statManager().addRateData("stream.receiveActive", active, total);
...@@ -179,9 +171,7 @@ public class ConnectionManager { ...@@ -179,9 +171,7 @@ public class ConnectionManager {
try { try {
con.getPacketHandler().receivePacket(synPacket, con); con.getPacketHandler().receivePacket(synPacket, con);
} catch (I2PException ie) { } catch (I2PException ie) {
synchronized (_connectionLock) { _connectionByInboundId.remove(Long.valueOf(receiveId));
_connectionByInboundId.remove(new Long(receiveId));
}
return null; return null;
} }
...@@ -215,8 +205,7 @@ public class ConnectionManager { ...@@ -215,8 +205,7 @@ public class ConnectionManager {
_numWaiting--; _numWaiting--;
return null; return null;
} }
boolean reject = false;
synchronized (_connectionLock) {
if (locked_tooManyStreams()) { if (locked_tooManyStreams()) {
// allow a full buffer of pending/waiting streams // allow a full buffer of pending/waiting streams
if (_numWaiting > _maxConcurrentStreams) { if (_numWaiting > _maxConcurrentStreams) {
...@@ -227,27 +216,30 @@ public class ConnectionManager { ...@@ -227,27 +216,30 @@ public class ConnectionManager {
_numWaiting--; _numWaiting--;
return null; return null;
} }
// no remaining streams, lets wait a bit // no remaining streams, lets wait a bit
try { _connectionLock.wait(remaining); } catch (InterruptedException ie) {} // got rid of the lock, so just sleep (fixme?)
// try { _connectionLock.wait(remaining); } catch (InterruptedException ie) {}
try { Thread.sleep(remaining/4); } catch (InterruptedException ie) {}
} else { } else {
con = new Connection(_context, this, _schedulerChooser, _outboundQueue, _conPacketHandler, opts); con = new Connection(_context, this, _schedulerChooser, _outboundQueue, _conPacketHandler, opts);
con.setRemotePeer(peer); con.setRemotePeer(peer);
while (_connectionByInboundId.containsKey(new Long(receiveId))) { while (_connectionByInboundId.containsKey(Long.valueOf(receiveId))) {
receiveId = _context.random().nextLong(Packet.MAX_STREAM_ID-1)+1; receiveId = _context.random().nextLong(Packet.MAX_STREAM_ID-1)+1;
} }
_connectionByInboundId.put(new Long(receiveId), con); _connectionByInboundId.put(Long.valueOf(receiveId), con);
break; // stop looping as a psuedo-wait break; // stop looping as a psuedo-wait
} }
}
} }
// ok we're in... // ok we're in...
con.setReceiveStreamId(receiveId); con.setReceiveStreamId(receiveId);
con.eventOccurred(); con.eventOccurred();
_log.debug("Connect() conDelay = " + opts.getConnectDelay()); if (_log.shouldLog(Log.DEBUG))
_log.debug("Connect() conDelay = " + opts.getConnectDelay());
if (opts.getConnectDelay() <= 0) { if (opts.getConnectDelay() <= 0) {
con.waitForConnect(); con.waitForConnect();
} }
...@@ -258,12 +250,15 @@ public class ConnectionManager { ...@@ -258,12 +250,15 @@ public class ConnectionManager {
return con; return con;
} }
/**
* Doesn't need to be locked any more
* @return too many
*/
private boolean locked_tooManyStreams() { private boolean locked_tooManyStreams() {
if (_maxConcurrentStreams <= 0) return false; if (_maxConcurrentStreams <= 0) return false;
if (_connectionByInboundId.size() < _maxConcurrentStreams) return false; if (_connectionByInboundId.size() < _maxConcurrentStreams) return false;
int active = 0; int active = 0;
for (Iterator iter = _connectionByInboundId.values().iterator(); iter.hasNext(); ) { for (Connection con : _connectionByInboundId.values()) {
Connection con = (Connection)iter.next();
if (con.getIsConnected()) if (con.getIsConnected())
active++; active++;
} }
...@@ -293,13 +288,10 @@ public class ConnectionManager { ...@@ -293,13 +288,10 @@ public class ConnectionManager {
* *
*/ */
public void disconnectAllHard() { public void disconnectAllHard() {
synchronized (_connectionLock) { for (Iterator<Connection> iter = _connectionByInboundId.values().iterator(); iter.hasNext(); ) {
for (Iterator iter = _connectionByInboundId.values().iterator(); iter.hasNext(); ) { Connection con = iter.next();
Connection con = (Connection)iter.next(); con.disconnect(false, false);
con.disconnect(false, false); iter.remove();
}
_connectionByInboundId.clear();
_connectionLock.notifyAll();
} }
_tcbShare.stop(); _tcbShare.stop();
} }
...@@ -310,17 +302,15 @@ public class ConnectionManager { ...@@ -310,17 +302,15 @@ public class ConnectionManager {
* @param con Connection to drop. * @param con Connection to drop.
*/ */
public void removeConnection(Connection con) { public void removeConnection(Connection con) {
boolean removed = false;
synchronized (_connectionLock) { Object o = _connectionByInboundId.remove(Long.valueOf(con.getReceiveStreamId()));
Object o = _connectionByInboundId.remove(new Long(con.getReceiveStreamId())); boolean removed = (o == con);
removed = (o == con);
if (_log.shouldLog(Log.DEBUG)) if (_log.shouldLog(Log.DEBUG))
_log.debug("Connection removed? " + removed + " remaining: " _log.debug("Connection removed? " + removed + " remaining: "
+ _connectionByInboundId.size() + ": " + con); + _connectionByInboundId.size() + ": " + con);
if (!removed && _log.shouldLog(Log.DEBUG)) if (!removed && _log.shouldLog(Log.DEBUG))
_log.debug("Failed to remove " + con +"\n" + _connectionByInboundId.values()); _log.debug("Failed to remove " + con +"\n" + _connectionByInboundId.values());
_connectionLock.notifyAll();
}
if (removed) { if (removed) {
_context.statManager().addRateData("stream.con.lifetimeMessagesSent", 1+con.getLastSendId(), con.getLifetime()); _context.statManager().addRateData("stream.con.lifetimeMessagesSent", 1+con.getLastSendId(), con.getLifetime());
MessageInputStream stream = con.getInputStream(); MessageInputStream stream = con.getInputStream();
...@@ -344,10 +334,8 @@ public class ConnectionManager { ...@@ -344,10 +334,8 @@ public class ConnectionManager {
/** return a set of Connection objects /** return a set of Connection objects
* @return set of Connection objects * @return set of Connection objects
*/ */
public Set listConnections() { public Set<Connection> listConnections() {
synchronized (_connectionLock) {
return new HashSet(_connectionByInboundId.values()); return new HashSet(_connectionByInboundId.values());
}
} }
/** blocking */ /** blocking */
...@@ -368,7 +356,7 @@ public class ConnectionManager { ...@@ -368,7 +356,7 @@ public class ConnectionManager {
} }
public boolean ping(Destination peer, long timeoutMs, boolean blocking, PingNotifier notifier) { public boolean ping(Destination peer, long timeoutMs, boolean blocking, PingNotifier notifier) {
Long id = new Long(_context.random().nextLong(Packet.MAX_STREAM_ID-1)+1); Long id = Long.valueOf(_context.random().nextLong(Packet.MAX_STREAM_ID-1)+1);
PacketLocal packet = new PacketLocal(_context, peer); PacketLocal packet = new PacketLocal(_context, peer);
packet.setSendStreamId(id.longValue()); packet.setSendStreamId(id.longValue());
packet.setFlag(Packet.FLAG_ECHO); packet.setFlag(Packet.FLAG_ECHO);
...@@ -381,9 +369,7 @@ public class ConnectionManager { ...@@ -381,9 +369,7 @@ public class ConnectionManager {
PingRequest req = new PingRequest(peer, packet, notifier); PingRequest req = new PingRequest(peer, packet, notifier);
synchronized (_pendingPings) { _pendingPings.put(id, req);
_pendingPings.put(id, req);
}
_outboundQueue.enqueue(packet); _outboundQueue.enqueue(packet);
packet.releasePayload(); packet.releasePayload();
...@@ -393,10 +379,7 @@ public class ConnectionManager { ...@@ -393,10 +379,7 @@ public class ConnectionManager {
if (!req.pongReceived()) if (!req.pongReceived())
try { req.wait(timeoutMs); } catch (InterruptedException ie) {} try { req.wait(timeoutMs); } catch (InterruptedException ie) {}
} }
_pendingPings.remove(id);
synchronized (_pendingPings) {
_pendingPings.remove(id);
}
} else { } else {
SimpleTimer.getInstance().addEvent(new PingFailed(id, notifier), timeoutMs); SimpleTimer.getInstance().addEvent(new PingFailed(id, notifier), timeoutMs);
} }
...@@ -418,13 +401,8 @@ public class ConnectionManager { ...@@ -418,13 +401,8 @@ public class ConnectionManager {
} }
public void timeReached() { public void timeReached() {
boolean removed = false; PingRequest pr = _pendingPings.remove(_id);
synchronized (_pendingPings) { if (pr != null) {
Object o = _pendingPings.remove(_id);
if (o != null)
removed = true;
}
if (removed) {
if (_notifier != null) if (_notifier != null)
_notifier.pingComplete(false); _notifier.pingComplete(false);
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
...@@ -433,7 +411,7 @@ public class ConnectionManager { ...@@ -433,7 +411,7 @@ public class ConnectionManager {
} }
} }
private class PingRequest { private static class PingRequest {
private boolean _ponged; private boolean _ponged;
private Destination _peer; private Destination _peer;
private PacketLocal _packet; private PacketLocal _packet;
...@@ -445,7 +423,8 @@ public class ConnectionManager { ...@@ -445,7 +423,8 @@ public class ConnectionManager {
_notifier = notifier; _notifier = notifier;
} }
public void pong() { public void pong() {
_log.debug("Ping successful"); // static, no log
//_log.debug("Ping successful");
//_context.sessionKeyManager().tagsDelivered(_peer.getPublicKey(), _packet.getKeyUsed(), _packet.getTagsSent()); //_context.sessionKeyManager().tagsDelivered(_peer.getPublicKey(), _packet.getKeyUsed(), _packet.getTagsSent());
synchronized (ConnectionManager.PingRequest.this) { synchronized (ConnectionManager.PingRequest.this) {
_ponged = true; _ponged = true;
...@@ -458,10 +437,7 @@ public class ConnectionManager { ...@@ -458,10 +437,7 @@ public class ConnectionManager {
} }
void receivePong(long pingId) { void receivePong(long pingId) {
PingRequest req = null; PingRequest req = _pendingPings.remove(Long.valueOf(pingId));
synchronized (_pendingPings) {
req = (PingRequest)_pendingPings.remove(new Long(pingId));
}
if (req != null) if (req != null)
req.pong(); req.pong();
} }
......
package net.i2p.client.streaming; package net.i2p.client.streaming;
import java.util.ArrayList; import java.util.Iterator;
import java.util.List; import java.util.Set;
import net.i2p.I2PAppContext; import net.i2p.I2PAppContext;
import net.i2p.client.I2PSession; import net.i2p.client.I2PSession;
import net.i2p.client.I2PSessionException; import net.i2p.client.I2PSessionException;
import net.i2p.client.I2PSessionListener; import net.i2p.client.I2PSessionListener;
import net.i2p.util.Log; import net.i2p.util.Log;
import net.i2p.util.ConcurrentHashSet;
/** /**
* Receive raw information from the I2PSession and turn it into * Receive raw information from the I2PSession and turn it into
...@@ -18,12 +19,12 @@ public class MessageHandler implements I2PSessionListener { ...@@ -18,12 +19,12 @@ public class MessageHandler implements I2PSessionListener {
private ConnectionManager _manager; private ConnectionManager _manager;
private I2PAppContext _context; private I2PAppContext _context;
private Log _log; private Log _log;
private final List _listeners; private final Set<I2PSocketManager.DisconnectListener> _listeners;
public MessageHandler(I2PAppContext ctx, ConnectionManager mgr) { public MessageHandler(I2PAppContext ctx, ConnectionManager mgr) {
_manager = mgr; _manager = mgr;
_context = ctx; _context = ctx;
_listeners = new ArrayList(1); _listeners = new ConcurrentHashSet(1);
_log = ctx.logManager().getLog(MessageHandler.class); _log = ctx.logManager().getLog(MessageHandler.class);
_context.statManager().createRateStat("stream.packetReceiveFailure", "When do we fail to decrypt or otherwise receive a packet sent to us?", "Stream", new long[] { 60*60*1000, 24*60*60*1000 }); _context.statManager().createRateStat("stream.packetReceiveFailure", "When do we fail to decrypt or otherwise receive a packet sent to us?", "Stream", new long[] { 60*60*1000, 24*60*60*1000 });
} }
...@@ -77,14 +78,10 @@ public class MessageHandler implements I2PSessionListener { ...@@ -77,14 +78,10 @@ public class MessageHandler implements I2PSessionListener {
_log.warn("I2PSession disconnected"); _log.warn("I2PSession disconnected");
_manager.disconnectAllHard(); _manager.disconnectAllHard();
List listeners = null; for (Iterator<I2PSocketManager.DisconnectListener> iter = _listeners.iterator(); iter.hasNext(); ) {
synchronized (_listeners) { I2PSocketManager.DisconnectListener lsnr = iter.next();
listeners = new ArrayList(_listeners);
_listeners.clear();
}
for (int i = 0; i < listeners.size(); i++) {
I2PSocketManager.DisconnectListener lsnr = (I2PSocketManager.DisconnectListener)listeners.get(i);
lsnr.sessionDisconnected(); lsnr.sessionDisconnected();
iter.remove();
} }
} }
...@@ -104,13 +101,9 @@ public class MessageHandler implements I2PSessionListener { ...@@ -104,13 +101,9 @@ public class MessageHandler implements I2PSessionListener {
} }
public void addDisconnectListener(I2PSocketManager.DisconnectListener lsnr) { public void addDisconnectListener(I2PSocketManager.DisconnectListener lsnr) {
synchronized (_listeners) {
_listeners.add(lsnr); _listeners.add(lsnr);
}
} }
public void removeDisconnectListener(I2PSocketManager.DisconnectListener lsnr) { public void removeDisconnectListener(I2PSocketManager.DisconnectListener lsnr) {
synchronized (_listeners) {
_listeners.remove(lsnr); _listeners.remove(lsnr);
}
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment