Merge branch '1759-fix-periodic-task-cancellation' into 'master'

Fix cancellation of periodic tasks, remove ticker

Closes #1759

See merge request briar/briar!1274
This commit is contained in:
Torsten Grote
2020-08-14 12:47:20 +00:00
7 changed files with 129 additions and 75 deletions

View File

@@ -4,6 +4,7 @@ import org.briarproject.bramble.api.io.TimeoutMonitor;
import org.briarproject.bramble.api.lifecycle.IoExecutor;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.TaskScheduler;
import org.briarproject.bramble.api.system.TaskScheduler.Cancellable;
import org.briarproject.bramble.api.system.Wakeful;
import java.io.IOException;
@@ -11,7 +12,6 @@ import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
import java.util.logging.Logger;
import javax.annotation.concurrent.GuardedBy;
@@ -38,7 +38,7 @@ class TimeoutMonitorImpl implements TimeoutMonitor {
private final List<TimeoutInputStream> streams = new ArrayList<>();
@GuardedBy("lock")
private Future<?> task = null;
private Cancellable cancellable = null;
@Inject
TimeoutMonitorImpl(TaskScheduler scheduler,
@@ -55,9 +55,9 @@ class TimeoutMonitorImpl implements TimeoutMonitor {
timeoutMs, this::removeStream);
synchronized (lock) {
if (streams.isEmpty()) {
task = scheduler.scheduleWithFixedDelay(this::checkTimeouts,
ioExecutor, CHECK_INTERVAL_MS, CHECK_INTERVAL_MS,
MILLISECONDS);
cancellable = scheduler.scheduleWithFixedDelay(
this::checkTimeouts, ioExecutor, CHECK_INTERVAL_MS,
CHECK_INTERVAL_MS, MILLISECONDS);
}
streams.add(stream);
}
@@ -65,14 +65,17 @@ class TimeoutMonitorImpl implements TimeoutMonitor {
}
private void removeStream(TimeoutInputStream stream) {
Future<?> toCancel = null;
Cancellable toCancel = null;
synchronized (lock) {
if (streams.remove(stream) && streams.isEmpty()) {
toCancel = task;
task = null;
toCancel = cancellable;
cancellable = null;
}
}
if (toCancel != null) toCancel.cancel(false);
if (toCancel != null) {
LOG.info("Cancelling timeout monitor task");
toCancel.cancel();
}
}
@IoExecutor

View File

@@ -27,6 +27,7 @@ import org.briarproject.bramble.api.properties.TransportProperties;
import org.briarproject.bramble.api.properties.TransportPropertyManager;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.TaskScheduler;
import org.briarproject.bramble.api.system.TaskScheduler.Cancellable;
import org.briarproject.bramble.api.system.Wakeful;
import org.briarproject.bramble.api.system.WakefulIoExecutor;
@@ -37,7 +38,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Logger;
@@ -191,11 +191,11 @@ class PollerImpl implements Poller, EventListener {
if (scheduled == null || due < scheduled.task.due) {
// If a later task exists, cancel it. If it's already started
// it will abort safely when it finds it's been replaced
if (scheduled != null) scheduled.future.cancel(false);
if (scheduled != null) scheduled.cancellable.cancel();
PollTask task = new PollTask(p, due, randomiseNext);
Future<?> future = scheduler.schedule(task, ioExecutor, delay,
MILLISECONDS);
tasks.put(t, new ScheduledPollTask(task, future));
Cancellable cancellable = scheduler.schedule(task, ioExecutor,
delay, MILLISECONDS);
tasks.put(t, new ScheduledPollTask(task, cancellable));
}
} finally {
lock.unlock();
@@ -206,7 +206,7 @@ class PollerImpl implements Poller, EventListener {
lock.lock();
try {
ScheduledPollTask scheduled = tasks.remove(t);
if (scheduled != null) scheduled.future.cancel(false);
if (scheduled != null) scheduled.cancellable.cancel();
} finally {
lock.unlock();
}
@@ -237,11 +237,11 @@ class PollerImpl implements Poller, EventListener {
private class ScheduledPollTask {
private final PollTask task;
private final Future<?> future;
private final Cancellable cancellable;
private ScheduledPollTask(PollTask task, Future<?> future) {
private ScheduledPollTask(PollTask task, Cancellable cancellable) {
this.task = task;
this.future = future;
this.cancellable = cancellable;
}
}

View File

@@ -4,8 +4,8 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.system.TaskScheduler;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import javax.annotation.concurrent.ThreadSafe;
@@ -24,17 +24,20 @@ class TaskSchedulerImpl implements TaskScheduler {
}
@Override
public Future<?> schedule(Runnable task, Executor executor, long delay,
public Cancellable schedule(Runnable task, Executor executor, long delay,
TimeUnit unit) {
Runnable execute = () -> executor.execute(task);
return scheduledExecutorService.schedule(execute, delay, unit);
ScheduledFuture<?> future =
scheduledExecutorService.schedule(execute, delay, unit);
return () -> future.cancel(false);
}
@Override
public Future<?> scheduleWithFixedDelay(Runnable task, Executor executor,
public Cancellable scheduleWithFixedDelay(Runnable task, Executor executor,
long delay, long interval, TimeUnit unit) {
Runnable execute = () -> executor.execute(task);
return scheduledExecutorService.scheduleWithFixedDelay(execute, delay,
interval, unit);
ScheduledFuture<?> future = scheduledExecutorService.
scheduleWithFixedDelay(execute, delay, interval, unit);
return () -> future.cancel(false);
}
}