From d17575d47cfd6f5d3d1e2e06b50562c211be2c0c Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 19 Apr 2026 21:16:22 -0500 Subject: [PATCH] Fix deadlock in Vulkan renderer using KMSDRM on AMDGPU --- app/masterhook_internal.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/app/masterhook_internal.c b/app/masterhook_internal.c index b03be56e..d9a817c7 100644 --- a/app/masterhook_internal.c +++ b/app/masterhook_internal.c @@ -39,12 +39,28 @@ int g_SdlDrmMasterFdCount = 0; pthread_mutex_t g_FdTableLock = PTHREAD_MUTEX_INITIALIZER; // This lock protects sections of code that must run uninterrupted with DRM master -pthread_mutex_t g_MasterLock = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t g_MasterLock; +pthread_once_t g_MasterLockInit; // Lock order: g_MasterLock -> g_FdTableLock +static void initializeMasterLock(void) +{ + pthread_mutexattr_t attr; + + // g_MasterLock must be a recursive mutex because we can't fully + // predict how SDL and Vulkan/GL driver code will behave. They may + // call functions that trigger reentrancy into our hooks again, + // which can deadlock if the caller already holds the master lock. + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&g_MasterLock, &attr); + pthread_mutexattr_destroy(&attr); +} + void lockDrmMaster() { + pthread_once(&g_MasterLockInit, initializeMasterLock); pthread_mutex_lock(&g_MasterLock); }