From 93df048bd671185fd394f56800c1f382997bd035 Mon Sep 17 00:00:00 2001 From: zab2 Date: Fri, 5 Jul 2013 11:54:18 +0000 Subject: [PATCH] Cleanups, make I2PSocket a Closeable --- .../net/i2p/client/streaming/I2PSocket.java | 9 ++---- .../streaming/I2PSocketManagerFull.java | 29 ++++++++++++++----- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocket.java b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocket.java index 0d2b5d0f0..5efe7e86b 100644 --- a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocket.java +++ b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocket.java @@ -1,5 +1,6 @@ package net.i2p.client.streaming; +import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -12,7 +13,7 @@ import net.i2p.data.Destination; * Note that this interface is a "subinterface" of the interface * defined in the "official" streaming api. */ -public interface I2PSocket { +public interface I2PSocket extends Closeable { /** * @return the Destination of this side of the socket. */ @@ -67,12 +68,6 @@ public interface I2PSocket { */ public void setReadTimeout(long ms); - /** - * Closes the socket if not closed yet - * @throws IOException on failure - */ - public void close() throws IOException; - public boolean isClosed(); public void setSocketErrorListener(SocketErrorListener lsnr); diff --git a/apps/streaming/java/src/net/i2p/client/streaming/I2PSocketManagerFull.java b/apps/streaming/java/src/net/i2p/client/streaming/I2PSocketManagerFull.java index 2e65bd0ae..83f170d84 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/I2PSocketManagerFull.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/I2PSocketManagerFull.java @@ -8,6 +8,8 @@ import java.net.SocketTimeoutException; import java.util.HashSet; import java.util.Properties; import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; import net.i2p.I2PAppContext; import net.i2p.I2PException; @@ -36,9 +38,9 @@ public class I2PSocketManagerFull implements I2PSocketManager { private final ConnectionOptions _defaultOptions; private long _acceptTimeout; private String _name; - private static int __managerId = 0; + private static final AtomicInteger __managerId = new AtomicInteger(0); private final ConnectionManager _connectionManager; - private volatile boolean _isDestroyed; + private final AtomicBoolean _isDestroyed = new AtomicBoolean(false); /** * How long to wait for the client app to accept() before sending back CLOSE? @@ -76,7 +78,7 @@ public class I2PSocketManagerFull implements I2PSocketManager { _session = session; _log = _context.logManager().getLog(I2PSocketManagerFull.class); - _name = name + " " + (++__managerId); + _name = name + " " + (__managerId.incrementAndGet()); _acceptTimeout = ACCEPT_TIMEOUT_DEFAULT; _defaultOptions = new ConnectionOptions(opts); _connectionManager = new ConnectionManager(_context, _session, _defaultOptions); @@ -201,7 +203,7 @@ public class I2PSocketManagerFull implements I2PSocketManager { } private void verifySession() throws I2PException { - if (_isDestroyed) + if (_isDestroyed.get()) throw new I2PException("destroyed"); if (!_connectionManager.getSession().isClosed()) return; @@ -312,7 +314,14 @@ public class I2PSocketManagerFull implements I2PSocketManager { * CANNOT be restarted. */ public void destroySocketManager() { - _isDestroyed = true; + if (!_isDestroyed.compareAndSet(false,true)) { + // shouldn't happen, log a stack trace to find out why it happened + if (_log.shouldLog(Log.WARN)) { + String log = "over-destroying manager "+getName(); + _log.log(Log.WARN,log,new Exception("check stack trace")); + } + return; + } _connectionManager.setAllowIncomingConnections(false); _connectionManager.shutdown(); // should we destroy the _session too? @@ -323,8 +332,12 @@ public class I2PSocketManagerFull implements I2PSocketManager { } catch (I2PSessionException ise) { _log.warn("Unable to destroy the session", ise); } - if (pcapWriter != null) - pcapWriter.flush(); + PcapWriter pcap = null; + synchronized(_pcapInitLock) { + pcap = pcapWriter; + } + if (pcap != null) + pcap.flush(); } } @@ -335,7 +348,7 @@ public class I2PSocketManagerFull implements I2PSocketManager { */ public Set listSockets() { Set connections = _connectionManager.listConnections(); - Set rv = new HashSet(connections.size()); + Set rv = new HashSet(connections.size()); for (Connection con : connections) { if (con.getSocket() != null) rv.add(con.getSocket());