Repository: godot
Issue: SoftBody3D can cause editor to hang when opening scene on multi-threaded physics
Labels: bug,topic:editor,topic:physics,topic:3d

### Tested versions

- Reproducible in: v4.3.stable.mono.official [77dcf97d8], custom build from commit 99a8ab795

### System information

Windows 10.0.22631 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3080 (NVIDIA; 32.0.15.6614) - AMD Ryzen 7 5800X 8-Core Processor (16 Threads)

### Issue description

When using multi-threaded physics, the editor may hang forever when opening a scene with a SoftBody3D node. This only happens if there is at least one other physics node in the scene. In my repro project, I used a AnimatableBody3D. This happens both with the old Godot Physics and the new Jolt Physics.

While in this state, I extracted the callstacks to see where Godot got stuck:
Main Thread:
```
godot.windows.editor.x86_64.mono.exe!mtx_do_lock
[External Code]
[Inline Frame] godot.windows.editor.x86_64.mono.exe!std::_Mutex_base::lock() Line 52
[Inline Frame] godot.windows.editor.x86_64.mono.exe!std::unique_lock<std::mutex>::{ctor}(std::mutex &) Line 144
[Inline Frame] godot.windows.editor.x86_64.mono.exe!MutexLock<MutexImpl<std::mutex>>::{ctor}(const MutexImpl<std::mutex> &) Line 78
godot.windows.editor.x86_64.mono.exe!CommandQueueMT::push<PhysicsServer3D,void (__cdecl PhysicsServer3D::*)(RID,enum PhysicsServer3D::BodyState,Variant const &),RID,enum PhysicsServer3D::BodyState,Variant>(PhysicsServer3D * p_instance, void(PhysicsServer3D::*)(RID, PhysicsServer3D::BodyState, const Variant &) p_method, RID p1, PhysicsServer3D::BodyState p2, Variant p3) Line 414
godot.windows.editor.x86_64.mono.exe!PhysicsServer3DWrapMT::body_set_state(RID p1, PhysicsServer3D::BodyState p2, const Variant & p3) Line 218
godot.windows.editor.x86_64.mono.exe!CollisionObject3D::_notification(int p_what) Line 62
godot.windows.editor.x86_64.mono.exe!CollisionObject3D::_notificationv(int p_notification, bool p_reversed) Line 38
godot.windows.editor.x86_64.mono.exe!AnimatableBody3D::_notificationv(int p_notification, bool p_reversed) Line 37
godot.windows.editor.x86_64.mono.exe!Object::notification(int p_notification, bool p_reversed) Line 877
godot.windows.editor.x86_64.mono.exe!Node3D::_notification(int p_what) Line 164
godot.windows.editor.x86_64.mono.exe!Node3D::_notificationv(int p_notification, bool p_reversed) Line 52
godot.windows.editor.x86_64.mono.exe!CollisionObject3D::_notificationv(int p_notification, bool p_reversed) Line 38
godot.windows.editor.x86_64.mono.exe!AnimatableBody3D::_notificationv(int p_notification, bool p_reversed) Line 37
godot.windows.editor.x86_64.mono.exe!Object::notification(int p_notification, bool p_reversed) Line 877
godot.windows.editor.x86_64.mono.exe!Node::_propagate_enter_tree() Line 310
godot.windows.editor.x86_64.mono.exe!Node::_propagate_enter_tree() Line 325
godot.windows.editor.x86_64.mono.exe!Node::_set_tree(SceneTree * p_tree) Line 3288
godot.windows.editor.x86_64.mono.exe!Node::_add_child_nocheck(Node * p_child, const StringName & p_name, Node::InternalMode p_internal_mode) Line 1641
godot.windows.editor.x86_64.mono.exe!Node::add_child(Node * p_child, bool p_force_readable_name, Node::InternalMode p_internal) Line 1669
[Inline Frame] godot.windows.editor.x86_64.mono.exe!EditorNode::set_edited_scene_root(Node *) Line 3779
godot.windows.editor.x86_64.mono.exe!EditorNode::set_edited_scene(Node * p_scene) Line 3759
godot.windows.editor.x86_64.mono.exe!EditorNode::load_scene(const String & p_scene, bool p_ignore_broken_deps, bool p_set_inherited, bool p_force_open_imported, bool p_silent_change_tab) Line 4082
godot.windows.editor.x86_64.mono.exe!EditorNode::open_request(const String & p_path, bool p_set_inherited) Line 4488
godot.windows.editor.x86_64.mono.exe!FileSystemDock::_select_file(const String & p_path, bool p_select_in_favorites, bool p_navigate) Line 1257
godot.windows.editor.x86_64.mono.exe!FileSystemDock::_tree_activate_file() Line 1301
[Inline Frame] godot.windows.editor.x86_64.mono.exe!call_with_variant_args_helper(FileSystemDock *) Line 303
[Inline Frame] godot.windows.editor.x86_64.mono.exe!call_with_variant_args(FileSystemDock * p_instance, void(FileSystemDock::*)() p_method, const Variant * *) Line 417
godot.windows.editor.x86_64.mono.exe!CallableCustomMethodPointer<FileSystemDock,void>::call(const Variant * * p_arguments, int p_argcount, Variant & r_return_value, Callable::CallError & r_call_error) Line 109
godot.windows.editor.x86_64.mono.exe!Callable::callp(const Variant * * p_arguments, int p_argcount, Variant & r_return_value, Callable::CallError & r_call_error) Line 58
godot.windows.editor.x86_64.mono.exe!Object::emit_signalp(const StringName & p_name, const Variant * * p_args, int p_argcount) Line 1202
godot.windows.editor.x86_64.mono.exe!Node::emit_signalp(const StringName & p_name, const Variant * * p_args, int p_argcount) Line 4022
godot.windows.editor.x86_64.mono.exe!Object::emit_signal<>(const StringName & p_name) Line 922
godot.windows.editor.x86_64.mono.exe!Tree::gui_input(const Ref<InputEvent> & p_event) Line 3975
godot.windows.editor.x86_64.mono.exe!Control::_call_gui_input(const Ref<InputEvent> & p_event) Line 1826
godot.windows.editor.x86_64.mono.exe!Viewport::_gui_call_input(Control * p_control, const Ref<InputEvent> & p_input) Line 1627
godot.windows.editor.x86_64.mono.exe!Viewport::_gui_input_event(Ref<InputEvent> p_event) Line 1860
godot.windows.editor.x86_64.mono.exe!Viewport::push_input(const Ref<InputEvent> & p_event, bool p_local_coords) Line 3242
godot.windows.editor.x86_64.mono.exe!Window::_window_input(const Ref<InputEvent> & p_ev) Line 1693
[Inline Frame] godot.windows.editor.x86_64.mono.exe!call_with_variant_args_helper(Window *) Line 303
[Inline Frame] godot.windows.editor.x86_64.mono.exe!call_with_variant_args(Window * p_instance, void(Window::*)(const Ref<InputEvent> &) p_method, const Variant * *) Line 417
godot.windows.editor.x86_64.mono.exe!CallableCustomMethodPointer<Window,void,Ref<InputEvent> const &>::call(const Variant * * p_arguments, int p_argcount, Variant & r_return_value, Callable::CallError & r_call_error) Line 105
godot.windows.editor.x86_64.mono.exe!Callable::callp(const Variant * * p_arguments, int p_argcount, Variant & r_return_value, Callable::CallError & r_call_error) Line 58
godot.windows.editor.x86_64.mono.exe!Callable::call<Ref<InputEvent>>(Ref<InputEvent> <p_args_0>) Line 921
godot.windows.editor.x86_64.mono.exe!DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> & p_event) Line 4127
godot.windows.editor.x86_64.mono.exe!Input::_parse_input_event_impl(const Ref<InputEvent> & p_event, bool p_is_emulated) Line 922
godot.windows.editor.x86_64.mono.exe!Input::flush_buffered_events() Line 1203
godot.windows.editor.x86_64.mono.exe!DisplayServerWindows::process_events() Line 3566
godot.windows.editor.x86_64.mono.exe!OS_Windows::run() Line 2064
godot.windows.editor.x86_64.mono.exe!widechar_main(int argc, wchar_t * * argv) Line 181
godot.windows.editor.x86_64.mono.exe!_main() Line 208
godot.windows.editor.x86_64.mono.exe!main(int argc, char * * argv) Line 220
[External Code]
```

Physics Thread:
```
[Inline Frame] godot.windows.editor.x86_64.mono.exe!_Primitive_wait_for
[External Code]
[Inline Frame] godot.windows.editor.x86_64.mono.exe!std::condition_variable::wait(std::unique_lock<std::mutex> &) Line 557
[Inline Frame] godot.windows.editor.x86_64.mono.exe!ConditionVariable::wait(const MutexLock<MutexImpl<std::mutex>> &) Line 60
[Inline Frame] godot.windows.editor.x86_64.mono.exe!CommandQueueMT::_wait_for_sync(MutexLock<MutexImpl<std::mutex>> &) Line 403
godot.windows.editor.x86_64.mono.exe!CommandQueueMT::push_and_ret<RendererMeshStorage,RenderingServer::SurfaceData (__cdecl RendererMeshStorage::*)(RID,int)const ,RID,int,RenderingServer::SurfaceData>(RendererMeshStorage * p_instance, RenderingServer::SurfaceData(const RendererMeshStorage::*)(RID, int) p_method, RID p1, int p2, RenderingServer::SurfaceData * r_ret) Line 418
godot.windows.editor.x86_64.mono.exe!RenderingServerDefault::mesh_get_surface(RID p1, int p2) Line 366
godot.windows.editor.x86_64.mono.exe!RenderingServer::mesh_surface_get_arrays(RID p_mesh, int p_surface) Line 1703
godot.windows.editor.x86_64.mono.exe!JoltSoftBody3D::_ref_shared_data() Line 138
godot.windows.editor.x86_64.mono.exe!JoltSoftBody3D::_add_to_space() Line 108
godot.windows.editor.x86_64.mono.exe!JoltObject3D::_reset_space() Line 54
[Inline Frame] godot.windows.editor.x86_64.mono.exe!JoltSoftBody3D::_try_rebuild() Line 314
[Inline Frame] godot.windows.editor.x86_64.mono.exe!JoltSoftBody3D::_mesh_changed() Line 319
godot.windows.editor.x86_64.mono.exe!JoltSoftBody3D::set_mesh(const RID & p_mesh) Line 414
godot.windows.editor.x86_64.mono.exe!JoltPhysicsServer3D::soft_body_set_mesh(RID p_body, RID p_mesh) Line 999
godot.windows.editor.x86_64.mono.exe!CommandQueueMT::_flush() Line 374
[Inline Frame] godot.windows.editor.x86_64.mono.exe!CommandQueueMT::flush_all() Line 431
godot.windows.editor.x86_64.mono.exe!PhysicsServer3DWrapMT::_thread_loop() Line 43
[Inline Frame] godot.windows.editor.x86_64.mono.exe!call_with_variant_args_helper(PhysicsServer3DWrapMT *) Line 303
[Inline Frame] godot.windows.editor.x86_64.mono.exe!call_with_variant_args(PhysicsServer3DWrapMT * p_instance, void(PhysicsServer3DWrapMT::*)() p_method, const Variant * *) Line 417
godot.windows.editor.x86_64.mono.exe!CallableCustomMethodPointer<PhysicsServer3DWrapMT,void>::call(const Variant * * p_arguments, int p_argcount, Variant & r_return_value, Callable::CallError & r_call_error) Line 109
godot.windows.editor.x86_64.mono.exe!Callable::callp(const Variant * * p_arguments, int p_argcount, Variant & r_return_value, Callable::CallError & r_call_error) Line 58
[Inline Frame] godot.windows.editor.x86_64.mono.exe!Callable::call() Line 920
godot.windows.editor.x86_64.mono.exe!WorkerThreadPool::_process_task(WorkerThreadPool::Task * p_task) Line 142
godot.windows.editor.x86_64.mono.exe!WorkerThreadPool::_thread_function(void * p_user) Line 189
godot.windows.editor.x86_64.mono.exe!Thread::callback(unsigned __int64 p_caller_id, const Thread::Settings & p_settings, void(*)(void *) p_callback, void * p_userdata) Line 66
[External Code]
godot.windows.editor.x86_64.mono.exe!thread_start<unsigned int (__cdecl*)(void *),1>(void * const parameter) Line 97
[External Code]
```

### Steps to reproduce

1. Open attached project
2. Open scene "crash.tscn"
3. Observe that the editor hangs forever

### Minimal reproduction project (MRP)

[cloth_crash.zip](https://github.com/user-attachments/files/18262481/cloth_crash.zip)