Synchronize DVDInterface::ChangeDisc with the CPU thread properly.
This addresses a bit of thread unsafety mentioned in a comment, and fixes a 'ScheduleEvent_Threadsafe from main thread' message. To make this work nicely, make PauseAndLock call DeclareAsCPUThread - i.e. while you have the CPU thread locked, you can consider yourself the CPU thread.
This commit is contained in:
parent
3de1ec384a
commit
e602eac4f9
|
@ -276,7 +276,7 @@ void Stop() // - Hammertime!
|
|||
}
|
||||
}
|
||||
|
||||
static void DeclareAsCPUThread()
|
||||
void DeclareAsCPUThread()
|
||||
{
|
||||
#ifdef ThreadLocalStorage
|
||||
tls_is_cpu_thread = true;
|
||||
|
@ -288,7 +288,7 @@ static void DeclareAsCPUThread()
|
|||
#endif
|
||||
}
|
||||
|
||||
static void UndeclareAsCPUThread()
|
||||
void UndeclareAsCPUThread()
|
||||
{
|
||||
#ifdef ThreadLocalStorage
|
||||
tls_is_cpu_thread = false;
|
||||
|
@ -715,6 +715,7 @@ bool PauseAndLock(bool doLock, bool unpauseOnUnlock)
|
|||
|
||||
// video has to come after CPU, because CPU thread can wait for video thread (s_efbAccessRequested).
|
||||
g_video_backend->PauseAndLock(doLock, unpauseOnUnlock);
|
||||
|
||||
return wasUnpaused;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,9 @@ bool Init();
|
|||
void Stop();
|
||||
void Shutdown();
|
||||
|
||||
void DeclareAsCPUThread();
|
||||
void UndeclareAsCPUThread();
|
||||
|
||||
std::string StopMessage(bool, const std::string&);
|
||||
|
||||
bool IsRunning();
|
||||
|
|
|
@ -149,13 +149,22 @@ void Break()
|
|||
|
||||
bool PauseAndLock(bool do_lock, bool unpause_on_unlock)
|
||||
{
|
||||
static bool s_have_fake_cpu_thread;
|
||||
bool wasUnpaused = !IsStepping();
|
||||
if (do_lock)
|
||||
{
|
||||
// we can't use EnableStepping, that would causes deadlocks with both audio and video
|
||||
PowerPC::Pause();
|
||||
if (!Core::IsCPUThread())
|
||||
{
|
||||
m_csCpuOccupied.lock();
|
||||
s_have_fake_cpu_thread = true;
|
||||
Core::DeclareAsCPUThread();
|
||||
}
|
||||
else
|
||||
{
|
||||
s_have_fake_cpu_thread = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -165,8 +174,12 @@ bool PauseAndLock(bool do_lock, bool unpause_on_unlock)
|
|||
m_StepEvent.Set();
|
||||
}
|
||||
|
||||
if (!Core::IsCPUThread())
|
||||
if (s_have_fake_cpu_thread)
|
||||
{
|
||||
Core::UndeclareAsCPUThread();
|
||||
m_csCpuOccupied.unlock();
|
||||
s_have_fake_cpu_thread = false;
|
||||
}
|
||||
}
|
||||
return wasUnpaused;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "Common/MathUtil.h"
|
||||
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/CoreTiming.h"
|
||||
#include "Core/Movie.h"
|
||||
#include "Core/HW/AudioInterface.h"
|
||||
|
@ -522,10 +523,11 @@ void InsertDiscCallback(u64 userdata, int cyclesLate)
|
|||
|
||||
void ChangeDisc(const std::string& newFileName)
|
||||
{
|
||||
bool is_cpu = Core::IsCPUThread();
|
||||
bool was_unpaused = is_cpu ? false : Core::PauseAndLock(true);
|
||||
std::string* _FileName = new std::string(newFileName);
|
||||
CoreTiming::ScheduleEvent_Threadsafe(0, ejectDisc);
|
||||
CoreTiming::ScheduleEvent_Threadsafe(500000000, insertDisc, (u64)_FileName);
|
||||
// TODO: We shouldn't be modifying movie state from the GUI thread.
|
||||
CoreTiming::ScheduleEvent(0, ejectDisc);
|
||||
CoreTiming::ScheduleEvent(500000000, insertDisc, (u64)_FileName);
|
||||
if (Movie::IsRecordingInput())
|
||||
{
|
||||
Movie::g_bDiscChange = true;
|
||||
|
@ -538,6 +540,8 @@ void ChangeDisc(const std::string& newFileName)
|
|||
}
|
||||
Movie::g_discChange = fileName.substr(sizeofpath);
|
||||
}
|
||||
if (!is_cpu)
|
||||
Core::PauseAndLock(false, was_unpaused);
|
||||
}
|
||||
|
||||
void SetLidOpen(bool _bOpen)
|
||||
|
|
Loading…
Reference in New Issue