Skip to content

Commit 85f9c46

Browse files
committed
Merge pull request #103880 from 100gold/fix_deadlock_on_pipelinehashmaprd
Fix deadlock between `PipelineHashMapRD::local_mutex` and `GDScriptCache::mutex`
2 parents 7d677fe + 477b645 commit 85f9c46

File tree

1 file changed

+27
-12
lines changed

1 file changed

+27
-12
lines changed

servers/rendering/renderer_rd/pipeline_hash_map_rd.h

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,16 @@ class PipelineHashMapRD {
7777
}
7878

7979
void _wait_for_all_pipelines() {
80-
MutexLock local_lock(local_mutex);
81-
for (KeyValue<uint32_t, WorkerThreadPool::TaskID> key_value : compilation_tasks) {
82-
WorkerThreadPool::get_singleton()->wait_for_task_completion(key_value.value);
80+
thread_local LocalVector<WorkerThreadPool::TaskID> tasks_to_wait;
81+
{
82+
MutexLock local_lock(local_mutex);
83+
for (KeyValue<uint32_t, WorkerThreadPool::TaskID> key_value : compilation_tasks) {
84+
tasks_to_wait.push_back(key_value.value);
85+
}
86+
}
87+
88+
for (WorkerThreadPool::TaskID task_id : tasks_to_wait) {
89+
WorkerThreadPool::get_singleton()->wait_for_task_completion(task_id);
8390
}
8491
}
8592

@@ -137,17 +144,25 @@ class PipelineHashMapRD {
137144
}
138145

139146
void wait_for_pipeline(uint32_t p_key_hash) {
140-
MutexLock local_lock(local_mutex);
141-
if (!compilation_set.has(p_key_hash)) {
142-
// The pipeline was never submitted, we can't wait for it.
143-
return;
147+
WorkerThreadPool::TaskID task_id_to_wait = WorkerThreadPool::INVALID_TASK_ID;
148+
149+
{
150+
MutexLock local_lock(local_mutex);
151+
if (!compilation_set.has(p_key_hash)) {
152+
// The pipeline was never submitted, we can't wait for it.
153+
return;
154+
}
155+
156+
HashMap<uint32_t, WorkerThreadPool::TaskID>::Iterator task_it = compilation_tasks.find(p_key_hash);
157+
if (task_it != compilation_tasks.end()) {
158+
// Wait for and remove the compilation task if it exists.
159+
task_id_to_wait = task_it->value;
160+
compilation_tasks.remove(task_it);
161+
}
144162
}
145163

146-
HashMap<uint32_t, WorkerThreadPool::TaskID>::Iterator task_it = compilation_tasks.find(p_key_hash);
147-
if (task_it != compilation_tasks.end()) {
148-
// Wait for and remove the compilation task if it exists.
149-
WorkerThreadPool::get_singleton()->wait_for_task_completion(task_it->value);
150-
compilation_tasks.remove(task_it);
164+
if (task_id_to_wait != WorkerThreadPool::INVALID_TASK_ID) {
165+
WorkerThreadPool::get_singleton()->wait_for_task_completion(task_id_to_wait);
151166
}
152167
}
153168

0 commit comments

Comments
 (0)