Skip to content

Commit

Permalink
Fix Connection#isConnected race
Browse files Browse the repository at this point in the history
Regression from 1fdc9ef.

This is a Netty thing so not much can be done. Could effect
other places that only check for channel#isOpen or theoretically
mods but fixing the deadlock is more important.
  • Loading branch information
aromaa committed Dec 17, 2023
1 parent c01050f commit 57880c5
Showing 1 changed file with 14 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.common.SpongeMinecraftVersion;
import org.spongepowered.common.accessor.network.Connection_PacketHolderAccessor;
import org.spongepowered.common.bridge.network.ConnectionBridge;
Expand Down Expand Up @@ -80,6 +81,8 @@ public abstract class ConnectionMixin extends SimpleChannelInboundHandler<Packet

private ClientType impl$clientType = ClientType.VANILLA;

private volatile boolean impl$disconnected;

@Override
public TransactionStore bridge$getTransactionStore() {
return this.impl$transactionStore;
Expand Down Expand Up @@ -188,5 +191,16 @@ public abstract class ConnectionMixin extends SimpleChannelInboundHandler<Packet
@Inject(method = "disconnect", at = @At(value = "INVOKE", target = "Lio/netty/channel/ChannelFuture;awaitUninterruptibly()Lio/netty/channel/ChannelFuture;"), cancellable = true)
private void impl$disconnectAsync(final CallbackInfo ci) {
ci.cancel(); //This can cause deadlock within the event loop

//Because we are now disconnecting asynchronously the channel might not
//be immediately flagged as closed so special case it
this.impl$disconnected = true;
}

@Inject(method = "isConnected", at = @At("HEAD"), cancellable = true)
private void impl$onIsConnected(final CallbackInfoReturnable<Boolean> cir) {
if (this.impl$disconnected) {
cir.setReturnValue(false);
}
}
}

0 comments on commit 57880c5

Please sign in to comment.