kopia lustrzana https://github.com/ryukoposting/Signal-Android
Fix deadlock with web socket health monitor.
rodzic
4ba4df706e
commit
59ad8bf76a
|
@ -5,6 +5,7 @@ import android.app.Application;
|
|||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.signal.core.util.ThreadUtil;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.events.ReminderUpdateEvent;
|
||||
|
@ -17,6 +18,8 @@ import org.whispersystems.signalservice.api.websocket.HealthMonitor;
|
|||
import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState;
|
||||
import org.whispersystems.signalservice.internal.websocket.WebSocketConnection;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
|
@ -35,11 +38,13 @@ public final class SignalWebSocketHealthMonitor implements HealthMonitor {
|
|||
private static final long KEEP_ALIVE_SEND_CADENCE = TimeUnit.SECONDS.toMillis(WebSocketConnection.KEEPALIVE_TIMEOUT_SECONDS);
|
||||
private static final long MAX_TIME_SINCE_SUCCESSFUL_KEEP_ALIVE = KEEP_ALIVE_SEND_CADENCE * 3;
|
||||
|
||||
private final Executor executor = ThreadUtil.trace(Executors.newSingleThreadExecutor());
|
||||
|
||||
private final Application context;
|
||||
private SignalWebSocket signalWebSocket;
|
||||
private final SleepTimer sleepTimer;
|
||||
|
||||
private volatile KeepAliveSender keepAliveSender;
|
||||
private KeepAliveSender keepAliveSender;
|
||||
|
||||
private final HealthState identified = new HealthState();
|
||||
private final HealthState unidentified = new HealthState();
|
||||
|
@ -50,6 +55,7 @@ public final class SignalWebSocketHealthMonitor implements HealthMonitor {
|
|||
}
|
||||
|
||||
public void monitor(@NonNull SignalWebSocket signalWebSocket) {
|
||||
executor.execute(() -> {
|
||||
Preconditions.checkNotNull(signalWebSocket);
|
||||
Preconditions.checkArgument(this.signalWebSocket == null, "monitor can only be called once");
|
||||
|
||||
|
@ -68,9 +74,11 @@ public final class SignalWebSocketHealthMonitor implements HealthMonitor {
|
|||
.observeOn(Schedulers.computation())
|
||||
.distinctUntilChanged()
|
||||
.subscribe(s -> onStateChange(s, unidentified));
|
||||
});
|
||||
}
|
||||
|
||||
private synchronized void onStateChange(WebSocketConnectionState connectionState, HealthState healthState) {
|
||||
private void onStateChange(WebSocketConnectionState connectionState, HealthState healthState) {
|
||||
executor.execute(() -> {
|
||||
switch (connectionState) {
|
||||
case CONNECTED:
|
||||
TextSecurePreferences.setUnauthorizedReceived(context, false);
|
||||
|
@ -96,19 +104,23 @@ public final class SignalWebSocketHealthMonitor implements HealthMonitor {
|
|||
keepAliveSender.shutdown();
|
||||
keepAliveSender = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeepAliveResponse(long sentTimestamp, boolean isIdentifiedWebSocket) {
|
||||
executor.execute(() -> {
|
||||
if (isIdentifiedWebSocket) {
|
||||
identified.lastKeepAliveReceived = System.currentTimeMillis();
|
||||
} else {
|
||||
unidentified.lastKeepAliveReceived = System.currentTimeMillis();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageError(int status, boolean isIdentifiedWebSocket) {
|
||||
executor.execute(() -> {
|
||||
if (status == 409) {
|
||||
HealthState healthState = (isIdentifiedWebSocket ? identified : unidentified);
|
||||
if (healthState.mismatchErrorTracker.addSample(System.currentTimeMillis())) {
|
||||
|
@ -116,6 +128,7 @@ public final class SignalWebSocketHealthMonitor implements HealthMonitor {
|
|||
signalWebSocket.forceNewWebSockets();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isKeepAliveNecessary() {
|
||||
|
|
Ładowanie…
Reference in New Issue