godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.58k stars 20.29k forks source link

RenderingServer multithreaded commands lock up multithreaded import plugins written in gdscript #90461

Open jamie-pate opened 5 months ago

jamie-pate commented 5 months ago

Tested versions

System information

Godot v4.3.dev5 - Ubuntu 22.04.4 LTS 22.04 - X11 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3050 Laptop GPU () - 12th Gen Intel(R) Core(TM) i7-12700H (14 Threads)

Issue description

When writing an import plugin for mesh resources it seems to lock up when I call ResourceSaver.save()

I traced it to RS::get_singleton()->mesh_get_surface(mesh, i) which calls, but never returns. It seems like the FUNC1RC wrapper macro in servers/server_wrap_mt_common.h sometimes returns from command_queue.push_and_ret() but somehow still never completes the call.

Array ArrayMesh::_get_surfaces() const {
    if (mesh.is_null()) {
        return Array();
    }

    Array ret;
    for (int i = 0; i < surfaces.size(); i++) {
        RenderingServer::SurfaceData surface = RS::get_singleton()->mesh_get_surface(mesh, i);

Steps to reproduce

Write an import plugin that creates a mesh, then add multiple of these resources to your project. This is affecting the govox project which uses the MagicaVoxel-Importer plugin to import .vox files as point cloud meshes

Minimal reproduction project (MRP)

govox-repro-lockup.zip unzip the project and attempt to open it. It will lock up while importing vox files.

The code with issues is inside addons/MagicaVoxel-Importer/plugin.gd

If you set the variable mutex_bug inside the _import function to true it will work around the issue by using call_deferred to push the ResourceSaver.save() call to the main thread.

akien-mga commented 5 months ago

CC @RandomShaper