Skip to content

Commit 01ea271

Browse files
authored
Fix crash due to race condition when calling markUnsaved (#3351)
1 parent e2af5b4 commit 01ea271

File tree

8 files changed

+94
-183
lines changed

8 files changed

+94
-183
lines changed

worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ protected <T extends Future<T>> T internalCall(
590590
set.getMaxSectionPosition()
591591
);
592592

593-
Runnable[] syncTasks = null;
593+
List<Runnable> syncTasks = new ArrayList<>();
594594

595595
int bx = chunkX << 4;
596596
int bz = chunkZ << 4;
@@ -599,24 +599,17 @@ protected <T extends Future<T>> T internalCall(
599599
// list will be null on spigot, so this is an implicit isPaper check
600600
if (beacons != null && !beacons.isEmpty()) {
601601
final List<BlockEntity> finalBeacons = beacons;
602-
603-
syncTasks = new Runnable[4];
604-
605-
syncTasks[3] = () -> {
602+
syncTasks.add(() -> {
606603
for (BlockEntity beacon : finalBeacons) {
607604
BeaconBlockEntity.playSound(beacon.getLevel(), beacon.getBlockPos(), SoundEvents.BEACON_DEACTIVATE);
608605
new BeaconDeactivatedEvent(CraftBlock.at(beacon.getLevel(), beacon.getBlockPos())).callEvent();
609606
}
610-
};
607+
});
611608
}
612609

613610
Set<UUID> entityRemoves = set.getEntityRemoves();
614611
if (entityRemoves != null && !entityRemoves.isEmpty()) {
615-
if (syncTasks == null) {
616-
syncTasks = new Runnable[3];
617-
}
618-
619-
syncTasks[2] = () -> {
612+
syncTasks.add(() -> {
620613
Set<UUID> entitiesRemoved = new HashSet<>();
621614
final List<Entity> entities = PaperweightPlatformAdapter.getEntities(nmsChunk);
622615

@@ -642,16 +635,12 @@ protected <T extends Future<T>> T internalCall(
642635
// Only save entities that were actually removed to history
643636
set.getEntityRemoves().clear();
644637
set.getEntityRemoves().addAll(entitiesRemoved);
645-
};
638+
});
646639
}
647640

648641
Collection<FaweCompoundTag> entities = set.entities();
649642
if (entities != null && !entities.isEmpty()) {
650-
if (syncTasks == null) {
651-
syncTasks = new Runnable[2];
652-
}
653-
654-
syncTasks[1] = () -> {
643+
syncTasks.add(() -> {
655644
Iterator<FaweCompoundTag> iterator = entities.iterator();
656645
while (iterator.hasNext()) {
657646
final FaweCompoundTag nativeTag = iterator.next();
@@ -696,17 +685,13 @@ protected <T extends Future<T>> T internalCall(
696685
}
697686
}
698687
}
699-
};
688+
});
700689
}
701690

702691
// set tiles
703692
Map<BlockVector3, FaweCompoundTag> tiles = set.tiles();
704693
if (tiles != null && !tiles.isEmpty()) {
705-
if (syncTasks == null) {
706-
syncTasks = new Runnable[1];
707-
}
708-
709-
syncTasks[0] = () -> {
694+
syncTasks.add(() -> {
710695
for (final Map.Entry<BlockVector3, FaweCompoundTag> entry : tiles.entrySet()) {
711696
final FaweCompoundTag nativeTag = entry.getValue();
712697
final BlockVector3 blockHash = entry.getKey();
@@ -730,19 +715,21 @@ protected <T extends Future<T>> T internalCall(
730715
}
731716
}
732717
}
733-
};
718+
});
734719
}
735720

736721
Runnable callback;
737722
if (bitMask == 0 && biomes == null && !lightUpdate) {
738723
callback = null;
739724
} else {
740725
int finalMask = bitMask != 0 ? bitMask : lightUpdate ? set.getBitMask() : 0;
741-
callback = () -> {
726+
syncTasks.add(() -> {
742727
// Set Modified
743-
nmsChunk.setLightCorrect(true); // Set Modified
728+
nmsChunk.setLightCorrect(true);
744729
nmsChunk.mustNotSave = false;
745730
nmsChunk.setUnsaved(true);
731+
});
732+
callback = () -> {
746733
// send to player
747734
if (!set
748735
.getSideEffectSet()

worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ protected <T extends Future<T>> T internalCall(
590590
set.getMaxSectionPosition()
591591
);
592592

593-
Runnable[] syncTasks = null;
593+
List<Runnable> syncTasks = new ArrayList<>();
594594

595595
int bx = chunkX << 4;
596596
int bz = chunkZ << 4;
@@ -599,24 +599,17 @@ protected <T extends Future<T>> T internalCall(
599599
// list will be null on spigot, so this is an implicit isPaper check
600600
if (beacons != null && !beacons.isEmpty()) {
601601
final List<BlockEntity> finalBeacons = beacons;
602-
603-
syncTasks = new Runnable[4];
604-
605-
syncTasks[3] = () -> {
602+
syncTasks.add(() -> {
606603
for (BlockEntity beacon : finalBeacons) {
607604
BeaconBlockEntity.playSound(beacon.getLevel(), beacon.getBlockPos(), SoundEvents.BEACON_DEACTIVATE);
608605
new BeaconDeactivatedEvent(CraftBlock.at(beacon.getLevel(), beacon.getBlockPos())).callEvent();
609606
}
610-
};
607+
});
611608
}
612609

613610
Set<UUID> entityRemoves = set.getEntityRemoves();
614611
if (entityRemoves != null && !entityRemoves.isEmpty()) {
615-
if (syncTasks == null) {
616-
syncTasks = new Runnable[3];
617-
}
618-
619-
syncTasks[2] = () -> {
612+
syncTasks.add(() -> {
620613
Set<UUID> entitiesRemoved = new HashSet<>();
621614
final List<Entity> entities = PaperweightPlatformAdapter.getEntities(nmsChunk);
622615

@@ -642,16 +635,12 @@ protected <T extends Future<T>> T internalCall(
642635
// Only save entities that were actually removed to history
643636
set.getEntityRemoves().clear();
644637
set.getEntityRemoves().addAll(entitiesRemoved);
645-
};
638+
});
646639
}
647640

648641
Collection<FaweCompoundTag> entities = set.entities();
649642
if (entities != null && !entities.isEmpty()) {
650-
if (syncTasks == null) {
651-
syncTasks = new Runnable[2];
652-
}
653-
654-
syncTasks[1] = () -> {
643+
syncTasks.add(() -> {
655644
Iterator<FaweCompoundTag> iterator = entities.iterator();
656645
while (iterator.hasNext()) {
657646
final FaweCompoundTag nativeTag = iterator.next();
@@ -697,17 +686,13 @@ protected <T extends Future<T>> T internalCall(
697686
}
698687
}
699688
}
700-
};
689+
});
701690
}
702691

703692
// set tiles
704693
Map<BlockVector3, FaweCompoundTag> tiles = set.tiles();
705694
if (tiles != null && !tiles.isEmpty()) {
706-
if (syncTasks == null) {
707-
syncTasks = new Runnable[1];
708-
}
709-
710-
syncTasks[0] = () -> {
695+
syncTasks.add(() -> {
711696
for (final Map.Entry<BlockVector3, FaweCompoundTag> entry : tiles.entrySet()) {
712697
final FaweCompoundTag nativeTag = entry.getValue();
713698
final BlockVector3 blockHash = entry.getKey();
@@ -731,19 +716,21 @@ protected <T extends Future<T>> T internalCall(
731716
}
732717
}
733718
}
734-
};
719+
});
735720
}
736721

737722
Runnable callback;
738723
if (bitMask == 0 && biomes == null && !lightUpdate) {
739724
callback = null;
740725
} else {
741726
int finalMask = bitMask != 0 ? bitMask : lightUpdate ? set.getBitMask() : 0;
742-
callback = () -> {
727+
syncTasks.add(() -> {
743728
// Set Modified
744-
nmsChunk.setLightCorrect(true); // Set Modified
729+
nmsChunk.setLightCorrect(true);
745730
nmsChunk.mustNotSave = false;
746731
nmsChunk.setUnsaved(true);
732+
});
733+
callback = () -> {
747734
// send to player
748735
if (!set
749736
.getSideEffectSet()

worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks.java

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ protected <T extends Future<T>> T internalCall(
591591
set.getMaxSectionPosition()
592592
);
593593

594-
Runnable[] syncTasks = null;
594+
List<Runnable> syncTasks = new ArrayList<>();
595595

596596
int bx = chunkX << 4;
597597
int bz = chunkZ << 4;
@@ -600,24 +600,17 @@ protected <T extends Future<T>> T internalCall(
600600
// list will be null on spigot, so this is an implicit isPaper check
601601
if (beacons != null && !beacons.isEmpty()) {
602602
final List<BlockEntity> finalBeacons = beacons;
603-
604-
syncTasks = new Runnable[4];
605-
606-
syncTasks[3] = () -> {
603+
syncTasks.add(() -> {
607604
for (BlockEntity beacon : finalBeacons) {
608605
BeaconBlockEntity.playSound(beacon.getLevel(), beacon.getBlockPos(), SoundEvents.BEACON_DEACTIVATE);
609606
new BeaconDeactivatedEvent(CraftBlock.at(beacon.getLevel(), beacon.getBlockPos())).callEvent();
610607
}
611-
};
608+
});
612609
}
613610

614611
Set<UUID> entityRemoves = set.getEntityRemoves();
615612
if (entityRemoves != null && !entityRemoves.isEmpty()) {
616-
if (syncTasks == null) {
617-
syncTasks = new Runnable[3];
618-
}
619-
620-
syncTasks[2] = () -> {
613+
syncTasks.add(() -> {
621614
Set<UUID> entitiesRemoved = new HashSet<>();
622615
final List<Entity> entities = PaperweightPlatformAdapter.getEntities(nmsChunk);
623616

@@ -643,16 +636,12 @@ protected <T extends Future<T>> T internalCall(
643636
// Only save entities that were actually removed to history
644637
set.getEntityRemoves().clear();
645638
set.getEntityRemoves().addAll(entitiesRemoved);
646-
};
639+
});
647640
}
648641

649642
Collection<FaweCompoundTag> entities = set.entities();
650643
if (entities != null && !entities.isEmpty()) {
651-
if (syncTasks == null) {
652-
syncTasks = new Runnable[2];
653-
}
654-
655-
syncTasks[1] = () -> {
644+
syncTasks.add(() -> {
656645
Iterator<FaweCompoundTag> iterator = entities.iterator();
657646
while (iterator.hasNext()) {
658647
final FaweCompoundTag nativeTag = iterator.next();
@@ -698,17 +687,13 @@ protected <T extends Future<T>> T internalCall(
698687
}
699688
}
700689
}
701-
};
690+
});
702691
}
703692

704693
// set tiles
705694
Map<BlockVector3, FaweCompoundTag> tiles = set.tiles();
706695
if (tiles != null && !tiles.isEmpty()) {
707-
if (syncTasks == null) {
708-
syncTasks = new Runnable[1];
709-
}
710-
711-
syncTasks[0] = () -> {
696+
syncTasks.add(() -> {
712697
for (final Map.Entry<BlockVector3, FaweCompoundTag> entry : tiles.entrySet()) {
713698
final FaweCompoundTag nativeTag = entry.getValue();
714699
final BlockVector3 blockHash = entry.getKey();
@@ -732,19 +717,21 @@ protected <T extends Future<T>> T internalCall(
732717
}
733718
}
734719
}
735-
};
720+
});
736721
}
737722

738723
Runnable callback;
739724
if (bitMask == 0 && biomes == null && !lightUpdate) {
740725
callback = null;
741726
} else {
742727
int finalMask = bitMask != 0 ? bitMask : lightUpdate ? set.getBitMask() : 0;
743-
callback = () -> {
728+
syncTasks.add(() -> {
744729
// Set Modified
745-
nmsChunk.setLightCorrect(true); // Set Modified
730+
nmsChunk.setLightCorrect(true);
746731
nmsChunk.mustNotSave = false;
747732
nmsChunk.setUnsaved(true);
733+
});
734+
callback = () -> {
748735
// send to player
749736
if (!set
750737
.getSideEffectSet()

0 commit comments

Comments
 (0)