Merged IncomingConnectionExecutor and PluginExecutor into IoExecutor.

We don't need two separate executors for long-running IO threads.
This commit is contained in:
akwizgran
2014-10-02 18:02:53 +01:00
parent 458c0ca285
commit 941efb4bbe
35 changed files with 172 additions and 223 deletions

View File

@@ -10,7 +10,6 @@
<item>org.briarproject.messaging.duplex.DuplexMessagingModule</item>
<item>org.briarproject.messaging.simplex.SimplexMessagingModule</item>
<item>org.briarproject.plugins.AndroidPluginsModule</item>
<item>org.briarproject.plugins.PluginsModule</item>
<item>org.briarproject.serial.SerialModule</item>
<item>org.briarproject.system.AndroidSystemModule</item>
<item>org.briarproject.transport.TransportModule</item>

View File

@@ -30,8 +30,8 @@ public class SplashScreenActivity extends RoboSplashActivity {
private static final Logger LOG =
Logger.getLogger(SplashScreenActivity.class.getName());
// This build expires on 12 July 2014
private static final long EXPIRY_DATE = 1405123200 * 1000L;
// This build expires on 8 October 2014
private static final long EXPIRY_DATE = 1412726400 * 1000L;
private long now = System.currentTimeMillis();

View File

@@ -7,8 +7,8 @@ import java.util.concurrent.Executor;
import org.briarproject.api.android.AndroidExecutor;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.lifecycle.IoExecutor;
import org.briarproject.api.lifecycle.ShutdownManager;
import org.briarproject.api.plugins.PluginExecutor;
import org.briarproject.api.plugins.duplex.DuplexPluginConfig;
import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
import org.briarproject.api.plugins.simplex.SimplexPluginConfig;
@@ -21,12 +21,9 @@ import org.briarproject.plugins.tor.TorPluginFactory;
import android.app.Application;
import android.content.Context;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
public class AndroidPluginsModule extends AbstractModule {
protected void configure() {}
public class AndroidPluginsModule extends PluginsModule {
@Provides
SimplexPluginConfig getSimplexPluginConfig() {
@@ -38,19 +35,17 @@ public class AndroidPluginsModule extends AbstractModule {
}
@Provides
DuplexPluginConfig getDuplexPluginConfig(
@PluginExecutor Executor pluginExecutor,
DuplexPluginConfig getDuplexPluginConfig(@IoExecutor Executor ioExecutor,
AndroidExecutor androidExecutor, Application app,
CryptoComponent crypto, LocationUtils locationUtils,
ShutdownManager shutdownManager) {
Context appContext = app.getApplicationContext();
DuplexPluginFactory bluetooth = new DroidtoothPluginFactory(
pluginExecutor, androidExecutor, appContext,
crypto.getSecureRandom());
DuplexPluginFactory tor = new TorPluginFactory(pluginExecutor,
appContext, locationUtils, shutdownManager);
DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(
pluginExecutor, appContext);
DuplexPluginFactory bluetooth = new DroidtoothPluginFactory(ioExecutor,
androidExecutor, appContext, crypto.getSecureRandom());
DuplexPluginFactory tor = new TorPluginFactory(ioExecutor, appContext,
locationUtils, shutdownManager);
DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor,
appContext);
final Collection<DuplexPluginFactory> factories =
Arrays.asList(bluetooth, tor, lan);
return new DuplexPluginConfig() {

View File

@@ -63,7 +63,7 @@ class DroidtoothPlugin implements DuplexPlugin {
private static final String DISCOVERY_FINISHED =
"android.bluetooth.adapter.action.DISCOVERY_FINISHED";
private final Executor pluginExecutor;
private final Executor ioExecutor;
private final AndroidExecutor androidExecutor;
private final Context appContext;
private final SecureRandom secureRandom;
@@ -80,11 +80,11 @@ class DroidtoothPlugin implements DuplexPlugin {
// Non-null if the plugin started successfully
private volatile BluetoothAdapter adapter = null;
DroidtoothPlugin(Executor pluginExecutor, AndroidExecutor androidExecutor,
DroidtoothPlugin(Executor ioExecutor, AndroidExecutor androidExecutor,
Context appContext, SecureRandom secureRandom, Clock clock,
DuplexPluginCallback callback, int maxFrameLength, long maxLatency,
long pollingInterval) {
this.pluginExecutor = pluginExecutor;
this.ioExecutor = ioExecutor;
this.androidExecutor = androidExecutor;
this.appContext = appContext;
this.secureRandom = secureRandom;
@@ -147,7 +147,7 @@ class DroidtoothPlugin implements DuplexPlugin {
}
private void bind() {
pluginExecutor.execute(new Runnable() {
ioExecutor.execute(new Runnable() {
public void run() {
if(!isRunning()) return;
if(LOG.isLoggable(INFO))
@@ -256,7 +256,7 @@ class DroidtoothPlugin implements DuplexPlugin {
if(StringUtils.isNullOrEmpty(address)) continue;
final String uuid = e.getValue().get("uuid");
if(StringUtils.isNullOrEmpty(uuid)) continue;
pluginExecutor.execute(new Runnable() {
ioExecutor.execute(new Runnable() {
public void run() {
if(!running) return;
BluetoothSocket s = connect(address, uuid);

View File

@@ -19,16 +19,16 @@ public class DroidtoothPluginFactory implements DuplexPluginFactory {
private static final long MAX_LATENCY = 60 * 1000; // 1 minute
private static final long POLLING_INTERVAL = 3 * 60 * 1000; // 3 minutes
private final Executor pluginExecutor;
private final Executor ioExecutor;
private final AndroidExecutor androidExecutor;
private final Context appContext;
private final SecureRandom secureRandom;
private final Clock clock;
public DroidtoothPluginFactory(Executor pluginExecutor,
public DroidtoothPluginFactory(Executor ioExecutor,
AndroidExecutor androidExecutor, Context appContext,
SecureRandom secureRandom) {
this.pluginExecutor = pluginExecutor;
this.ioExecutor = ioExecutor;
this.androidExecutor = androidExecutor;
this.appContext = appContext;
this.secureRandom = secureRandom;
@@ -40,7 +40,7 @@ public class DroidtoothPluginFactory implements DuplexPluginFactory {
}
public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
return new DroidtoothPlugin(pluginExecutor, androidExecutor, appContext,
return new DroidtoothPlugin(ioExecutor, androidExecutor, appContext,
secureRandom, clock, callback, MAX_FRAME_LENGTH, MAX_LATENCY,
POLLING_INTERVAL);
}

View File

@@ -25,10 +25,10 @@ class AndroidLanTcpPlugin extends LanTcpPlugin {
private volatile BroadcastReceiver networkStateReceiver = null;
AndroidLanTcpPlugin(Executor pluginExecutor, Context appContext,
AndroidLanTcpPlugin(Executor ioExecutor, Context appContext,
DuplexPluginCallback callback, int maxFrameLength, long maxLatency,
long pollingInterval) {
super(pluginExecutor, callback, maxFrameLength, maxLatency,
super(ioExecutor, callback, maxFrameLength, maxLatency,
pollingInterval);
this.appContext = appContext;
}

View File

@@ -15,12 +15,11 @@ public class AndroidLanTcpPluginFactory implements DuplexPluginFactory {
private static final long MAX_LATENCY = 60 * 1000; // 1 minute
private static final long POLLING_INTERVAL = 60 * 1000; // 1 minute
private final Executor pluginExecutor;
private final Executor ioExecutor;
private final Context appContext;
public AndroidLanTcpPluginFactory(Executor pluginExecutor,
Context appContext) {
this.pluginExecutor = pluginExecutor;
public AndroidLanTcpPluginFactory(Executor ioExecutor, Context appContext) {
this.ioExecutor = ioExecutor;
this.appContext = appContext;
}
@@ -29,7 +28,7 @@ public class AndroidLanTcpPluginFactory implements DuplexPluginFactory {
}
public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
return new AndroidLanTcpPlugin(pluginExecutor, appContext, callback,
return new AndroidLanTcpPlugin(ioExecutor, appContext, callback,
MAX_FRAME_LENGTH, MAX_LATENCY, POLLING_INTERVAL);
}
}

View File

@@ -72,7 +72,7 @@ class TorPlugin implements DuplexPlugin, EventHandler {
private static final Logger LOG =
Logger.getLogger(TorPlugin.class.getName());
private final Executor pluginExecutor;
private final Executor ioExecutor;
private final Context appContext;
private final LocationUtils locationUtils;
private final ShutdownManager shutdownManager;
@@ -92,11 +92,11 @@ class TorPlugin implements DuplexPlugin, EventHandler {
private volatile TorControlConnection controlConnection = null;
private volatile BroadcastReceiver networkStateReceiver = null;
TorPlugin(Executor pluginExecutor, Context appContext,
TorPlugin(Executor ioExecutor, Context appContext,
LocationUtils locationUtils, ShutdownManager shutdownManager,
DuplexPluginCallback callback, int maxFrameLength, long maxLatency,
long pollingInterval) {
this.pluginExecutor = pluginExecutor;
this.ioExecutor = ioExecutor;
this.appContext = appContext;
this.locationUtils = locationUtils;
this.shutdownManager = shutdownManager;
@@ -448,7 +448,7 @@ class TorPlugin implements DuplexPlugin, EventHandler {
}
private void bind() {
pluginExecutor.execute(new Runnable() {
ioExecutor.execute(new Runnable() {
public void run() {
// If there's already a port number stored in config, reuse it
String portString = callback.getConfig().get("port");
@@ -476,7 +476,7 @@ class TorPlugin implements DuplexPlugin, EventHandler {
c.put("port", localPort);
callback.mergeConfig(c);
// Create a hidden service if necessary
pluginExecutor.execute(new Runnable() {
ioExecutor.execute(new Runnable() {
public void run() {
publishHiddenService(localPort);
}
@@ -605,7 +605,7 @@ class TorPlugin implements DuplexPlugin, EventHandler {
}
private void connectAndCallBack(final ContactId c) {
pluginExecutor.execute(new Runnable() {
ioExecutor.execute(new Runnable() {
public void run() {
DuplexTransportConnection d = createConnection(c);
if(d != null) callback.outgoingConnectionCreated(c, d);

View File

@@ -22,14 +22,14 @@ public class TorPluginFactory implements DuplexPluginFactory {
private static final long MAX_LATENCY = 60 * 1000; // 1 minute
private static final long POLLING_INTERVAL = 3 * 60 * 1000; // 3 minutes
private final Executor pluginExecutor;
private final Executor ioExecutor;
private final Context appContext;
private final LocationUtils locationUtils;
private final ShutdownManager shutdownManager;
public TorPluginFactory(Executor pluginExecutor, Context appContext,
public TorPluginFactory(Executor ioExecutor, Context appContext,
LocationUtils locationUtils, ShutdownManager shutdownManager) {
this.pluginExecutor = pluginExecutor;
this.ioExecutor = ioExecutor;
this.appContext = appContext;
this.locationUtils = locationUtils;
this.shutdownManager = shutdownManager;
@@ -45,7 +45,7 @@ public class TorPluginFactory implements DuplexPluginFactory {
LOG.info("Tor is not supported on this architecture");
return null;
}
return new TorPlugin(pluginExecutor,appContext, locationUtils,
return new TorPlugin(ioExecutor,appContext, locationUtils,
shutdownManager, callback, MAX_FRAME_LENGTH, MAX_LATENCY,
POLLING_INTERVAL);
}

View File

@@ -1,4 +1,4 @@
package org.briarproject.api.plugins;
package org.briarproject.api.lifecycle;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
@@ -10,8 +10,8 @@ import java.lang.annotation.Target;
import com.google.inject.BindingAnnotation;
/** Annotation for injecting the executor used by transport plugins. */
/** Annotation for injecting the executor used by long-lived IO tasks. */
@BindingAnnotation
@Target({ FIELD, METHOD, PARAMETER })
@Retention(RUNTIME)
public @interface PluginExecutor {}
public @interface IoExecutor {}

View File

@@ -1,19 +0,0 @@
package org.briarproject.api.transport;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import com.google.inject.BindingAnnotation;
/**
* Annotation for injecting the executor for recognising incoming connections.
*/
@BindingAnnotation
@Target({ FIELD, METHOD, PARAMETER })
@Retention(RUNTIME)
public @interface IncomingConnectionExecutor {}

View File

@@ -1,18 +1,49 @@
package org.briarproject.lifecycle;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import javax.inject.Singleton;
import org.briarproject.api.lifecycle.IoExecutor;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.lifecycle.ShutdownManager;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
public class LifecycleModule extends AbstractModule {
private final ExecutorService ioExecutor;
public LifecycleModule() {
// The thread pool is unbounded, so use direct handoff
BlockingQueue<Runnable> queue = new SynchronousQueue<Runnable>();
// Discard tasks that are submitted during shutdown
RejectedExecutionHandler policy =
new ThreadPoolExecutor.DiscardPolicy();
// Create threads as required and keep them in the pool for 60 seconds
ioExecutor = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60, SECONDS, queue, policy);
}
@Override
protected void configure() {
bind(LifecycleManager.class).to(
LifecycleManagerImpl.class).in(Singleton.class);
bind(ShutdownManager.class).to(
ShutdownManagerImpl.class).in(Singleton.class);
}
@Provides @Singleton @IoExecutor
Executor getIoExecutor(LifecycleManager lifecycleManager) {
lifecycleManager.registerForShutdown(ioExecutor);
return ioExecutor;
}
}

View File

@@ -23,9 +23,9 @@ import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.lifecycle.IoExecutor;
import org.briarproject.api.plugins.Plugin;
import org.briarproject.api.plugins.PluginCallback;
import org.briarproject.api.plugins.PluginExecutor;
import org.briarproject.api.plugins.PluginManager;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
@@ -49,7 +49,7 @@ class PluginManagerImpl implements PluginManager {
private static final Logger LOG =
Logger.getLogger(PluginManagerImpl.class.getName());
private final Executor pluginExecutor;
private final Executor ioExecutor;
private final SimplexPluginConfig simplexPluginConfig;
private final DuplexPluginConfig duplexPluginConfig;
private final Clock clock;
@@ -62,12 +62,12 @@ class PluginManagerImpl implements PluginManager {
private final List<DuplexPlugin> duplexPlugins;
@Inject
PluginManagerImpl(@PluginExecutor Executor pluginExecutor,
PluginManagerImpl(@IoExecutor Executor ioExecutor,
SimplexPluginConfig simplexPluginConfig,
DuplexPluginConfig duplexPluginConfig, Clock clock,
DatabaseComponent db, Poller poller,
ConnectionDispatcher dispatcher, UiCallback uiCallback) {
this.pluginExecutor = pluginExecutor;
this.ioExecutor = ioExecutor;
this.simplexPluginConfig = simplexPluginConfig;
this.duplexPluginConfig = duplexPluginConfig;
this.clock = clock;
@@ -87,14 +87,14 @@ class PluginManagerImpl implements PluginManager {
simplexPluginConfig.getFactories();
final CountDownLatch sLatch = new CountDownLatch(sFactories.size());
for(SimplexPluginFactory factory : sFactories)
pluginExecutor.execute(new SimplexPluginStarter(factory, sLatch));
ioExecutor.execute(new SimplexPluginStarter(factory, sLatch));
// Instantiate and start the duplex plugins
LOG.info("Starting duplex plugins");
Collection<DuplexPluginFactory> dFactories =
duplexPluginConfig.getFactories();
final CountDownLatch dLatch = new CountDownLatch(dFactories.size());
for(DuplexPluginFactory factory : dFactories)
pluginExecutor.execute(new DuplexPluginStarter(factory, dLatch));
ioExecutor.execute(new DuplexPluginStarter(factory, dLatch));
// Wait for the plugins to start
try {
sLatch.await();
@@ -119,11 +119,11 @@ class PluginManagerImpl implements PluginManager {
// Stop the simplex plugins
LOG.info("Stopping simplex plugins");
for(SimplexPlugin plugin : simplexPlugins)
pluginExecutor.execute(new PluginStopper(plugin, latch));
ioExecutor.execute(new PluginStopper(plugin, latch));
// Stop the duplex plugins
LOG.info("Stopping duplex plugins");
for(DuplexPlugin plugin : duplexPlugins)
pluginExecutor.execute(new PluginStopper(plugin, latch));
ioExecutor.execute(new PluginStopper(plugin, latch));
plugins.clear();
simplexPlugins.clear();
duplexPlugins.clear();

View File

@@ -1,18 +1,8 @@
package org.briarproject.plugins;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import javax.inject.Singleton;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.plugins.PluginExecutor;
import org.briarproject.api.plugins.PluginManager;
import com.google.inject.AbstractModule;
@@ -20,19 +10,7 @@ import com.google.inject.Provides;
public class PluginsModule extends AbstractModule {
private final ExecutorService pluginExecutor;
public PluginsModule() {
// The thread pool is unbounded, so use direct handoff
BlockingQueue<Runnable> queue = new SynchronousQueue<Runnable>();
// Discard tasks that are submitted during shutdown
RejectedExecutionHandler policy =
new ThreadPoolExecutor.DiscardPolicy();
// Create threads as required and keep them in the pool for 60 seconds
pluginExecutor = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60, SECONDS, queue, policy);
}
@Override
protected void configure() {
bind(Poller.class).to(PollerImpl.class);
}
@@ -43,10 +21,4 @@ public class PluginsModule extends AbstractModule {
lifecycleManager.register(pluginManager);
return pluginManager;
}
@Provides @Singleton @PluginExecutor
Executor getPluginExecutor(LifecycleManager lifecycleManager) {
lifecycleManager.registerForShutdown(pluginExecutor);
return pluginExecutor;
}
}

View File

@@ -9,8 +9,8 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import org.briarproject.api.lifecycle.IoExecutor;
import org.briarproject.api.plugins.Plugin;
import org.briarproject.api.plugins.PluginExecutor;
import org.briarproject.api.system.Timer;
import org.briarproject.api.transport.ConnectionRegistry;
@@ -19,14 +19,14 @@ class PollerImpl implements Poller {
private static final Logger LOG =
Logger.getLogger(PollerImpl.class.getName());
private final Executor pluginExecutor;
private final Executor ioExecutor;
private final ConnectionRegistry connRegistry;
private final Timer timer;
@Inject
PollerImpl(@PluginExecutor Executor pluginExecutor,
ConnectionRegistry connRegistry, Timer timer) {
this.pluginExecutor = pluginExecutor;
PollerImpl(@IoExecutor Executor ioExecutor, ConnectionRegistry connRegistry,
Timer timer) {
this.ioExecutor = ioExecutor;
this.connRegistry = connRegistry;
this.timer = timer;
}
@@ -49,7 +49,7 @@ class PollerImpl implements Poller {
}
public void pollNow(final Plugin p) {
pluginExecutor.execute(new Runnable() {
ioExecutor.execute(new Runnable() {
public void run() {
if(LOG.isLoggable(INFO))
LOG.info("Polling " + p.getClass().getSimpleName());
@@ -66,6 +66,7 @@ class PollerImpl implements Poller {
this.plugin = plugin;
}
@Override
public void run() {
pollNow(plugin);
schedule(plugin, false);

View File

@@ -25,7 +25,7 @@ public abstract class FilePlugin implements SimplexPlugin {
private static final Logger LOG =
Logger.getLogger(FilePlugin.class.getName());
protected final Executor pluginExecutor;
protected final Executor ioExecutor;
protected final FileUtils fileUtils;
protected final SimplexPluginCallback callback;
protected final int maxFrameLength;
@@ -38,10 +38,10 @@ public abstract class FilePlugin implements SimplexPlugin {
protected abstract void writerFinished(File f);
protected abstract void readerFinished(File f);
protected FilePlugin(Executor pluginExecutor, FileUtils fileUtils,
protected FilePlugin(Executor ioExecutor, FileUtils fileUtils,
SimplexPluginCallback callback, int maxFrameLength,
long maxLatency) {
this.pluginExecutor = pluginExecutor;
this.ioExecutor = ioExecutor;
this.fileUtils = fileUtils;
this.callback = callback;
this.maxFrameLength = maxFrameLength;
@@ -100,7 +100,7 @@ public abstract class FilePlugin implements SimplexPlugin {
protected void createReaderFromFile(final File f) {
if(!running) return;
pluginExecutor.execute(new ReaderCreator(f));
ioExecutor.execute(new ReaderCreator(f));
}
private class ReaderCreator implements Runnable {

View File

@@ -16,9 +16,9 @@ class LanTcpPlugin extends TcpPlugin {
static final TransportId ID = new TransportId("lan");
LanTcpPlugin(Executor pluginExecutor, DuplexPluginCallback callback,
LanTcpPlugin(Executor ioExecutor, DuplexPluginCallback callback,
int maxFrameLength, long maxLatency, long pollingInterval) {
super(pluginExecutor, callback, maxFrameLength, maxLatency,
super(ioExecutor, callback, maxFrameLength, maxLatency,
pollingInterval);
}

View File

@@ -13,10 +13,10 @@ public class LanTcpPluginFactory implements DuplexPluginFactory {
private static final long MAX_LATENCY = 60 * 1000; // 1 minute
private static final long POLLING_INTERVAL = 60 * 1000; // 1 minute
private final Executor pluginExecutor;
private final Executor ioExecutor;
public LanTcpPluginFactory(Executor pluginExecutor) {
this.pluginExecutor = pluginExecutor;
public LanTcpPluginFactory(Executor ioExecutor) {
this.ioExecutor = ioExecutor;
}
public TransportId getId() {
@@ -24,7 +24,7 @@ public class LanTcpPluginFactory implements DuplexPluginFactory {
}
public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
return new LanTcpPlugin(pluginExecutor, callback, MAX_FRAME_LENGTH,
return new LanTcpPlugin(ioExecutor, callback, MAX_FRAME_LENGTH,
MAX_LATENCY, POLLING_INTERVAL);
}
}

View File

@@ -35,7 +35,7 @@ abstract class TcpPlugin implements DuplexPlugin {
private static final Logger LOG =
Logger.getLogger(TcpPlugin.class.getName());
protected final Executor pluginExecutor;
protected final Executor ioExecutor;
protected final DuplexPluginCallback callback;
protected final int maxFrameLength;
protected final long maxLatency, pollingInterval;
@@ -52,9 +52,9 @@ abstract class TcpPlugin implements DuplexPlugin {
/** Returns true if connections to the given address can be attempted. */
protected abstract boolean isConnectable(InetSocketAddress remote);
protected TcpPlugin(Executor pluginExecutor, DuplexPluginCallback callback,
protected TcpPlugin(Executor ioExecutor, DuplexPluginCallback callback,
int maxFrameLength, long maxLatency, long pollingInterval) {
this.pluginExecutor = pluginExecutor;
this.ioExecutor = ioExecutor;
this.callback = callback;
this.maxFrameLength = maxFrameLength;
this.maxLatency = maxLatency;
@@ -76,7 +76,7 @@ abstract class TcpPlugin implements DuplexPlugin {
}
protected void bind() {
pluginExecutor.execute(new Runnable() {
ioExecutor.execute(new Runnable() {
public void run() {
if(!running) return;
ServerSocket ss = null;
@@ -172,7 +172,7 @@ abstract class TcpPlugin implements DuplexPlugin {
}
private void connectAndCallBack(final ContactId c) {
pluginExecutor.execute(new Runnable() {
ioExecutor.execute(new Runnable() {
public void run() {
DuplexTransportConnection d = createConnection(c);
if(d != null) callback.outgoingConnectionCreated(c, d);

View File

@@ -20,10 +20,10 @@ class WanTcpPlugin extends TcpPlugin {
private volatile MappingResult mappingResult;
WanTcpPlugin(Executor pluginExecutor, DuplexPluginCallback callback,
WanTcpPlugin(Executor ioExecutor, DuplexPluginCallback callback,
int maxFrameLength, long maxLatency, long pollingInterval,
PortMapper portMapper) {
super(pluginExecutor, callback, maxFrameLength, maxLatency,
super(ioExecutor, callback, maxFrameLength, maxLatency,
pollingInterval);
this.portMapper = portMapper;
}

View File

@@ -14,12 +14,12 @@ public class WanTcpPluginFactory implements DuplexPluginFactory {
private static final long MAX_LATENCY = 60 * 1000; // 1 minute
private static final long POLLING_INTERVAL = 5 * 60 * 1000; // 5 minutes
private final Executor pluginExecutor;
private final Executor ioExecutor;
private final ShutdownManager shutdownManager;
public WanTcpPluginFactory(Executor pluginExecutor,
public WanTcpPluginFactory(Executor ioExecutor,
ShutdownManager shutdownManager) {
this.pluginExecutor = pluginExecutor;
this.ioExecutor = ioExecutor;
this.shutdownManager = shutdownManager;
}
@@ -28,7 +28,7 @@ public class WanTcpPluginFactory implements DuplexPluginFactory {
}
public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
return new WanTcpPlugin(pluginExecutor, callback, MAX_FRAME_LENGTH,
return new WanTcpPlugin(ioExecutor, callback, MAX_FRAME_LENGTH,
MAX_LATENCY, POLLING_INTERVAL,
new PortMapperImpl(shutdownManager));
}

View File

@@ -14,6 +14,7 @@ import javax.inject.Inject;
import org.briarproject.api.ContactId;
import org.briarproject.api.TransportId;
import org.briarproject.api.db.DbException;
import org.briarproject.api.lifecycle.IoExecutor;
import org.briarproject.api.messaging.duplex.DuplexConnectionFactory;
import org.briarproject.api.messaging.simplex.SimplexConnectionFactory;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
@@ -22,31 +23,30 @@ import org.briarproject.api.plugins.simplex.SimplexTransportWriter;
import org.briarproject.api.transport.ConnectionContext;
import org.briarproject.api.transport.ConnectionDispatcher;
import org.briarproject.api.transport.ConnectionRecogniser;
import org.briarproject.api.transport.IncomingConnectionExecutor;
class ConnectionDispatcherImpl implements ConnectionDispatcher {
private static final Logger LOG =
Logger.getLogger(ConnectionDispatcherImpl.class.getName());
private final Executor connExecutor;
private final Executor ioExecutor;
private final ConnectionRecogniser recogniser;
private final SimplexConnectionFactory simplexConnFactory;
private final DuplexConnectionFactory duplexConnFactory;
@Inject
ConnectionDispatcherImpl(@IncomingConnectionExecutor Executor connExecutor,
ConnectionDispatcherImpl(@IoExecutor Executor ioExecutor,
ConnectionRecogniser recogniser,
SimplexConnectionFactory simplexConnFactory,
DuplexConnectionFactory duplexConnFactory) {
this.connExecutor = connExecutor;
this.ioExecutor = ioExecutor;
this.recogniser = recogniser;
this.simplexConnFactory = simplexConnFactory;
this.duplexConnFactory = duplexConnFactory;
}
public void dispatchReader(TransportId t, SimplexTransportReader r) {
connExecutor.execute(new DispatchSimplexConnection(t, r));
ioExecutor.execute(new DispatchSimplexConnection(t, r));
}
public void dispatchWriter(ContactId c, TransportId t,
@@ -56,7 +56,7 @@ class ConnectionDispatcherImpl implements ConnectionDispatcher {
public void dispatchIncomingConnection(TransportId t,
DuplexTransportConnection d) {
connExecutor.execute(new DispatchDuplexConnection(t, d));
ioExecutor.execute(new DispatchDuplexConnection(t, d));
}
public void dispatchOutgoingConnection(ContactId c, TransportId t,

View File

@@ -1,14 +1,5 @@
package org.briarproject.transport;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import javax.inject.Singleton;
import org.briarproject.api.crypto.KeyManager;
@@ -18,26 +9,13 @@ import org.briarproject.api.transport.ConnectionReaderFactory;
import org.briarproject.api.transport.ConnectionRecogniser;
import org.briarproject.api.transport.ConnectionRegistry;
import org.briarproject.api.transport.ConnectionWriterFactory;
import org.briarproject.api.transport.IncomingConnectionExecutor;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
public class TransportModule extends AbstractModule {
private final ExecutorService incomingConnectionExecutor;
public TransportModule() {
// The thread pool is unbounded, so use direct handoff
BlockingQueue<Runnable> queue = new SynchronousQueue<Runnable>();
// Discard tasks that are submitted during shutdown
RejectedExecutionHandler policy =
new ThreadPoolExecutor.DiscardPolicy();
// Create threads as required and keep them in the pool for 60 seconds
incomingConnectionExecutor = new ThreadPoolExecutor(0,
Integer.MAX_VALUE, 60, SECONDS, queue, policy);
}
@Override
protected void configure() {
bind(ConnectionDispatcher.class).to(ConnectionDispatcherImpl.class);
bind(ConnectionReaderFactory.class).to(
@@ -55,10 +33,4 @@ public class TransportModule extends AbstractModule {
lifecycleManager.register(keyManager);
return keyManager;
}
@Provides @Singleton @IncomingConnectionExecutor
Executor getIncomingConnectionExecutor(LifecycleManager lifecycleManager) {
lifecycleManager.registerForShutdown(incomingConnectionExecutor);
return incomingConnectionExecutor;
}
}

View File

@@ -4,21 +4,20 @@ import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.lifecycle.ShutdownManager;
import org.briarproject.util.OsUtils;
import com.google.inject.AbstractModule;
import com.google.inject.Singleton;
public class DesktopLifecycleModule extends AbstractModule {
public class DesktopLifecycleModule extends LifecycleModule {
@Override
protected void configure() {
bind(LifecycleManager.class).to(
LifecycleManagerImpl.class).in(Singleton.class);
if(OsUtils.isWindows()) {
bind(ShutdownManager.class).to(
WindowsShutdownManagerImpl.class).in(
Singleton.class);
WindowsShutdownManagerImpl.class).in(Singleton.class);
} else {
bind(ShutdownManager.class).to(
ShutdownManagerImpl.class).in(Singleton.class);
ShutdownManagerImpl.class).in(Singleton.class);
}
}
}

View File

@@ -5,8 +5,8 @@ import java.util.Collection;
import java.util.concurrent.Executor;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.lifecycle.IoExecutor;
import org.briarproject.api.lifecycle.ShutdownManager;
import org.briarproject.api.plugins.PluginExecutor;
import org.briarproject.api.plugins.duplex.DuplexPluginConfig;
import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
import org.briarproject.api.plugins.simplex.SimplexPluginConfig;
@@ -19,18 +19,15 @@ import org.briarproject.plugins.modem.ModemPluginFactory;
import org.briarproject.plugins.tcp.LanTcpPluginFactory;
import org.briarproject.plugins.tcp.WanTcpPluginFactory;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
public class DesktopPluginsModule extends AbstractModule {
public void configure() {}
public class DesktopPluginsModule extends PluginsModule {
@Provides
SimplexPluginConfig getSimplexPluginConfig(
@PluginExecutor Executor pluginExecutor, FileUtils fileUtils) {
SimplexPluginConfig getSimplexPluginConfig(@IoExecutor Executor ioExecutor,
FileUtils fileUtils) {
SimplexPluginFactory removable =
new RemovableDrivePluginFactory(pluginExecutor, fileUtils);
new RemovableDrivePluginFactory(ioExecutor, fileUtils);
final Collection<SimplexPluginFactory> factories =
Arrays.asList(removable);
return new SimplexPluginConfig() {
@@ -41,16 +38,15 @@ public class DesktopPluginsModule extends AbstractModule {
}
@Provides
DuplexPluginConfig getDuplexPluginConfig(
@PluginExecutor Executor pluginExecutor,
DuplexPluginConfig getDuplexPluginConfig(@IoExecutor Executor ioExecutor,
CryptoComponent crypto, ReliabilityLayerFactory reliabilityFactory,
ShutdownManager shutdownManager) {
DuplexPluginFactory bluetooth = new BluetoothPluginFactory(
pluginExecutor, crypto.getSecureRandom());
DuplexPluginFactory modem = new ModemPluginFactory(pluginExecutor,
ioExecutor, crypto.getSecureRandom());
DuplexPluginFactory modem = new ModemPluginFactory(ioExecutor,
reliabilityFactory);
DuplexPluginFactory lan = new LanTcpPluginFactory(pluginExecutor);
DuplexPluginFactory wan = new WanTcpPluginFactory(pluginExecutor,
DuplexPluginFactory lan = new LanTcpPluginFactory(ioExecutor);
DuplexPluginFactory wan = new WanTcpPluginFactory(ioExecutor,
shutdownManager);
final Collection<DuplexPluginFactory> factories =
Arrays.asList(bluetooth, modem, lan, wan);

View File

@@ -42,7 +42,7 @@ class BluetoothPlugin implements DuplexPlugin {
Logger.getLogger(BluetoothPlugin.class.getName());
private static final int UUID_BYTES = 16;
private final Executor pluginExecutor;
private final Executor ioExecutor;
private final Clock clock;
private final SecureRandom secureRandom;
private final DuplexPluginCallback callback;
@@ -54,10 +54,10 @@ class BluetoothPlugin implements DuplexPlugin {
private volatile StreamConnectionNotifier socket = null;
private volatile LocalDevice localDevice = null;
BluetoothPlugin(Executor pluginExecutor, Clock clock,
SecureRandom secureRandom, DuplexPluginCallback callback,
int maxFrameLength, long maxLatency, long pollingInterval) {
this.pluginExecutor = pluginExecutor;
BluetoothPlugin(Executor ioExecutor, Clock clock, SecureRandom secureRandom,
DuplexPluginCallback callback, int maxFrameLength, long maxLatency,
long pollingInterval) {
this.ioExecutor = ioExecutor;
this.clock = clock;
this.secureRandom = secureRandom;
this.callback = callback;
@@ -96,7 +96,7 @@ class BluetoothPlugin implements DuplexPlugin {
}
private void bind() {
pluginExecutor.execute(new Runnable() {
ioExecutor.execute(new Runnable() {
public void run() {
if(!running) return;
// Advertise the Bluetooth address to contacts
@@ -197,7 +197,7 @@ class BluetoothPlugin implements DuplexPlugin {
if(StringUtils.isNullOrEmpty(address)) continue;
final String uuid = e.getValue().get("uuid");
if(StringUtils.isNullOrEmpty(uuid)) continue;
pluginExecutor.execute(new Runnable() {
ioExecutor.execute(new Runnable() {
public void run() {
if(!running) return;
StreamConnection s = connect(makeUrl(address, uuid));

View File

@@ -16,13 +16,13 @@ public class BluetoothPluginFactory implements DuplexPluginFactory {
private static final long MAX_LATENCY = 60 * 1000; // 1 minute
private static final long POLLING_INTERVAL = 3 * 60 * 1000; // 3 minutes
private final Executor pluginExecutor;
private final Executor ioExecutor;
private final SecureRandom secureRandom;
private final Clock clock;
public BluetoothPluginFactory(Executor pluginExecutor,
public BluetoothPluginFactory(Executor ioExecutor,
SecureRandom secureRandom) {
this.pluginExecutor = pluginExecutor;
this.ioExecutor = ioExecutor;
this.secureRandom = secureRandom;
clock = new SystemClock();
}
@@ -32,7 +32,7 @@ public class BluetoothPluginFactory implements DuplexPluginFactory {
}
public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
return new BluetoothPlugin(pluginExecutor, clock, secureRandom,
callback, MAX_FRAME_LENGTH, MAX_LATENCY, POLLING_INTERVAL);
return new BluetoothPlugin(ioExecutor, clock, secureRandom, callback,
MAX_FRAME_LENGTH, MAX_LATENCY, POLLING_INTERVAL);
}
}

View File

@@ -11,7 +11,7 @@ class PollingRemovableDriveMonitor implements RemovableDriveMonitor, Runnable {
private static final Logger LOG =
Logger.getLogger(PollingRemovableDriveMonitor.class.getName());
private final Executor pluginExecutor;
private final Executor ioExecutor;
private final RemovableDriveFinder finder;
private final long pollingInterval;
private final Object pollingLock = new Object();
@@ -19,9 +19,9 @@ class PollingRemovableDriveMonitor implements RemovableDriveMonitor, Runnable {
private volatile boolean running = false;
private volatile Callback callback = null;
public PollingRemovableDriveMonitor(Executor pluginExecutor,
public PollingRemovableDriveMonitor(Executor ioExecutor,
RemovableDriveFinder finder, long pollingInterval) {
this.pluginExecutor = pluginExecutor;
this.ioExecutor = ioExecutor;
this.finder = finder;
this.pollingInterval = pollingInterval;
}
@@ -29,7 +29,7 @@ class PollingRemovableDriveMonitor implements RemovableDriveMonitor, Runnable {
public void start(Callback callback) throws IOException {
this.callback = callback;
running = true;
pluginExecutor.execute(this);
ioExecutor.execute(this);
}
public void stop() throws IOException {

View File

@@ -27,11 +27,11 @@ implements RemovableDriveMonitor.Callback {
private final RemovableDriveFinder finder;
private final RemovableDriveMonitor monitor;
RemovableDrivePlugin(Executor pluginExecutor, FileUtils fileUtils,
RemovableDrivePlugin(Executor ioExecutor, FileUtils fileUtils,
SimplexPluginCallback callback, RemovableDriveFinder finder,
RemovableDriveMonitor monitor, int maxFrameLength,
long maxLatency) {
super(pluginExecutor, fileUtils, callback, maxFrameLength, maxLatency);
super(ioExecutor, fileUtils, callback, maxFrameLength, maxLatency);
this.finder = finder;
this.monitor = monitor;
}

View File

@@ -17,12 +17,12 @@ public class RemovableDrivePluginFactory implements SimplexPluginFactory {
private static final long MAX_LATENCY = 14 * 24 * 60 * 60 * 1000;
private static final long POLLING_INTERVAL = 10 * 1000; // 10 seconds
private final Executor pluginExecutor;
private final Executor ioExecutor;
private final FileUtils fileUtils;
public RemovableDrivePluginFactory(Executor pluginExecutor,
public RemovableDrivePluginFactory(Executor ioExecutor,
FileUtils fileUtils) {
this.pluginExecutor = pluginExecutor;
this.ioExecutor = ioExecutor;
this.fileUtils = fileUtils;
}
@@ -42,16 +42,16 @@ public class RemovableDrivePluginFactory implements SimplexPluginFactory {
} else if(OsUtils.isMac()) {
// JNotify requires OS X 10.5 or newer, so we have to poll
finder = new MacRemovableDriveFinder();
monitor = new PollingRemovableDriveMonitor(pluginExecutor, finder,
monitor = new PollingRemovableDriveMonitor(ioExecutor, finder,
POLLING_INTERVAL);
} else if(OsUtils.isWindows()) {
finder = new WindowsRemovableDriveFinder();
monitor = new PollingRemovableDriveMonitor(pluginExecutor, finder,
monitor = new PollingRemovableDriveMonitor(ioExecutor, finder,
POLLING_INTERVAL);
} else {
return null;
}
return new RemovableDrivePlugin(pluginExecutor, fileUtils, callback,
return new RemovableDrivePlugin(ioExecutor, fileUtils, callback,
finder, monitor, MAX_FRAME_LENGTH, MAX_LATENCY);
}
}

View File

@@ -32,7 +32,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
private static final Logger LOG =
Logger.getLogger(ModemPlugin.class.getName());
private final Executor pluginExecutor;
private final Executor ioExecutor;
private final ModemFactory modemFactory;
private final SerialPortList serialPortList;
private final DuplexPluginCallback callback;
@@ -43,11 +43,11 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
private volatile boolean running = false;
private volatile Modem modem = null;
ModemPlugin(Executor pluginExecutor, ModemFactory modemFactory,
ModemPlugin(Executor ioExecutor, ModemFactory modemFactory,
SerialPortList serialPortList, DuplexPluginCallback callback,
int maxFrameLength, long maxLatency, long pollingInterval,
boolean shuffle) {
this.pluginExecutor = pluginExecutor;
this.ioExecutor = ioExecutor;
this.modemFactory = modemFactory;
this.serialPortList = serialPortList;
this.callback = callback;
@@ -112,7 +112,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
public void poll(Collection<ContactId> connected) {
if(!connected.isEmpty()) return; // One at a time please
pluginExecutor.execute(new Runnable() {
ioExecutor.execute(new Runnable() {
public void run() {
poll();
}

View File

@@ -15,14 +15,14 @@ public class ModemPluginFactory implements DuplexPluginFactory {
private static final long MAX_LATENCY = 60 * 1000; // 1 minute
private static final long POLLING_INTERVAL = 60 * 60 * 1000; // 1 hour
private final Executor pluginExecutor;
private final Executor ioExecutor;
private final ModemFactory modemFactory;
private final SerialPortList serialPortList;
public ModemPluginFactory(Executor pluginExecutor,
public ModemPluginFactory(Executor ioExecutor,
ReliabilityLayerFactory reliabilityFactory) {
this.pluginExecutor = pluginExecutor;
modemFactory = new ModemFactoryImpl(pluginExecutor, reliabilityFactory);
this.ioExecutor = ioExecutor;
modemFactory = new ModemFactoryImpl(ioExecutor, reliabilityFactory);
serialPortList = new SerialPortListImpl();
}
@@ -34,7 +34,7 @@ public class ModemPluginFactory implements DuplexPluginFactory {
// This plugin is not enabled by default
String enabled = callback.getConfig().get("enabled");
if(StringUtils.isNullOrEmpty(enabled)) return null;
return new ModemPlugin(pluginExecutor, modemFactory, serialPortList,
return new ModemPlugin(ioExecutor, modemFactory, serialPortList,
callback, MAX_FRAME_LENGTH, MAX_LATENCY, POLLING_INTERVAL,
true);
}

View File

@@ -1,7 +1,10 @@
package org.briarproject;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.briarproject.api.lifecycle.IoExecutor;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.lifecycle.Service;
import org.briarproject.api.lifecycle.ShutdownManager;
@@ -10,6 +13,7 @@ import com.google.inject.AbstractModule;
public class TestLifecycleModule extends AbstractModule {
@Override
protected void configure() {
bind(LifecycleManager.class).toInstance(new LifecycleManager() {
@@ -37,5 +41,7 @@ public class TestLifecycleModule extends AbstractModule {
return true;
}
});
bind(Executor.class).annotatedWith(IoExecutor.class).toInstance(
Executors.newCachedThreadPool());
}
}

View File

@@ -29,7 +29,7 @@ public class PluginManagerImplTest extends BriarTestCase {
public void testStartAndStop() throws Exception {
Clock clock = new SystemClock();
Mockery context = new Mockery();
final Executor pluginExecutor = Executors.newCachedThreadPool();
final Executor ioExecutor = Executors.newCachedThreadPool();
final SimplexPluginConfig simplexPluginConfig =
context.mock(SimplexPluginConfig.class);
final DuplexPluginConfig duplexPluginConfig =
@@ -116,7 +116,7 @@ public class PluginManagerImplTest extends BriarTestCase {
oneOf(simplexPlugin).stop();
oneOf(duplexPlugin).stop();
}});
PluginManagerImpl p = new PluginManagerImpl(pluginExecutor,
PluginManagerImpl p = new PluginManagerImpl(ioExecutor,
simplexPluginConfig, duplexPluginConfig, clock, db, poller,
dispatcher, uiCallback);
// Two plugins should be started and stopped

View File

@@ -15,7 +15,6 @@ import org.briarproject.api.ContactId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
import org.hamcrest.Description;
import org.jmock.Expectations;
import org.jmock.Mockery;
@@ -194,8 +193,7 @@ public class ModemPluginTest extends BriarTestCase {
@Test
public void testPolling() throws Exception {
final ExecutorService pluginExecutor =
Executors.newSingleThreadExecutor();
final ExecutorService ioExecutor = Executors.newSingleThreadExecutor();
Mockery context = new Mockery();
final ModemFactory modemFactory = context.mock(ModemFactory.class);
final SerialPortList serialPortList =
@@ -203,7 +201,7 @@ public class ModemPluginTest extends BriarTestCase {
final DuplexPluginCallback callback =
context.mock(DuplexPluginCallback.class);
// Disable shuffling for this test, it confuses jMock
final ModemPlugin plugin = new ModemPlugin(pluginExecutor, modemFactory,
final ModemPlugin plugin = new ModemPlugin(ioExecutor, modemFactory,
serialPortList, callback, 0, 0, 0, false);
final Modem modem = context.mock(Modem.class);
final TransportProperties local = new TransportProperties();
@@ -265,7 +263,7 @@ public class ModemPluginTest extends BriarTestCase {
assertTrue(plugin.start());
plugin.poll(Collections.<ContactId>emptyList());
assertTrue(disposeAction.invoked.await(5, SECONDS));
pluginExecutor.shutdown();
ioExecutor.shutdown();
context.assertIsSatisfied();
}