diff --git a/briar-api/src/org/briarproject/api/system/Scheduler.java b/briar-api/src/org/briarproject/api/system/Scheduler.java
new file mode 100644
index 000000000..0b1e225da
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/system/Scheduler.java
@@ -0,0 +1,25 @@
+package org.briarproject.api.system;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+
+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;
+
+/**
+ * Annotation for injecting a scheduled executor service
+ * that can be used to schedule the execution of tasks.
+ *
+ * The service should only be used for running tasks on other executors
+ * at scheduled times.
+ * No significant work should be run by the service itself!
+ */
+@Qualifier
+@Target({FIELD, METHOD, PARAMETER})
+@Retention(RUNTIME)
+public @interface Scheduler {
+}
\ No newline at end of file
diff --git a/briar-core/src/org/briarproject/feed/FeedManagerImpl.java b/briar-core/src/org/briarproject/feed/FeedManagerImpl.java
index b2229a60c..55a413cde 100644
--- a/briar-core/src/org/briarproject/feed/FeedManagerImpl.java
+++ b/briar-core/src/org/briarproject/feed/FeedManagerImpl.java
@@ -29,6 +29,7 @@ import org.briarproject.api.feed.FeedManager;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.lifecycle.IoExecutor;
+import org.briarproject.api.system.Scheduler;
import org.briarproject.api.plugins.TorConstants;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId;
@@ -74,7 +75,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
private static final int CONNECT_TIMEOUT = 60 * 1000; // Milliseconds
- private final ScheduledExecutorService feedExecutor;
+ private final ScheduledExecutorService scheduler;
private final Executor ioExecutor;
private final DatabaseComponent db;
private final ContactGroupFactory contactGroupFactory;
@@ -92,13 +93,13 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
Clock clock;
@Inject
- FeedManagerImpl(ScheduledExecutorService feedExecutor,
+ FeedManagerImpl(@Scheduler ScheduledExecutorService scheduler,
@IoExecutor Executor ioExecutor, DatabaseComponent db,
ContactGroupFactory contactGroupFactory, ClientHelper clientHelper,
IdentityManager identityManager, BlogManager blogManager,
SocketFactory torSocketFactory) {
- this.feedExecutor = feedExecutor;
+ this.scheduler = scheduler;
this.ioExecutor = ioExecutor;
this.db = db;
this.contactGroupFactory = contactGroupFactory;
@@ -132,7 +133,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
});
}
};
- feedExecutor.scheduleWithFixedDelay(fetcher, FETCH_DELAY_INITIAL,
+ scheduler.scheduleWithFixedDelay(fetcher, FETCH_DELAY_INITIAL,
FETCH_INTERVAL, FETCH_UNIT);
}
diff --git a/briar-core/src/org/briarproject/plugins/PluginsModule.java b/briar-core/src/org/briarproject/plugins/PluginsModule.java
index fc58bc404..d7e6925e5 100644
--- a/briar-core/src/org/briarproject/plugins/PluginsModule.java
+++ b/briar-core/src/org/briarproject/plugins/PluginsModule.java
@@ -8,6 +8,7 @@ import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.ConnectionRegistry;
import org.briarproject.api.plugins.PluginManager;
import org.briarproject.api.system.Clock;
+import org.briarproject.api.system.Scheduler;
import java.security.SecureRandom;
import java.util.concurrent.Executor;
@@ -37,7 +38,7 @@ public class PluginsModule {
@Provides
@Singleton
Poller providePoller(@IoExecutor Executor ioExecutor,
- ScheduledExecutorService scheduler,
+ @Scheduler ScheduledExecutorService scheduler,
ConnectionManager connectionManager,
ConnectionRegistry connectionRegistry, PluginManager pluginManager,
SecureRandom random, Clock clock, EventBus eventBus) {
diff --git a/briar-core/src/org/briarproject/plugins/Poller.java b/briar-core/src/org/briarproject/plugins/Poller.java
index 20643e43e..a904bbfe6 100644
--- a/briar-core/src/org/briarproject/plugins/Poller.java
+++ b/briar-core/src/org/briarproject/plugins/Poller.java
@@ -18,6 +18,7 @@ import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
import org.briarproject.api.plugins.simplex.SimplexPlugin;
import org.briarproject.api.system.Clock;
+import org.briarproject.api.system.Scheduler;
import java.security.SecureRandom;
import java.util.HashMap;
@@ -48,7 +49,8 @@ class Poller implements EventListener {
private final Map tasks; // Locking: lock
@Inject
- Poller(@IoExecutor Executor ioExecutor, ScheduledExecutorService scheduler,
+ Poller(@IoExecutor Executor ioExecutor,
+ @Scheduler ScheduledExecutorService scheduler,
ConnectionManager connectionManager,
ConnectionRegistry connectionRegistry, PluginManager pluginManager,
SecureRandom random, Clock clock) {
@@ -135,13 +137,14 @@ class Poller implements EventListener {
private void reschedule(TransportId t) {
Plugin p = pluginManager.getPlugin(t);
- if (p.shouldPoll()) schedule(p, p.getPollingInterval(), false);
+ if (p != null && p.shouldPoll())
+ schedule(p, p.getPollingInterval(), false);
}
private void pollNow(TransportId t) {
Plugin p = pluginManager.getPlugin(t);
// Randomise next polling interval
- if (p.shouldPoll()) schedule(p, 0, true);
+ if (p != null && p.shouldPoll()) schedule(p, 0, true);
}
private void schedule(Plugin p, int delay, boolean randomiseNext) {
@@ -152,24 +155,25 @@ class Poller implements EventListener {
try {
PollTask scheduled = tasks.get(t);
if (scheduled == null || due < scheduled.due) {
- PollTask task = new PollTask(p, due, randomiseNext);
+ final PollTask task = new PollTask(p, due, randomiseNext);
tasks.put(t, task);
- scheduler.schedule(task, delay, MILLISECONDS);
+ scheduler.schedule(new Runnable() {
+ @Override
+ public void run() {
+ ioExecutor.execute(task);
+ }
+ }, delay, MILLISECONDS);
}
} finally {
lock.unlock();
}
}
+ @IoExecutor
private void poll(final Plugin p) {
- ioExecutor.execute(new Runnable() {
- @Override
- public void run() {
- TransportId t = p.getId();
- if (LOG.isLoggable(INFO)) LOG.info("Polling plugin " + t);
- p.poll(connectionRegistry.getConnectedContacts(t));
- }
- });
+ TransportId t = p.getId();
+ if (LOG.isLoggable(INFO)) LOG.info("Polling plugin " + t);
+ p.poll(connectionRegistry.getConnectedContacts(t));
}
private class PollTask implements Runnable {
@@ -185,6 +189,7 @@ class Poller implements EventListener {
}
@Override
+ @IoExecutor
public void run() {
lock.lock();
try {
diff --git a/briar-core/src/org/briarproject/system/SystemModule.java b/briar-core/src/org/briarproject/system/SystemModule.java
index 8893a86ab..40ca8037c 100644
--- a/briar-core/src/org/briarproject/system/SystemModule.java
+++ b/briar-core/src/org/briarproject/system/SystemModule.java
@@ -2,6 +2,7 @@ package org.briarproject.system;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.system.Clock;
+import org.briarproject.api.system.Scheduler;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@@ -17,6 +18,7 @@ public class SystemModule {
public static class EagerSingletons {
@Inject
+ @Scheduler
ScheduledExecutorService scheduledExecutorService;
}
@@ -33,6 +35,7 @@ public class SystemModule {
@Provides
@Singleton
+ @Scheduler
ScheduledExecutorService provideScheduledExecutorService(
LifecycleManager lifecycleManager) {
lifecycleManager.registerForShutdown(scheduler);
diff --git a/briar-core/src/org/briarproject/transport/TransportKeyManagerFactoryImpl.java b/briar-core/src/org/briarproject/transport/TransportKeyManagerFactoryImpl.java
index dbc05778b..55818bfdc 100644
--- a/briar-core/src/org/briarproject/transport/TransportKeyManagerFactoryImpl.java
+++ b/briar-core/src/org/briarproject/transport/TransportKeyManagerFactoryImpl.java
@@ -5,6 +5,7 @@ import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DatabaseExecutor;
import org.briarproject.api.system.Clock;
+import org.briarproject.api.system.Scheduler;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
@@ -23,7 +24,7 @@ class TransportKeyManagerFactoryImpl implements
@Inject
TransportKeyManagerFactoryImpl(DatabaseComponent db, CryptoComponent crypto,
@DatabaseExecutor Executor dbExecutor,
- ScheduledExecutorService scheduler, Clock clock) {
+ @Scheduler ScheduledExecutorService scheduler, Clock clock) {
this.db = db;
this.crypto = crypto;
this.dbExecutor = dbExecutor;
diff --git a/briar-core/src/org/briarproject/transport/TransportKeyManagerImpl.java b/briar-core/src/org/briarproject/transport/TransportKeyManagerImpl.java
index 3afd0ef92..72d0e444d 100644
--- a/briar-core/src/org/briarproject/transport/TransportKeyManagerImpl.java
+++ b/briar-core/src/org/briarproject/transport/TransportKeyManagerImpl.java
@@ -9,6 +9,7 @@ import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.system.Clock;
+import org.briarproject.api.system.Scheduler;
import org.briarproject.api.transport.StreamContext;
import org.briarproject.api.transport.TransportKeys;
import org.briarproject.transport.ReorderingWindow.Change;
@@ -48,7 +49,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
private final Map keys;
TransportKeyManagerImpl(DatabaseComponent db, CryptoComponent crypto,
- Executor dbExecutor, ScheduledExecutorService scheduler,
+ Executor dbExecutor, @Scheduler ScheduledExecutorService scheduler,
Clock clock, TransportId transportId, long maxLatency) {
this.db = db;
this.crypto = crypto;