Godot Version
4.3
Hello godot friends!
For context, I develop this tool over here: https://forum.godotengine.org/t/gdimagedb-a-tag-based-media-database-for-your-desktop/
Something that tool has to do a lot is to load image files from the OS filesystem on the fly.
Ideally that should happen asynchronously to not lock up the GUI and to allow background preloads.
Unfortunately I have been running into a lot of issues writing async code with godot.
The general problem:
I have run into lots of different scenarios that could cause random crashes. Apparently these are due to indirect async interactions with the scene tree, which are apparently completely forbidden.
Think instantiating a control node within another thread, then adding it to the tree in the main thread.
This would randomly (fairly rarely) crash outright, and with near 100% reproducibility crash on exit.
I have resolved to only load resources in threads, which appears to be mostly safe - except when it isn’t.
The question:
How do I asynchronously load and cache images on the fly without causing crashes on exit?
Apparently I can’t use the WorkerThreadPool since there is no threadsafe way to notify my code when a thread is finished. Calling (even deferred calling) a signal from a thread seems to cause crashes on exit - maybe. I am not actually sure what exactly causes the crash.
The documentation says to use wait_for_task_completion, but that cannot be correct since the WorkerThreadPool will remove finished threads with wait_for_task_completion returning INVALID_PARAMETER for the IDs of finished threads.
Apparently I can also not use regular threads - at the very least not if I want to cache the images (which is required) as they also cause crashes on exit.
It is very unclear to me what actually is and isn’t thread safe in godot.
Edit, more information:
These crashes themselves are completely outside of my code.
I have rewritten my entire loading and instantiation code in C# since I am more experienced in that language - same result.
I have even built and run debug builds of godot to try and get to the bottom of the problem, only to end up miles deep in invalid memory and completely out of my depth when it comes to c++ debugging.