Fix dead lock when switching from async to quick mode

This commit is contained in:
Jonas Herzig
2018-12-18 10:44:42 +01:00
parent c30520ad3d
commit 1670ed4e80
2 changed files with 13 additions and 7 deletions

View File

@@ -348,20 +348,22 @@ public class ReplayHandler {
public void setQuickMode(boolean quickMode) { public void setQuickMode(boolean quickMode) {
if (quickMode == this.quickMode) return; if (quickMode == this.quickMode) return;
if (quickMode && !fullReplaySender.isAsyncMode()) return; // Cannot activate quick mode when already in sync mode if (quickMode && fullReplaySender.isAsyncMode()) {
// If this method is called via runLater, then it cannot switch to sync mode by itself as there might be
// some rogue packets in the task queue after it. Instead the caller must switch to sync mode first and
// use runLater until all packets have been processed (when using setAsyncModeAndWait, one runLater should
// be sufficient).
throw new IllegalStateException("Cannot switch to quick mode while in async mode.");
}
this.quickMode = quickMode; this.quickMode = quickMode;
if (quickMode) { if (quickMode) {
fullReplaySender.setSyncModeAndWait();
quickReplaySender.register(); quickReplaySender.register();
quickReplaySender.restart(); quickReplaySender.restart();
quickReplaySender.sendPacketsTill(fullReplaySender.currentTimeStamp()); quickReplaySender.sendPacketsTill(fullReplaySender.currentTimeStamp());
quickReplaySender.setAsyncMode(true);
} else { } else {
quickReplaySender.setSyncModeAndWait();
quickReplaySender.unregister(); quickReplaySender.unregister();
fullReplaySender.sendPacketsTill(0); fullReplaySender.sendPacketsTill(0);
fullReplaySender.sendPacketsTill(quickReplaySender.currentTimeStamp()); fullReplaySender.sendPacketsTill(quickReplaySender.currentTimeStamp());
fullReplaySender.setAsyncMode(true);
} }
} }

View File

@@ -144,8 +144,12 @@ public class ReplayModReplay {
core.getKeyBindingRegistry().registerKeyBinding("replaymod.input.quickmode", Keyboard.KEY_Q, () -> { core.getKeyBindingRegistry().registerKeyBinding("replaymod.input.quickmode", Keyboard.KEY_Q, () -> {
if (replayHandler != null) { if (replayHandler != null) {
replayHandler.ensureQuickModeInitialized(() -> replayHandler.getReplaySender().setSyncModeAndWait();
replayHandler.setQuickMode(!replayHandler.isQuickMode())); core.runLater(() ->
replayHandler.ensureQuickModeInitialized(() -> {
replayHandler.setQuickMode(!replayHandler.isQuickMode());
replayHandler.getReplaySender().setAsyncMode(true);
}));
} }
}); });