-
-
Notifications
You must be signed in to change notification settings - Fork 293
Fix crash due to data race when removing block entity #3152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Is it better worth to locate the tiles async and only perform the removes synchronously, if required, rather than needing a (potentially pointless) main-thread task on every chunk call? |
Using the map returned by |
If the map is empty when we retrieve it I think it's acceptable to skip the main thread call entirely tbh. Otherwise yes I suppose it probably is best to iterate the map in the sync job. Also, with the previous changes made to the futures, I wonder if we want do something similar to how we handle the chunk load waiting by returning a future for the main thread operation, which continues with the operation when complete |
Checking whether the map is empty asynchronously is already flawed, so I don't think we can skip that.
I was thinking about that too, but that makes it more difficult to get things back to the threads we want to run it on, so I decided to go the easiest route for now. Maybe we should think about switching to e.g. an actor model in future, that would allow far more flexibility in such scenarios. |
Arguably the same can be said for the whole operation at that point. The rest of FAWE assumes the chunk isn't modified after reading (cached GET for masks could be cached a while) and halting everything awaiting a potentially empty main thread task feels suboptimal.
Currently after the chunk async load we just "resubmit" the task and return that future. Here we would submit a main thread task instead, which after completion would perform the resubmission to the FAWE queue(s) |
Please take a moment and address the merge conflicts of your pull request. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (5)
worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightGetBlocks.java:349
- Consider initializing beaconEntities with an empty ArrayList (e.g., new ArrayList<>()) rather than null to ensure a non-null return value, which can improve null-safety for later processing.
List<BlockEntity> beaconEntities = null;
worldedit-bukkit/adapters/adapter-1_21_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_3/PaperweightGetBlocks.java:349
- Consider initializing beaconEntities with an empty ArrayList immediately to avoid returning null if no beacon entities are found.
List<BlockEntity> beaconEntities = null;
worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks.java:351
- Consider initializing beaconEntities to new ArrayList<>() instead of null to ensure that the method returns a valid (even if empty) list.
List<BlockEntity> beaconEntities = null;
worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks.java:348
- Initialize beaconEntities with an empty ArrayList right away to avoid the potential for a null pointer later in the code.
List<BlockEntity> beaconEntities = null;
worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java:347
- It is recommended to initialize beaconEntities as a new ArrayList<>() immediately rather than null to avoid null-related issues downstream.
List<BlockEntity> beaconEntities = null;
List<BlockEntity> beacons = TaskManager.taskManager().sync(() -> { | ||
// Remove existing tiles. Create a copy so that we can remove blocks | ||
Map<BlockPos, BlockEntity> chunkTiles = new HashMap<>(nmsChunk.getBlockEntities()); | ||
List<BlockEntity> beaconEntities = null; |
Copilot
AI
Apr 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider initializing beaconEntities to new ArrayList<>() instead of null so that the method consistently returns a non-null list.
List<BlockEntity> beaconEntities = null; | |
List<BlockEntity> beaconEntities = new ArrayList<>(); |
Copilot uses AI. Check for mistakes.
Any news on this? |
Overview
Fixes #3151
Description
This is rather a quick fix for the server crash. Performance impact seems to be okay, but we might want to take a closer look in future. We could probably also use Minecraft's new tick freezing mechanism instead. The beacon special-casing can be removed too probably.
Submitter Checklist
@since TODO
.