Better world lock
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
package io.akarin.api.internal.mixin;
|
||||||
|
|
||||||
|
public interface IMixinLockProvider {
|
||||||
|
public Object lock();
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user