mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-12-16 04:09:39 +00:00
Core: Make s_cpu_thread_job_finished a local variable
Having it be static leads to a race condition if two different threads call RunOnCPUThread with wait_for_completion set to true. (There's currently nobody calling RunOnCPUThread from anything other than the host thread, so this hasn't led to any consequences yet.)
This commit is contained in:
parent
5769fc7372
commit
2d9f317f04
@ -27,12 +27,12 @@
|
|||||||
#include "Common/CPUDetect.h"
|
#include "Common/CPUDetect.h"
|
||||||
#include "Common/CommonPaths.h"
|
#include "Common/CommonPaths.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/Event.h"
|
|
||||||
#include "Common/FPURoundMode.h"
|
#include "Common/FPURoundMode.h"
|
||||||
#include "Common/FatFsUtil.h"
|
#include "Common/FatFsUtil.h"
|
||||||
#include "Common/FileUtil.h"
|
#include "Common/FileUtil.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
#include "Common/MsgHandler.h"
|
#include "Common/MsgHandler.h"
|
||||||
|
#include "Common/OneShotEvent.h"
|
||||||
#include "Common/ScopeGuard.h"
|
#include "Common/ScopeGuard.h"
|
||||||
#include "Common/StringUtil.h"
|
#include "Common/StringUtil.h"
|
||||||
#include "Common/Thread.h"
|
#include "Common/Thread.h"
|
||||||
@ -127,7 +127,6 @@ struct HostJob
|
|||||||
};
|
};
|
||||||
static std::mutex s_host_jobs_lock;
|
static std::mutex s_host_jobs_lock;
|
||||||
static std::queue<HostJob> s_host_jobs_queue;
|
static std::queue<HostJob> s_host_jobs_queue;
|
||||||
static Common::Event s_cpu_thread_job_finished;
|
|
||||||
|
|
||||||
static thread_local bool tls_is_cpu_thread = false;
|
static thread_local bool tls_is_cpu_thread = false;
|
||||||
static thread_local bool tls_is_gpu_thread = false;
|
static thread_local bool tls_is_gpu_thread = false;
|
||||||
@ -841,6 +840,8 @@ void RunOnCPUThread(Core::System& system, Common::MoveOnlyFunction<void()> funct
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Common::OneShotEvent cpu_thread_job_finished;
|
||||||
|
|
||||||
// Pause the CPU (set it to stepping mode).
|
// Pause the CPU (set it to stepping mode).
|
||||||
const bool was_running = PauseAndLock(system);
|
const bool was_running = PauseAndLock(system);
|
||||||
|
|
||||||
@ -853,10 +854,9 @@ void RunOnCPUThread(Core::System& system, Common::MoveOnlyFunction<void()> funct
|
|||||||
else if (wait_for_completion)
|
else if (wait_for_completion)
|
||||||
{
|
{
|
||||||
// Queue the job function followed by triggering the event.
|
// Queue the job function followed by triggering the event.
|
||||||
s_cpu_thread_job_finished.Reset();
|
system.GetCPU().AddCPUThreadJob([&function, &cpu_thread_job_finished] {
|
||||||
system.GetCPU().AddCPUThreadJob([&function] {
|
|
||||||
function();
|
function();
|
||||||
s_cpu_thread_job_finished.Set();
|
cpu_thread_job_finished.Set();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -872,7 +872,7 @@ void RunOnCPUThread(Core::System& system, Common::MoveOnlyFunction<void()> funct
|
|||||||
if (wait_for_completion)
|
if (wait_for_completion)
|
||||||
{
|
{
|
||||||
// Periodically yield to the UI thread, so we don't deadlock.
|
// Periodically yield to the UI thread, so we don't deadlock.
|
||||||
while (!s_cpu_thread_job_finished.WaitFor(std::chrono::milliseconds(10)))
|
while (!cpu_thread_job_finished.WaitFor(std::chrono::milliseconds(10)))
|
||||||
Host_YieldToUI();
|
Host_YieldToUI();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user