Better world lock

This commit is contained in:
Sotr
2018-06-16 20:36:18 +08:00
parent 1d9f3a0584
commit cf62349837
3 changed files with 17 additions and 4 deletions

View File

@@ -0,0 +1,5 @@
package io.akarin.api.internal.mixin;
public interface IMixinLockProvider {
public Object lock();
}

View File

@@ -17,6 +17,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import co.aikar.timings.MinecraftTimings; import co.aikar.timings.MinecraftTimings;
import io.akarin.api.internal.Akari; import io.akarin.api.internal.Akari;
import io.akarin.api.internal.mixin.IMixinLockProvider;
import io.akarin.server.core.AkarinGlobalConfig; import io.akarin.server.core.AkarinGlobalConfig;
import io.akarin.server.core.AkarinSlackScheduler; import io.akarin.server.core.AkarinSlackScheduler;
import net.minecraft.server.CrashReport; import net.minecraft.server.CrashReport;
@@ -144,10 +145,9 @@ public abstract class MixinMinecraftServer {
Akari.mayEnableAsyncCathcer = false; Akari.mayEnableAsyncCathcer = false;
Akari.STAGE_TICK.submit(() -> { Akari.STAGE_TICK.submit(() -> {
// Never tick one world concurrently! // Never tick one world concurrently!
// TODO better treat world index
for (int i = 1; i <= worlds.size(); ++i) { for (int i = 1; i <= worlds.size(); ++i) {
WorldServer world = worlds.get(i < worlds.size() ? i : 0); WorldServer world = worlds.get(i < worlds.size() ? i : 0);
synchronized (world) { synchronized (((IMixinLockProvider) world).lock()) {
tickEntities(world); tickEntities(world);
} }
} }
@@ -155,7 +155,7 @@ public abstract class MixinMinecraftServer {
for (int i = 0; i < worlds.size(); ++i) { for (int i = 0; i < worlds.size(); ++i) {
WorldServer world = worlds.get(i); WorldServer world = worlds.get(i);
synchronized (world) { synchronized (((IMixinLockProvider) world).lock()) {
tickWorld(world); tickWorld(world);
} }
} }

View File

@@ -4,13 +4,21 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Redirect;
import io.akarin.api.internal.mixin.IMixinLockProvider;
import net.minecraft.server.WorldServer; import net.minecraft.server.WorldServer;
@Mixin(value = WorldServer.class, remap = false) @Mixin(value = WorldServer.class, remap = false)
public abstract class MixinWorldServer { public abstract class MixinWorldServer implements IMixinLockProvider {
@Redirect(method = "doTick", at = @At( @Redirect(method = "doTick", at = @At(
value = "INVOKE", value = "INVOKE",
target = "net/minecraft/server/PlayerChunkMap.flush()V" target = "net/minecraft/server/PlayerChunkMap.flush()V"
)) ))
public void onFlush() {} // Migrated to main thread public void onFlush() {} // Migrated to main thread
private final Object tickLock = new Object();
@Override
public Object lock() {
return tickLock;
}
} }