Merge pull request #3867 from phire/fix_wii_savestates_some_more

IPC_HLE: Close file handles before savestating. Fixes DKCR crashing.
This commit is contained in:
Pierre Bourdon 2016-05-29 16:26:37 +02:00
commit 6ef7414479
4 changed files with 26 additions and 13 deletions

View File

@ -270,11 +270,11 @@ void DoState(PointerWrap &p)
p.Do(reply_queue); p.Do(reply_queue);
p.Do(last_reply_time); p.Do(last_reply_time);
if (p.GetMode() == PointerWrap::MODE_READ) // We need to make sure all file handles are closed so WII_IPC_Devices_fs::DoState can successfully save or re-create /tmp
for (auto& descriptor : g_FdMap)
{ {
// We need to make sure all file handles are closed so WII_IPC_Devices_fs::DoState can successfully re-create /tmp if (descriptor)
for (u32 i = 0; i < IPC_MAX_FDS; i++) descriptor->PrepareForState(p.GetMode());
g_FdMap[i].reset();
} }
for (const auto& entry : g_DeviceMap) for (const auto& entry : g_DeviceMap)
@ -320,22 +320,22 @@ void DoState(PointerWrap &p)
} }
else else
{ {
for (auto& dev : g_FdMap) for (auto& descriptor : g_FdMap)
{ {
u32 exists = dev ? 1 : 0; u32 exists = descriptor ? 1 : 0;
p.Do(exists); p.Do(exists);
if (exists) if (exists)
{ {
u32 isHw = dev->IsHardware() ? 1 : 0; u32 isHw = descriptor->IsHardware() ? 1 : 0;
p.Do(isHw); p.Do(isHw);
if (isHw) if (isHw)
{ {
u32 hwId = dev->GetDeviceID(); u32 hwId = descriptor->GetDeviceID();
p.Do(hwId); p.Do(hwId);
} }
else else
{ {
dev->DoState(p); descriptor->DoState(p);
} }
} }
} }

View File

@ -109,6 +109,11 @@ public:
{ {
} }
// Release any resources which might interfere with savestating.
virtual void PrepareForState(PointerWrap::Mode mode)
{
}
virtual void DoState(PointerWrap& p) virtual void DoState(PointerWrap& p)
{ {
DoStateShared(p); DoStateShared(p);

View File

@ -356,6 +356,14 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
return GetDefaultReply(); return GetDefaultReply();
} }
void CWII_IPC_HLE_Device_FileIO::PrepareForState(PointerWrap::Mode mode)
{
// Temporally close the file, to prevent any issues with the savestating of /tmp
// it can be opened again with another call to OpenFile()
m_file.reset();
}
void CWII_IPC_HLE_Device_FileIO::DoState(PointerWrap &p) void CWII_IPC_HLE_Device_FileIO::DoState(PointerWrap &p)
{ {
DoStateShared(p); DoStateShared(p);
@ -365,8 +373,7 @@ void CWII_IPC_HLE_Device_FileIO::DoState(PointerWrap &p)
m_filepath = HLE_IPC_BuildFilename(m_Name); m_filepath = HLE_IPC_BuildFilename(m_Name);
if (p.GetMode() == PointerWrap::MODE_READ) // The file was closed during state (and might now be pointing at another file)
{ // Open it again
OpenFile(); OpenFile();
}
} }

View File

@ -26,6 +26,7 @@ public:
IPCCommandResult Read(u32 _CommandAddress) override; IPCCommandResult Read(u32 _CommandAddress) override;
IPCCommandResult Write(u32 _CommandAddress) override; IPCCommandResult Write(u32 _CommandAddress) override;
IPCCommandResult IOCtl(u32 _CommandAddress) override; IPCCommandResult IOCtl(u32 _CommandAddress) override;
void PrepareForState(PointerWrap::Mode mode) override;
void DoState(PointerWrap &p) override; void DoState(PointerWrap &p) override;
void OpenFile(); void OpenFile();