According to godot docs (https://docs.godotengine.org/en/stable/tutorials/performance/threads/thread_safe_apis.html), instancing scenes on a thread other than the main one is possible:

However, creating scene chunks (nodes in tree arrangement) outside the active tree is fine. This way, parts of a scene can be built or instantiated in a thread, then added in the main thread:

var enemy_scene = load("res://enemy_scene.scn")
var enemy = enemy_scene.instance()
enemy.add_child(weapon) # Set a weapon.
world.call_deferred("add_child", enemy)

The closest thing I got working:

if(m_busy) {
            Chunk* chunk = nullptr;

            m_prefabManagerMutex->lock();
            // -- instancing a scene in the main thread, super dirty way
            m_prefabManager->call_deferred("RequestPrefab", PREFAB_ID_CHUNK);
            
            while(chunk == nullptr) {
                using namespace std::chrono_literals;
                std::this_thread::sleep_for(1ms);
                chunk = cast_to<Chunk>(m_prefabManager->requestedPrefab);
            }

            m_prefabManager->requestedPrefab = nullptr;
            // --
            m_prefabManagerMutex->unlock();

            chunk->coordinates = m_chunkToRenderCoordinates;

            m_bakedChunksMutex->lock();
            m_bakedChunks->push(chunk);
            m_bakedChunksMutex->unlock();

            m_freeThreadsMutex->lock();
            m_freeThreads->push(this);
            m_freeThreadsMutex->unlock();

            m_busy = false;
        }

        using namespace std::chrono_literals;
        std::this_thread::sleep_for(sleepTime * 1ms);
    }

This way everything works great, no problems occur whatsoever.

But, when I change the code so that the instancing is done on a thread, after some time the game freezes (not instantly).

if(m_busy) { // spinlock
            m_prefabManagerMutex->lock();
            // -- instancing a scene in the worker thread
            Chunk* chunk  = cast_to<Chunk>(chunkScene->instance());
            // --
            m_prefabManagerMutex->unlock();

            chunk->coordinates = m_chunkToRenderCoordinates;

            m_bakedChunksMutex->lock();
            m_bakedChunks->push(chunk);
            m_bakedChunksMutex->unlock();

            m_freeThreadsMutex->lock();
            m_freeThreads->push(this);
            m_freeThreadsMutex->unlock();

            m_busy = false;
        }

        using namespace std::chrono_literals;
        std::this_thread::sleep_for(sleepTime * 1ms);
    }

I've seen that others also had problems instancing scenes on a worker thread.
Just to be clear: I'm certain that I'm adding my chunks to the active scene tree in the main thread (And instancing in the first code example, too). My worker thread(s) just take(s) care of setting chunks up.
Has anyone managed to get it working with GDNative?

If needed, I can post entire source code on a pasting site.

Edit:
If I remove every node that has anything to do with rendering from the scene I'm instancing it seems to work just fine.
Plus the error I'm getting while the game hangs:

I've already set rendering to multithreaded, doesn't help.

I can't answer your question, but you probably meant to use 3.4.4 in the title, since 3.4.5 doesn't exist.

    muszx godot 3.4.5-rc in the current 3.4 branch

    That's not an official release. Official releases are in the download repository:
    https://downloads.tuxfamily.org/godotengine/

    Is this a custom build that you or someone else made? (It's perfectly okay to make custom builds of Godot, and that may be unrelated to your question. But knowing what version you're using is helpful in diagnosing issues.)

      8 days later

      DaveTheCoder Sorry for taking so long to respond.
      Yes. I've compiled godot myself.

      What I've also found out is that the same problem exists in 3.4.4, too.

      I did my best to find any code examples of multithreading in gdnative, but I wasn't lucky.

      Not analizing the code because I have enough trouble with mine ;-), but from what you describe there's most certainly a race condition and/or deadlock in your code. You won't get around debugging.

      5 days later

      Okay, it works if I use

      Chunk* chunk = Chunk::_new();
      chunk->setup(...);

      instead of
      Chunk* chunk = cast_to<Chunk>(chunkScene->instance());

      When I create the Chunk object using _new() and then run simple setup() funcion everything seems to work fine.

      Has anyone seen a working example of creating instances on a seperate thread? (in GDNative or GDExtension)

      Edit:
      Okay, quick correction: It doesn't work either, the game just doesn't freeze for much longer