Concurrency, Async, and Thread Affinity
Godot may use internal threads, but ordinary scene-tree objects are main-thread
objects. Gd<T> deliberately does not promise unrestricted cross-thread use.
The binding exposes a reviewed subset of thread-safe value lifecycle functions
and requires Send + Sync + 'static for explicitly thread-safe closures.
godot::task::spawn is a local async executor integrated with the engine. It
accepts non-Send futures, stores them on the main thread, and uses a custom
Waker to arrange another main-thread poll. Signal futures can wake from other
threads, but actual object-facing polling is redirected to the owner thread.
A task must not hold GdRef or GdMut across .await. The suspended task could
be re-entered by _process, a signal, or GDScript, and the stale guard would
block valid access. Strict safeguards detect and warn at the suspension point.
Parallel work should operate on owned, thread-safe Rust data, then schedule a small result integration back on the engine thread. This is the same single-writer principle seen in UI applications, imposed here by a foreign engine rather than a Rust event loop.