godotengine / godotengine/godot
Calling call_deferred() from std::thread can spam thread-check errors when MessageQueue is full
- Dominant language
- C++
- Stars
- 117k
- Forks
- 26.8k
- PR merge metrics
- PR metrics pending
Description
### Tested versions
4.6.2.stable
### System information
Android - 4.6.2.stable
### Issue description
There appears to be a secondary failure in the `call_deferred()` / `MessageQueue` out-of-memory error path.
When `call_deferred()` is called from a native `std::thread`, and the internal `CallQueue` / `MessageQueue` is full, Godot tries to print the following error:
```cpp
fprintf(stderr, "Failed method: %s. Message queue out of memory. %s\n", String(p_callable).utf8().get_data(), error_text.utf8().get_data());
```
In `Callable::operator String()` it will try to call `get_script()`.
```cpp
Callable::operator String() const {
if (is_custom()) {
return custom->get_as_text();
} else {
if (is_null()) {
return "null::null";
}
Object *base = get_object();
if (base) {
String class_name = base->get_class();
Ref script = base->get_script();
if (script.is_valid()) {
if (!script->get_global_name().is_empty()) {
class_name += "(" + script->get_global_name() + ")";
} else if (script->get_path().is_resource_file()) {
class_name += "(" + script->get_path().get_file() + ")";
}
}
return class_name + "::" + String(method);
} else {
return "null::" + String(method);
}
}
}
```
For node, it will cause error in log in debug build.
```c++
Variant Node::get_script() const {
ERR_THREAD_GUARD_V(Variant());
return Object::get_script();
}
```
### Steps to reproduce
Block main thread and continue call `call_deferred()` in std thread.
### Minimal reproduction project (MRP)
The code is already showing the problem.
Contributor guide
Research direction
Start with the MessageQueue/CallQueue full error path and Callable::operator String(), then inspect Node::get_script() and its thread guard. Reproduce the issue by blocking the main thread while calling call_deferred() from a std::thread; done means the full-queue error path no longer spams thread-check errors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- backend, game-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 50/100