[C#] Fix thread deadlock when using a worker thread to load a script with a generic base class #99798
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fix for #99839 and #99128
Currently, if we use either a worker thread with
ResourceLoader::load()
or useResourceLoader::load_threaded_request()
, and try to load any resource with a dependency on a script that inherits a generic C# class, we run into a_scriptTypeBiMap.ReadWriteLock
deadlock.This happens in a very specific circumstance:
ResourceLoader::load()
call from insidegodot_sharp_internal_script_load
to spin up a separate worker thread to load the dependency base scriptReadWriteLock
from when we were loading it's child scriptThis PR addresses this by moving the call to
godot_sharp_internal_reload_registered_script
after we've unlocked the lock on the BiMap. This method doesn't need, and in fact shouldn't be run while we're locked. This has made it necessary to always call this method after we callCreateScriptBridgeForType
from inside the lock, however that method has only two callsites at the moment, so it wasn't a difficult change to make.To make sure the method is called by anyone making further changes to the code in the future, I've added a doc comment to the
CreateScriptBridgeForType
method noting that the registration needs to be done manually.Detailed callstack of the problem with explanations:
Managed code is italics to make it easier to read when we switch between managed and unmanaged
Then we call the following on the new worker thread: