From d224d6ea329a0bc7a37f18cb8bdbcb475add82bf Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Mon, 15 Mar 2021 18:33:21 +0000 Subject: [PATCH] Add synchronization to CharBlocks (#963) similar to ChunkHolder, it represents an internal chunk for which operations should not be accepted by multiple threads at once. Co-authored-by: NotMyFault --- .../implementation/blocks/CharBlocks.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java index e656cdb9d..d146043aa 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java @@ -62,7 +62,7 @@ public abstract class CharBlocks implements IBlocks { } @Override - public boolean trim(boolean aggressive) { + public synchronized boolean trim(boolean aggressive) { boolean result = true; for (int i = 0; i < 16; i++) { if (!sections[i].isFull() && blocks[i] != null) { @@ -75,7 +75,7 @@ public abstract class CharBlocks implements IBlocks { } @Override - public boolean trim(boolean aggressive, int layer) { + public synchronized boolean trim(boolean aggressive, int layer) { boolean result = true; if (!sections[layer].isFull() && blocks[layer] != null) { blocks[layer] = null; @@ -86,18 +86,18 @@ public abstract class CharBlocks implements IBlocks { } @Override - public IChunkSet reset() { + public synchronized IChunkSet reset() { for (int i = 0; i < 16; i++) { sections[i] = EMPTY; } return null; } - public void reset(@Range(from = 0, to = 15) int layer) { + public synchronized void reset(@Range(from = 0, to = 15) int layer) { sections[layer] = EMPTY; } - public char[] update(int layer, char[] data) { + public synchronized char[] update(int layer, char[] data) { if (data == null) { return new char[4096]; } @@ -107,22 +107,23 @@ public abstract class CharBlocks implements IBlocks { return data; } + // Not synchronized as any subsequent methods called from this class will be, or the section shouldn't appear as loaded anyway. @Override public boolean hasSection(@Range(from = 0, to = 15) int layer) { return sections[layer].isFull(); } @Override - public char[] load(@Range(from = 0, to = 15) int layer) { + public synchronized char[] load(@Range(from = 0, to = 15) int layer) { return sections[layer].get(this, layer); } @Override - public BlockState getBlock(int x, int y, int z) { + public synchronized BlockState getBlock(int x, int y, int z) { return BlockTypesCache.states[get(x, y, z)]; } - public char get(int x, @Range(from = 0, to = 255) int y, int z) { + public synchronized char get(int x, @Range(from = 0, to = 255) int y, int z) { final int layer = y >> 4; final int index = (y & 15) << 8 | z << 4 | x; if (layer >= sections.length || layer < 0) { @@ -131,6 +132,7 @@ public abstract class CharBlocks implements IBlocks { return sections[layer].get(this, layer, index); } + // Not synchronized as it refers to a synchronized method and includes nothing that requires synchronization public void set(int x, @Range(from = 0, to = 255) int y, int z, char value) { final int layer = y >> 4; final int index = (y & 15) << 8 | z << 4 | x; @@ -147,11 +149,11 @@ public abstract class CharBlocks implements IBlocks { Section */ - public final char get(@Range(from = 0, to = 15)int layer, int index) { + public synchronized final char get(@Range(from = 0, to = 15) int layer, int index) { return sections[layer].get(this, layer, index); } - public final void set(@Range(from = 0, to = 15) int layer, int index, char value) throws ArrayIndexOutOfBoundsException { + public synchronized final void set(@Range(from = 0, to = 15) int layer, int index, char value) throws ArrayIndexOutOfBoundsException { sections[layer].set(this, layer, index, value); }