mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Compare commits
3 Commits
variable-l
...
bluetooth-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb98cb2f23 | ||
|
|
aa331981cc | ||
|
|
e9a6faad2d |
@@ -28,7 +28,9 @@ import org.briarproject.bramble.api.system.Scheduler;
|
|||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
@@ -58,6 +60,7 @@ class Poller implements EventListener {
|
|||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
private final Lock lock;
|
private final Lock lock;
|
||||||
private final Map<TransportId, ScheduledPollTask> tasks; // Locking: lock
|
private final Map<TransportId, ScheduledPollTask> tasks; // Locking: lock
|
||||||
|
private final Set<TransportId> polling; // Locking: lock
|
||||||
|
|
||||||
Poller(@IoExecutor Executor ioExecutor,
|
Poller(@IoExecutor Executor ioExecutor,
|
||||||
@Scheduler ScheduledExecutorService scheduler,
|
@Scheduler ScheduledExecutorService scheduler,
|
||||||
@@ -75,6 +78,7 @@ class Poller implements EventListener {
|
|||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
lock = new ReentrantLock();
|
lock = new ReentrantLock();
|
||||||
tasks = new HashMap<>();
|
tasks = new HashMap<>();
|
||||||
|
polling = new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -241,20 +245,33 @@ class Poller implements EventListener {
|
|||||||
@Override
|
@Override
|
||||||
@IoExecutor
|
@IoExecutor
|
||||||
public void run() {
|
public void run() {
|
||||||
|
TransportId t = plugin.getId();
|
||||||
|
boolean shouldPoll;
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
TransportId t = plugin.getId();
|
|
||||||
ScheduledPollTask scheduled = tasks.get(t);
|
ScheduledPollTask scheduled = tasks.get(t);
|
||||||
if (scheduled != null && scheduled.task != this)
|
if (scheduled != null && scheduled.task != this)
|
||||||
return; // Replaced by another task
|
return; // Replaced by another task
|
||||||
tasks.remove(t);
|
tasks.remove(t);
|
||||||
|
// Don't poll again if last poll is still running
|
||||||
|
shouldPoll = polling.add(t);
|
||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
int delay = plugin.getPollingInterval();
|
int delay = plugin.getPollingInterval();
|
||||||
if (randomiseNext) delay = (int) (delay * random.nextDouble());
|
if (randomiseNext) delay = (int) (delay * random.nextDouble());
|
||||||
schedule(plugin, delay, false);
|
schedule(plugin, delay, false);
|
||||||
|
if (shouldPoll) {
|
||||||
poll(plugin);
|
poll(plugin);
|
||||||
|
} else if (LOG.isLoggable(INFO)) {
|
||||||
|
LOG.info("Last poll for " + t + " is still running");
|
||||||
|
}
|
||||||
|
lock.lock();
|
||||||
|
try {
|
||||||
|
polling.remove(t);
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,8 +26,10 @@ import org.briarproject.bramble.util.StringUtils;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
@@ -52,6 +54,12 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
|||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(BluetoothPlugin.class.getName());
|
Logger.getLogger(BluetoothPlugin.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How many milliseconds to pause between connection attempts when
|
||||||
|
* polling, to avoid interfering with other Bluetooth or wifi connections.
|
||||||
|
*/
|
||||||
|
private static final int POLLING_PAUSE_MS = 1000;
|
||||||
|
|
||||||
final BluetoothConnectionLimiter connectionLimiter;
|
final BluetoothConnectionLimiter connectionLimiter;
|
||||||
|
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
@@ -252,24 +260,39 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
|||||||
public void poll(Map<ContactId, TransportProperties> contacts) {
|
public void poll(Map<ContactId, TransportProperties> contacts) {
|
||||||
if (!isRunning() || !shouldAllowContactConnections()) return;
|
if (!isRunning() || !shouldAllowContactConnections()) return;
|
||||||
backoff.increment();
|
backoff.increment();
|
||||||
// Try to connect to known devices in parallel
|
// Try to connect to known devices in a random order
|
||||||
for (Entry<ContactId, TransportProperties> e : contacts.entrySet()) {
|
List<ContactId> keys = new ArrayList<>(contacts.keySet());
|
||||||
String address = e.getValue().get(PROP_ADDRESS);
|
Collections.shuffle(keys);
|
||||||
if (StringUtils.isNullOrEmpty(address)) continue;
|
|
||||||
String uuid = e.getValue().get(PROP_UUID);
|
|
||||||
if (StringUtils.isNullOrEmpty(uuid)) continue;
|
|
||||||
ContactId c = e.getKey();
|
|
||||||
ioExecutor.execute(() -> {
|
ioExecutor.execute(() -> {
|
||||||
|
boolean first = true;
|
||||||
|
for (ContactId c : keys) {
|
||||||
if (!isRunning() || !shouldAllowContactConnections()) return;
|
if (!isRunning() || !shouldAllowContactConnections()) return;
|
||||||
if (!connectionLimiter.canOpenContactConnection()) return;
|
if (!connectionLimiter.canOpenContactConnection()) return;
|
||||||
|
TransportProperties p = contacts.get(c);
|
||||||
|
String address = p.get(PROP_ADDRESS);
|
||||||
|
if (StringUtils.isNullOrEmpty(address)) continue;
|
||||||
|
String uuid = p.get(PROP_UUID);
|
||||||
|
if (StringUtils.isNullOrEmpty(uuid)) continue;
|
||||||
|
// Pause between connection attempts
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
Thread.sleep(POLLING_PAUSE_MS);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
LOG.info("Interrupted while polling");
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
DuplexTransportConnection conn = connect(address, uuid);
|
DuplexTransportConnection conn = connect(address, uuid);
|
||||||
if (conn != null) {
|
if (conn != null) {
|
||||||
backoff.reset();
|
backoff.reset();
|
||||||
if (connectionLimiter.contactConnectionOpened(conn))
|
if (connectionLimiter.contactConnectionOpened(conn))
|
||||||
callback.outgoingConnectionCreated(c, conn);
|
callback.outgoingConnectionCreated(c, conn);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
Reference in New Issue
Block a user