Compare commits

...

1 Commits

Author SHA1 Message Date
Muyuan Li (from Dev Box)
a97ae6042e fix(runner): add recursive mutex locks to all HotkeyConflictManager methods
All public methods of HotkeyConflictManager now acquire hotkeyMutex before accessing shared state (hotkeyMap, sysConflictHotkeyMap, inAppConflictHotkeyMap, disabledHotkeys). Changed from std::mutex to std::recursive_mutex to support internal call chains (e.g. EnableHotkeyByModule -> AddHotkey -> HasConflict). Also moved the lock in RemoveHotkeyByModule to before the disabledHotkeys access.

Closes #46952
2026-04-29 17:40:01 +08:00
2 changed files with 9 additions and 4 deletions

View File

@@ -36,6 +36,7 @@ namespace HotkeyConflictDetector
HotkeyConflictType HotkeyConflictManager::HasConflict(Hotkey const& _hotkey, const wchar_t* _moduleName, const int _hotkeyID)
{
std::lock_guard<std::recursive_mutex> lock(hotkeyMutex);
if (disabledHotkeys.find(_moduleName) != disabledHotkeys.end())
{
return HotkeyConflictType::NoConflict;
@@ -79,6 +80,7 @@ namespace HotkeyConflictDetector
HotkeyConflictType HotkeyConflictManager::HasConflict(Hotkey const& _hotkey)
{
std::lock_guard<std::recursive_mutex> lock(hotkeyMutex);
uint16_t handle = GetHotkeyHandle(_hotkey);
if (handle == 0)
@@ -113,6 +115,7 @@ namespace HotkeyConflictDetector
// It returns a list of all conflicting shortcuts.
std::vector<HotkeyConflictInfo> HotkeyConflictManager::GetAllConflicts(Hotkey const& _hotkey)
{
std::lock_guard<std::recursive_mutex> lock(hotkeyMutex);
std::vector<HotkeyConflictInfo> conflicts;
uint16_t handle = GetHotkeyHandle(_hotkey);
@@ -164,6 +167,7 @@ namespace HotkeyConflictDetector
bool HotkeyConflictManager::AddHotkey(Hotkey const& _hotkey, const wchar_t* _moduleName, const int _hotkeyID, bool isEnabled)
{
std::lock_guard<std::recursive_mutex> lock(hotkeyMutex);
if (!isEnabled)
{
disabledHotkeys[_moduleName].push_back({ _hotkey, _moduleName, _hotkeyID });
@@ -209,14 +213,13 @@ namespace HotkeyConflictDetector
std::vector<HotkeyConflictInfo> HotkeyConflictManager::RemoveHotkeyByModule(const std::wstring& moduleName)
{
std::lock_guard<std::recursive_mutex> lock(hotkeyMutex);
std::vector<HotkeyConflictInfo> removedHotkeys;
if (disabledHotkeys.find(moduleName) != disabledHotkeys.end())
{
disabledHotkeys.erase(moduleName);
}
std::lock_guard<std::mutex> lock(hotkeyMutex);
bool foundRecord = false;
for (auto it = sysConflictHotkeyMap.begin(); it != sysConflictHotkeyMap.end();)
@@ -310,6 +313,7 @@ namespace HotkeyConflictDetector
void HotkeyConflictManager::EnableHotkeyByModule(const std::wstring& moduleName)
{
std::lock_guard<std::recursive_mutex> lock(hotkeyMutex);
if (disabledHotkeys.find(moduleName) == disabledHotkeys.end())
{
return; // No disabled hotkeys for this module
@@ -327,6 +331,7 @@ namespace HotkeyConflictDetector
void HotkeyConflictManager::DisableHotkeyByModule(const std::wstring& moduleName)
{
std::lock_guard<std::recursive_mutex> lock(hotkeyMutex);
auto hotkeys = RemoveHotkeyByModule(moduleName);
disabledHotkeys[moduleName] = hotkeys;
}
@@ -382,7 +387,7 @@ namespace HotkeyConflictDetector
json::JsonObject HotkeyConflictManager::GetHotkeyConflictsAsJson()
{
std::lock_guard<std::mutex> lock(hotkeyMutex);
std::lock_guard<std::recursive_mutex> lock(hotkeyMutex);
using namespace json;
JsonObject root;

View File

@@ -57,7 +57,7 @@ namespace HotkeyConflictDetector
static std::mutex instanceMutex;
static HotkeyConflictManager* instance;
std::mutex hotkeyMutex;
std::recursive_mutex hotkeyMutex;
// Hotkey in hotkeyMap means the hotkey has been registered successfully
std::unordered_map<uint16_t, HotkeyConflictInfo> hotkeyMap;
// Hotkey in sysConflictHotkeyMap means the hotkey has conflict with system defined hotkeys