You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-14 13:41:12 +00:00
fix deadlock between PilelineHashMapRD::local_mutex and GDScriptCache::mutex
This commit is contained in:
@@ -77,9 +77,16 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _wait_for_all_pipelines() {
|
void _wait_for_all_pipelines() {
|
||||||
|
thread_local LocalVector<WorkerThreadPool::TaskID> tasks_to_wait;
|
||||||
|
{
|
||||||
MutexLock local_lock(local_mutex);
|
MutexLock local_lock(local_mutex);
|
||||||
for (KeyValue<uint32_t, WorkerThreadPool::TaskID> key_value : compilation_tasks) {
|
for (KeyValue<uint32_t, WorkerThreadPool::TaskID> key_value : compilation_tasks) {
|
||||||
WorkerThreadPool::get_singleton()->wait_for_task_completion(key_value.value);
|
tasks_to_wait.push_back(key_value.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (WorkerThreadPool::TaskID task_id : tasks_to_wait) {
|
||||||
|
WorkerThreadPool::get_singleton()->wait_for_task_completion(task_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,6 +144,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void wait_for_pipeline(uint32_t p_key_hash) {
|
void wait_for_pipeline(uint32_t p_key_hash) {
|
||||||
|
WorkerThreadPool::TaskID task_id_to_wait = WorkerThreadPool::INVALID_TASK_ID;
|
||||||
|
|
||||||
|
{
|
||||||
MutexLock local_lock(local_mutex);
|
MutexLock local_lock(local_mutex);
|
||||||
if (!compilation_set.has(p_key_hash)) {
|
if (!compilation_set.has(p_key_hash)) {
|
||||||
// The pipeline was never submitted, we can't wait for it.
|
// The pipeline was never submitted, we can't wait for it.
|
||||||
@@ -146,11 +156,16 @@ public:
|
|||||||
HashMap<uint32_t, WorkerThreadPool::TaskID>::Iterator task_it = compilation_tasks.find(p_key_hash);
|
HashMap<uint32_t, WorkerThreadPool::TaskID>::Iterator task_it = compilation_tasks.find(p_key_hash);
|
||||||
if (task_it != compilation_tasks.end()) {
|
if (task_it != compilation_tasks.end()) {
|
||||||
// Wait for and remove the compilation task if it exists.
|
// Wait for and remove the compilation task if it exists.
|
||||||
WorkerThreadPool::get_singleton()->wait_for_task_completion(task_it->value);
|
task_id_to_wait = task_it->value;
|
||||||
compilation_tasks.remove(task_it);
|
compilation_tasks.remove(task_it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (task_id_to_wait != WorkerThreadPool::INVALID_TASK_ID) {
|
||||||
|
WorkerThreadPool::get_singleton()->wait_for_task_completion(task_id_to_wait);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Retrieve a pipeline. It'll return an empty pipeline if it's not available yet, but it'll be guaranteed to succeed if 'wait for compilation' is true and stall as necessary. Source is just an optional number to aid debugging.
|
// Retrieve a pipeline. It'll return an empty pipeline if it's not available yet, but it'll be guaranteed to succeed if 'wait for compilation' is true and stall as necessary. Source is just an optional number to aid debugging.
|
||||||
RID get_pipeline(const Key &p_key, uint32_t p_key_hash, bool p_wait_for_compilation, RS::PipelineSource p_source) {
|
RID get_pipeline(const Key &p_key, uint32_t p_key_hash, bool p_wait_for_compilation, RS::PipelineSource p_source) {
|
||||||
RBMap<uint32_t, RID>::Element *e = hash_map.find(p_key_hash);
|
RBMap<uint32_t, RID>::Element *e = hash_map.find(p_key_hash);
|
||||||
|
|||||||
Reference in New Issue
Block a user