tunnel: replace CompletableFuture with GhettoCompletableFuture

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jason A. Donenfeld 2020-03-12 01:13:24 -06:00
parent 78377a5c67
commit 86fc518585
2 changed files with 33 additions and 3 deletions

View File

@ -25,7 +25,6 @@ android {
dependencies {
api "net.sourceforge.streamsupport:android-retrostreams:$streamsupportVersion"
implementation "net.sourceforge.streamsupport:android-retrofuture:$streamsupportVersion"
implementation "androidx.annotation:annotation:$annotationsVersion"
implementation "androidx.collection:collection:$collectionVersion"
implementation "com.google.code.findbugs:jsr305:$jsr305Version"

View File

@ -24,18 +24,20 @@ import com.wireguard.util.NonNullForAll;
import java.net.InetAddress;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import androidx.annotation.Nullable;
import androidx.collection.ArraySet;
import java9.util.concurrent.CompletableFuture;
@NonNullForAll
public final class GoBackend implements Backend {
private static final String TAG = "WireGuard/" + GoBackend.class.getSimpleName();
@Nullable private static AlwaysOnCallback alwaysOnCallback;
private static CompletableFuture<VpnService> vpnService = new CompletableFuture<>();
private static GhettoCompletableFuture<VpnService> vpnService = new GhettoCompletableFuture<>();
private final Context context;
@Nullable private Config currentConfig;
@Nullable private Tunnel currentTunnel;
@ -247,6 +249,35 @@ public final class GoBackend implements Backend {
void alwaysOnTriggered();
}
// TODO: When we finally drop API 21 and move to API 24, delete this and replace with the ordinary CompletableFuture.
private static final class GhettoCompletableFuture<V> {
private final LinkedBlockingQueue<V> completion = new LinkedBlockingQueue<>(1);
private final FutureTask<V> result = new FutureTask<>(completion::peek);
public boolean complete(final V value) {
final boolean offered = completion.offer(value);
if (offered)
result.run();
return offered;
}
public V get() throws ExecutionException, InterruptedException {
return result.get();
}
public V get(final long timeout, final TimeUnit unit) throws ExecutionException, InterruptedException, TimeoutException {
return result.get(timeout, unit);
}
public boolean isDone() {
return !completion.isEmpty();
}
public GhettoCompletableFuture<V> newIncompleteFuture() {
return new GhettoCompletableFuture<>();
}
}
public static class VpnService extends android.net.VpnService {
@Nullable private GoBackend owner;