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:
dordsor21
2021-01-13 19:02:51 +00:00
parent e94e3b7b05
commit be9866ddb3
6 changed files with 50 additions and 31 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);