mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Merge pull request #21988 from Arkadyzja/savestate-forget-stale-helper-threads
Savestate: don't let stale HLE helper threads mutate restored kernel state
This commit is contained in:
2 files changed
+22
No files matched your search
@@ -701,6 +701,18 @@ void __PsmfPlayerDoState(PointerWrap &p) {
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
if (p.mode == p.MODE_READ) {
|
||||
// The map serializer deletes every existing host PsmfPlayer before
|
||||
// loading. ~PsmfPlayer -> AbortFinish() deletes its helper thread
|
||||
// without Forget(), mutating the freshly restored kernel state with
|
||||
// stale ids/blocks from before the load (see the matching fix in
|
||||
// __UtilityDoState). Forget the helpers first; the kernel-side
|
||||
// objects belong to the restored state, not to these host wrappers.
|
||||
for (auto &it : psmfPlayerMap) {
|
||||
if (it.second && it.second->finishThread)
|
||||
it.second->finishThread->Forget();
|
||||
}
|
||||
}
|
||||
Do(p, psmfPlayerMap);
|
||||
Do(p, videoPixelMode);
|
||||
Do(p, videoLoopStatus);
|
||||
|
||||
@@ -361,6 +361,16 @@ void __UtilityDoState(PointerWrap &p) {
|
||||
if (s >= 4) {
|
||||
Do(p, hasAccessThread);
|
||||
if (hasAccessThread) {
|
||||
if (p.mode == p.MODE_READ && accessThread) {
|
||||
// Do() below would delete the stale host object without Forget(),
|
||||
// letting ~HLEHelperThread run __KernelDeleteThread and free kernel
|
||||
// memory using pre-load ids/blocks against the restored kernel
|
||||
// state. If an id or block was recycled, that kills a live thread
|
||||
// or frees a live allocation. Same pattern as __IoDoState.
|
||||
accessThread->Forget();
|
||||
delete accessThread;
|
||||
accessThread = nullptr;
|
||||
}
|
||||
Do(p, accessThread);
|
||||
if (p.mode == p.MODE_READ)
|
||||
accessThreadState = "from save state";
|
||||
|
||||
Reference in new issue
Block a user