You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add ability to suspend threads until a signal is called
For GDScript users that run code on threads, it often happens they want to `await` until something happens,
the continue the thread execution.
Unfortunately, signals will most likely execute on the main thread, hence this means that the code being run on
the thread will continue running on the main thread by default.
It has been discussed whether await should be smart about this and simply suspend the
thread if running on one. The problem with this is, that users may also be willing to
emit the signal that will resume from the thread itself and, at the time of awaiting,
there is **no way for the interpreter to know on which thread the function will be resumed**.
Additionally, suspending the thread is a very different operation than awaiting. Awaiting saves the local
function stack and returns immediately, while suspending stops the whole thread until another resumes it.
Mixing and matching both seems, ultimately, undesired as they are not the same.
To solve this, a new utility function is added by this pull request, which
suspends a thread until a signal is emitted (no matter in which other thread).
It works like this.
```GDScript
# Suspends a thread until a button is pressed.
Thread.suspend( button.pressed )
```
If code must do this and can run on both the main thread or a dedicated thread,
it can do as follows:
```GDScript
# Suspends a thread until a button is pressed.
if (Thread.is_main_thread()):
await button.pressed
else:
Thread.suspend( button.pressed )
```
For this, the `Thread.is_main_thread()` function (already existing in the internal Thread object)
has been exposed to the engine API.
**Q**: Are you sure this can't be done with await transparently?
**A**: No, please read again. There is no way for await to know beforehand how the function will be resumed. Only the user knows.
**Q**: Does it not make more sense to have an `await_thread` or something where the user will pass the argument?
**A**: I think its better to have a dedicated utility function for this. Not only the intention is more explicit, but additionally, as this makes it non exclusive to GDScript. It can be used from other languages that use the engine.
The ratio of [WorkerThreadPool]'s threads that will be reserved for low-priority tasks. For example, if 10 threads are available and this value is set to [code]0.3[/code], 3 of the worker threads will be reserved for low-priority tasks. The actual value won't exceed the number of CPU cores minus one, and if possible, at least one worker thread will be dedicated to low-priority tasks.
Suspend a thread until the signal provided in the [param resume_signal] argument is emitted. As connecting signals between threads is often discouraged (or blocked by thread guards), the [param connect_on_main_thread] is provided to perform the connection to the signal on the main thread. As a note, if you intend to await on a script function instead of a signal, use the following syntax instead: [code] Thread.suspend( function().completed ) [/code].
if (warn_on_cross_thread_await && await_id != Thread::get_caller_id()) {
199
+
WARN_PRINT("Function " + function->get_name() + " was resumed on a different thread than it was awaited. If you really intend to do this, Use Thread.suspend() for cross thread suspension or disable the 'warn_on_cross_thread_await' warning on project settings.");
0 commit comments