Invoke resource manager callbacks outside the callback mutex

This commit is contained in:
Ken Sanislo
2026-07-26 22:47:18 +00:00
committed by Adam Honse
parent 394a5c8eb0
commit acc7fa6754
2 changed files with 24 additions and 4 deletions

View File

@@ -811,15 +811,27 @@ void ResourceManager::SignalResourceManagerUpdate(unsigned int update_reason)
server->SignalResourceManagerUpdate(update_reason);
}
/*-----------------------------------------------------*\
| Snapshot the callback list, then invoke unlocked. A |
| blocking callback must not hold the mutex: the GUI's |
| blocking device list callback waits forever once the |
| event loop has exited at shutdown, and a held mutex |
| then deadlocks the unregister in the dialog |
| destructor. A callback may still fire once after its |
| unregister returns. |
\*-----------------------------------------------------*/
ResourceManagerCallbackMutex.lock();
for(std::size_t callback_idx = 0; callback_idx < ResourceManagerCallbacks.size(); callback_idx++)
{
ResourceManagerCallbacks[callback_idx](ResourceManagerCallbackArgs[callback_idx], update_reason);
}
std::vector<ResourceManagerCallback> callbacks = ResourceManagerCallbacks;
std::vector<void *> callback_args = ResourceManagerCallbackArgs;
ResourceManagerCallbackMutex.unlock();
for(std::size_t callback_idx = 0; callback_idx < callbacks.size(); callback_idx++)
{
callbacks[callback_idx](callback_args[callback_idx], update_reason);
}
LOG_TRACE("[%s] ResourceManager update signalled: %d", RESOURCEMANAGER, update_reason);
}

View File

@@ -577,6 +577,14 @@ void OpenRGBDialog::closeEvent(QCloseEvent *event)
}
else
{
/*-------------------------------------------------*\
| Stop receiving resource manager callbacks before |
| the event loop dies: plugin teardown signals from |
| worker threads would post blocking calls no loop |
| will ever service. |
\*-------------------------------------------------*/
ResourceManager::get()->UnregisterResourceManagerCallback(OpenRGBDialogResourceManagerCallback, this);
plugin_manager->UnloadPlugins();
if(ResourceManager::get()->GetProfileManager()->LoadAutoProfileExit())