Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ScriptRunner): fix deadlock #1209

Merged
merged 1 commit into from
Mar 4, 2025
Merged

fix(ScriptRunner): fix deadlock #1209

merged 1 commit into from
Mar 4, 2025

Conversation

mrbeardad
Copy link
Contributor

@mrbeardad mrbeardad commented Mar 4, 2025

Fix deadlock problem when play MHWilds on a high performance machine

@HookedBehemoth
Copy link

Couldn't both be passed into the same scoped_lock ctor? https://en.cppreference.com/w/cpp/thread/scoped_lock/scoped_lock
The docs explicitly mention that it avoids deadlocks https://en.cppreference.com/w/cpp/thread/lock
and neither is released early.

@praydog praydog merged commit 92b9376 into praydog:master Mar 4, 2025
13 checks passed
@mrbeardad
Copy link
Contributor Author

@praydog I just reproduced the deadlock problem again, so I think m_access_mutex is not the essential reason. After further research, I've found the real problem.

In imgui thread, m_imgui_mtx first locked here

void REFramework::run_imgui_frame(bool from_present) {
std::scoped_lock _{ m_imgui_mtx };
m_has_frame = false;
if (!m_initialized) {
return;
}

and then get_hook_monitor_mutex called here
void ScriptRunner::reset_scripts() {
std::scoped_lock __{ g_framework->get_hook_monitor_mutex() }; // Stops D3D monitor from attempting to re-hook during long script startups
std::scoped_lock _{ m_access_mutex };
{

But in d3d12 threads, get_hook_monitor_mutex is first called here
std::scoped_lock _{g_framework->get_hook_monitor_mutex()};
bool hook_was_nullptr = g_d3d12_hook == nullptr;
if (g_d3d12_hook != nullptr && g_framework->get_d3d12_hook() != nullptr) {
g_framework->on_reset(); // Needed to prevent a crash due to resources hanging around
g_d3d12_hook->unhook(); // Removes all vtable hooks
}

and then m_imgui_mtx locked here
void REFramework::on_reset() {
std::scoped_lock _{ m_imgui_mtx };
spdlog::info("Reset!");

Unfortunately, them are not in the same function, is there a easy way to solve it? BTW, this pr solve my problem most of the time, I don't know the reason

@praydog
Copy link
Owner

praydog commented Mar 5, 2025

Should be fixed in 8358c55

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants