Skip to content

Commit

Permalink
Don't attempt to notify chunk updates while generating
Browse files Browse the repository at this point in the history
Signed-off-by: Ross Allan <rallanpcl@gmail.com>
  • Loading branch information
LunNova committed Feb 5, 2013
1 parent 29811ee commit 678928a
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 30 deletions.
61 changes: 33 additions & 28 deletions src/common/me/nallar/patched/PatchChunkProviderServer.java
Expand Up @@ -192,42 +192,47 @@ public Chunk loadChunk(int x, int z) {
// Lock the generation lock - ChunkProviderGenerate isn't threadsafe at all
// TODO: Possibly make ChunkProviderGenerate threadlocal? Would need many changes to
// structure code to get it to work properly.
synchronized (genLock) {
synchronized (lock) {
var5 = (Chunk) this.loadedChunkHashMap.getValueByKey(var3);
if (var5 != null) {
return var5;
}
var5 = (Chunk) this.loadingChunkHashMap.getValueByKey(var3);
if (var5 == null) {
if (this.currentChunkProvider == null) {
var5 = this.defaultEmptyChunk;
try {
synchronized (genLock) {
synchronized (lock) {
worldObj.worldGenInProgress.set(true);
var5 = (Chunk) this.loadedChunkHashMap.getValueByKey(var3);
if (var5 != null) {
return var5;
}
var5 = (Chunk) this.loadingChunkHashMap.getValueByKey(var3);
if (var5 == null) {
if (this.currentChunkProvider == null) {
var5 = this.defaultEmptyChunk;
} else {
try {
var5 = this.currentChunkProvider.provideChunk(x, z);
} catch (Throwable var9) {
Log.severe("Failed to generate a chunk in " + Log.name(worldObj) + " at chunk coords " + x + ',' + z);
UnsafeAccess.$.throwException(var9);
}
}
} else {
try {
var5 = this.currentChunkProvider.provideChunk(x, z);
} catch (Throwable var9) {
Log.severe("Failed to generate a chunk in " + Log.name(worldObj) + " at chunk coords " + x + ',' + z);
UnsafeAccess.$.throwException(var9);
if (this.currentChunkProvider != null) {
this.currentChunkProvider.recreateStructures(x, z);
}
}
} else {
if (this.currentChunkProvider != null) {
this.currentChunkProvider.recreateStructures(x, z);

if (var5 == null) {
throw new IllegalStateException("Null chunk was provided!");
}
}

if (var5 == null) {
throw new IllegalStateException("Null chunk was provided!");
}
this.loadingChunkHashMap.remove(var3);
this.loadedChunkHashMap.add(var3, var5);
synchronized (loadedChunks) {
this.loadedChunks.add(var5);
}

this.loadingChunkHashMap.remove(var3);
this.loadedChunkHashMap.add(var3, var5);
synchronized (loadedChunks) {
this.loadedChunks.add(var5);
var5.populateChunk(this, this, x, z);
}

var5.populateChunk(this, this, x, z);
}
} finally {
worldObj.worldGenInProgress.set(false);
}

// TODO: Do initial mob spawning here - doing it while locked is stupid and can cause deadlocks with some bukkit plugins
Expand Down
5 changes: 3 additions & 2 deletions src/common/me/nallar/patched/PatchPlayerManagerForge.java
Expand Up @@ -5,15 +5,16 @@

import me.nallar.tickthreading.Log;
import me.nallar.tickthreading.patcher.Declare;
import me.nallar.tickthreading.util.concurrent.TwoWayReentrantReadWriteLock;
import net.minecraft.server.management.PlayerInstance;
import net.minecraft.server.management.PlayerManager;
import net.minecraft.world.WorldServer;

public abstract class PatchPlayerManagerForge extends PlayerManager {
@Declare
public java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock playerUpdateLock_;
public java.util.concurrent.locks.Lock playerUpdateLock_;
@Declare
public java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock playersUpdateLock_;
public java.util.concurrent.locks.Lock playersUpdateLock_;

public void construct() {
ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
Expand Down
22 changes: 22 additions & 0 deletions src/common/me/nallar/patched/PatchWorldServer.java
Expand Up @@ -21,6 +21,7 @@
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ReportedException;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.IWorldAccess;
import net.minecraft.world.NextTickListEntry;
import net.minecraft.world.SpawnerAnimals;
import net.minecraft.world.Teleporter;
Expand All @@ -37,6 +38,8 @@ public abstract class PatchWorldServer extends WorldServer implements Runnable {
private ThreadManager threadManager;
private ThreadLocal<Random> randoms;
@Declare
public ThreadLocal<Boolean> worldGenInProgress_;
@Declare
public int tickCount_;

public PatchWorldServer(MinecraftServer par1MinecraftServer, ISaveHandler par2ISaveHandler, String par3Str, int par4, WorldSettings par5WorldSettings, Profiler par6Profiler) {
Expand All @@ -48,6 +51,7 @@ public void construct() {
threadManager = new ThreadManager(TickThreading.instance.getThreadCount(), "Chunk Updates for " + Log.name(this));
field_73064_N = null;
pendingTickListEntries = new TreeHashSet();
worldGenInProgress = new BooleanThreadLocal();
}

@Override
Expand Down Expand Up @@ -376,4 +380,22 @@ public Random initialValue() {
return new Random();
}
}

@Override
public void markBlockForUpdate(int par1, int par2, int par3)
{
if (!worldGenInProgress.get()) {
for (int var4 = 0; var4 < this.worldAccesses.size(); ++var4)
{
((IWorldAccess)this.worldAccesses.get(var4)).markBlockForUpdate(par1, par2, par3);
}
}
}

public static class BooleanThreadLocal extends ThreadLocal<Boolean> {
@Override
public Boolean initialValue() {
return false;
}
}
}

0 comments on commit 678928a

Please sign in to comment.