mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2024-12-22 17:27:38 +00:00
Fix a lot of FAWE-freezing properly
- Add a "loadPrivately" method to be used when GetChunks are called to avoid synchronocity issues with super classes being used on different threads - Synchronise the call method so we're not attempting to call whilst also loading/updating
This commit is contained in:
parent
e94e3b7b05
commit
be9866ddb3
@ -376,7 +376,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks implements BukkitGetBl
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
||||
public synchronized <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
||||
forceLoadSections = false;
|
||||
copy = createCopy ? new BukkitGetBlocks_1_15_2_Copy(world) : null;
|
||||
try {
|
||||
@ -424,7 +424,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks implements BukkitGetBl
|
||||
|
||||
char[] setArr = set.load(layer).clone();
|
||||
if (createCopy) {
|
||||
copy.storeSection(layer, load(layer).clone());
|
||||
copy.storeSection(layer, loadPrivately(layer).clone());
|
||||
}
|
||||
|
||||
ChunkSection newSection;
|
||||
@ -458,12 +458,12 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks implements BukkitGetBl
|
||||
} else if (existingSection != getSections(false)[layer]) {
|
||||
this.sections[layer] = existingSection;
|
||||
this.reset();
|
||||
} else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) {
|
||||
} else if (!Arrays.equals(update(layer, new char[4096]), loadPrivately(layer))) {
|
||||
this.reset(layer);
|
||||
} else if (lock.isModified()) {
|
||||
this.reset(layer);
|
||||
}
|
||||
newSection = BukkitAdapter_1_15_2.newChunkSection(layer, this::load, setArr, fastmode);
|
||||
newSection = BukkitAdapter_1_15_2.newChunkSection(layer, this::loadPrivately, setArr, fastmode);
|
||||
if (!BukkitAdapter_1_15_2.setSectionAtomic(sections, existingSection, newSection, layer)) {
|
||||
log.error("Failed to set chunk section:" + chunkX + "," + chunkZ + " layer: " + layer);
|
||||
} else {
|
||||
@ -676,6 +676,14 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks implements BukkitGetBl
|
||||
}
|
||||
}
|
||||
|
||||
private char[] loadPrivately(int layer) {
|
||||
if (super.sections[layer].isFull()) {
|
||||
return super.blocks[layer];
|
||||
} else {
|
||||
return BukkitGetBlocks_1_15_2.this.update(layer, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void send(int mask, boolean lighting) {
|
||||
BukkitAdapter_1_15_2.sendChunk(world, chunkX, chunkZ, mask, lighting);
|
||||
|
@ -376,7 +376,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks implements BukkitGetBl
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
||||
public synchronized <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
||||
forceLoadSections = false;
|
||||
copy = createCopy ? new BukkitGetBlocks_1_16_1_Copy(world) : null;
|
||||
try {
|
||||
@ -424,7 +424,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks implements BukkitGetBl
|
||||
|
||||
char[] setArr = set.load(layer).clone();
|
||||
if (createCopy) {
|
||||
copy.storeSection(layer, load(layer).clone());
|
||||
copy.storeSection(layer, loadPrivately(layer).clone());
|
||||
}
|
||||
|
||||
ChunkSection newSection;
|
||||
@ -458,13 +458,13 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks implements BukkitGetBl
|
||||
} else if (existingSection != getSections(false)[layer]) {
|
||||
this.sections[layer] = existingSection;
|
||||
this.reset();
|
||||
} else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) {
|
||||
} else if (!Arrays.equals(update(layer, new char[4096]), loadPrivately(layer))) {
|
||||
this.reset(layer);
|
||||
} else if (lock.isModified()) {
|
||||
this.reset(layer);
|
||||
}
|
||||
newSection = BukkitAdapter_1_16_1
|
||||
.newChunkSection(layer, this::load, setArr, fastmode);
|
||||
.newChunkSection(layer, this::loadPrivately, setArr, fastmode);
|
||||
if (!BukkitAdapter_1_16_1
|
||||
.setSectionAtomic(sections, existingSection, newSection, layer)) {
|
||||
log.error("Failed to set chunk section:" + chunkX + "," + chunkZ + " layer: " + layer);
|
||||
@ -678,6 +678,14 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks implements BukkitGetBl
|
||||
}
|
||||
}
|
||||
|
||||
private char[] loadPrivately(int layer) {
|
||||
if (super.sections[layer].isFull()) {
|
||||
return super.blocks[layer];
|
||||
} else {
|
||||
return BukkitGetBlocks_1_16_1.this.update(layer, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void send(int mask, boolean lighting) {
|
||||
BukkitAdapter_1_16_1.sendChunk(world, chunkX, chunkZ, mask, lighting);
|
||||
|
@ -379,7 +379,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks implements BukkitGetBl
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
||||
public synchronized <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
||||
forceLoadSections = false;
|
||||
copy = createCopy ? new BukkitGetBlocks_1_16_2_Copy(world) : null;
|
||||
try {
|
||||
@ -427,7 +427,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks implements BukkitGetBl
|
||||
|
||||
char[] setArr = set.load(layer).clone();
|
||||
if (createCopy) {
|
||||
copy.storeSection(layer, load(layer).clone());
|
||||
copy.storeSection(layer, loadPrivately(layer).clone());
|
||||
}
|
||||
|
||||
ChunkSection newSection;
|
||||
@ -461,13 +461,13 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks implements BukkitGetBl
|
||||
} else if (existingSection != getSections(false)[layer]) {
|
||||
this.sections[layer] = existingSection;
|
||||
this.reset();
|
||||
} else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) {
|
||||
} else if (!Arrays.equals(update(layer, new char[4096]), loadPrivately(layer))) {
|
||||
this.reset(layer);
|
||||
} else if (lock.isModified()) {
|
||||
this.reset(layer);
|
||||
}
|
||||
newSection = BukkitAdapter_1_16_2
|
||||
.newChunkSection(layer, this::load, setArr, fastmode);
|
||||
.newChunkSection(layer, this::loadPrivately, setArr, fastmode);
|
||||
if (!BukkitAdapter_1_16_2
|
||||
.setSectionAtomic(sections, existingSection, newSection, layer)) {
|
||||
log.error("Failed to set chunk section:" + chunkX + "," + chunkZ + " layer: " + layer);
|
||||
@ -681,6 +681,14 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks implements BukkitGetBl
|
||||
}
|
||||
}
|
||||
|
||||
private char[] loadPrivately(int layer) {
|
||||
if (super.sections[layer].isFull()) {
|
||||
return super.blocks[layer];
|
||||
} else {
|
||||
return BukkitGetBlocks_1_16_2.this.update(layer, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void send(int mask, boolean lighting) {
|
||||
BukkitAdapter_1_16_2.sendChunk(world, chunkX, chunkZ, mask, lighting);
|
||||
|
@ -379,7 +379,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBl
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
||||
public synchronized <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
||||
forceLoadSections = false;
|
||||
copy = createCopy ? new BukkitGetBlocks_1_16_4_Copy(world) : null;
|
||||
try {
|
||||
@ -427,7 +427,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBl
|
||||
|
||||
char[] setArr = set.load(layer).clone();
|
||||
if (createCopy) {
|
||||
copy.storeSection(layer, load(layer).clone());
|
||||
copy.storeSection(layer, loadPrivately(layer).clone());
|
||||
}
|
||||
|
||||
ChunkSection newSection;
|
||||
@ -461,13 +461,13 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBl
|
||||
} else if (existingSection != getSections(false)[layer]) {
|
||||
this.sections[layer] = existingSection;
|
||||
this.reset();
|
||||
} else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) {
|
||||
} else if (!Arrays.equals(update(layer, new char[4096]), loadPrivately(layer))) {
|
||||
this.reset(layer);
|
||||
} else if (lock.isModified()) {
|
||||
this.reset(layer);
|
||||
}
|
||||
newSection = BukkitAdapter_1_16_4
|
||||
.newChunkSection(layer, this::load, setArr, fastmode);
|
||||
.newChunkSection(layer, this::loadPrivately, setArr, fastmode);
|
||||
if (!BukkitAdapter_1_16_4
|
||||
.setSectionAtomic(sections, existingSection, newSection, layer)) {
|
||||
log.error("Failed to set chunk section:" + chunkX + "," + chunkZ + " layer: " + layer);
|
||||
@ -681,6 +681,14 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks implements BukkitGetBl
|
||||
}
|
||||
}
|
||||
|
||||
private char[] loadPrivately(int layer) {
|
||||
if (super.sections[layer].isFull()) {
|
||||
return super.blocks[layer];
|
||||
} else {
|
||||
return BukkitGetBlocks_1_16_4.this.update(layer, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void send(int mask, boolean lighting) {
|
||||
BukkitAdapter_1_16_4.sendChunk(world, chunkX, chunkZ, mask, lighting);
|
||||
|
@ -9,8 +9,6 @@ import org.jetbrains.annotations.Range;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public abstract class CharBlocks implements IBlocks {
|
||||
|
||||
public static final Logger logger = LoggerFactory.getLogger(CharBlocks.class);
|
||||
|
@ -250,19 +250,8 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen
|
||||
// - memory is low & queue size > num threads + 8
|
||||
// - queue size > target size and primary queue has less than num threads submissions
|
||||
if (enabledQueue && ((lowMem && size > Settings.IMP.QUEUE.PARALLEL_THREADS + 8) || (size > Settings.IMP.QUEUE.TARGET_SIZE && Fawe.get().getQueueHandler().isUnderutilized()))) {
|
||||
int i = 0;
|
||||
boolean found = false;
|
||||
while (i < chunks.size() && (chunk = chunks.get(i)) != null) {
|
||||
if (Thread.holdsLock(chunk)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
Future future = null;
|
||||
if (found) {
|
||||
future = submitUnchecked(chunk);
|
||||
}
|
||||
chunk = chunks.removeFirst();
|
||||
final Future future = submitUnchecked(chunk);
|
||||
if (future != null && !future.isDone()) {
|
||||
final int targetSize;
|
||||
if (lowMem) {
|
||||
|
Loading…
Reference in New Issue
Block a user