crash fix: when __ClearReserveDeleteWindowList() was destroying Windows, some might have pushed it's children for deletion to m_ReserveDeleteWindowList, invalidating iterators

This commit is contained in:
d1str4ught
2026-02-09 02:25:35 +01:00
parent de25f437ed
commit 6dfb708888
2 changed files with 47 additions and 41 deletions

View File

@@ -75,6 +75,7 @@ namespace UI
void CWindowManager::Destroy() void CWindowManager::Destroy()
{ {
__ClearReserveDeleteWindowList(); __ClearReserveDeleteWindowList();
#ifdef __WINDOW_LEAK_CHECK__ #ifdef __WINDOW_LEAK_CHECK__
std::set<CWindow*>::iterator i; std::set<CWindow*>::iterator i;
for (i=gs_kSet_pkWnd.begin(); i!=gs_kSet_pkWnd.end(); ++i) for (i=gs_kSet_pkWnd.begin(); i!=gs_kSet_pkWnd.end(); ++i)
@@ -430,7 +431,7 @@ namespace UI
pParentWin->DeleteChild(pWin); pParentWin->DeleteChild(pWin);
} }
pWin->Clear(); pWin->Clear();
m_ReserveDeleteWindowList.push_back(pWin); m_ReserveDeleteWindowList.insert(pWin);
} }
BOOL CWindowManager::IsDragging() BOOL CWindowManager::IsDragging()
@@ -710,17 +711,21 @@ namespace UI
void CWindowManager::__ClearReserveDeleteWindowList() void CWindowManager::__ClearReserveDeleteWindowList()
{ {
for (TWindowContainer::iterator itor = m_ReserveDeleteWindowList.begin(); itor != m_ReserveDeleteWindowList.end(); ++itor) if (m_ReserveDeleteWindowList.empty())
{ return;
CWindow * pWin = *itor;
#ifdef __WINDOW_LEAK_CHECK__
gs_kSet_pkWnd.erase(pWin);
#endif
delete pWin;
}
m_ReserveDeleteWindowList.clear();
} std::unordered_set<CWindow*> tmp;
do {
tmp.swap(m_ReserveDeleteWindowList);
for (CWindow* pWin : tmp) {
#ifdef __WINDOW_LEAK_CHECK__
gs_kSet_pkWnd.erase(pWin);
#endif
delete pWin;
}
tmp.clear();
} while (!m_ReserveDeleteWindowList.empty());
}
void CWindowManager::Update() void CWindowManager::Update()
{ {

View File

@@ -1,4 +1,5 @@
#pragma once #pragma once
#include <unordered_set>
namespace UI namespace UI
{ {
@@ -144,44 +145,44 @@ namespace UI
void __ClearReserveDeleteWindowList(); void __ClearReserveDeleteWindowList();
private: private:
long m_lWidth; long m_lWidth;
long m_lHeight; long m_lHeight;
int m_iVres; int m_iVres;
int m_iHres; int m_iHres;
long m_lMouseX, m_lMouseY; long m_lMouseX, m_lMouseY;
long m_lDragX, m_lDragY; long m_lDragX, m_lDragY;
long m_lPickedX, m_lPickedY; long m_lPickedX, m_lPickedY;
BOOL m_bOnceIgnoreMouseLeftButtonUpEventFlag; BOOL m_bOnceIgnoreMouseLeftButtonUpEventFlag;
int m_iIgnoreEndTime; int m_iIgnoreEndTime;
// Attaching Icon // Attaching Icon
PyObject * m_poMouseHandler; PyObject * m_poMouseHandler;
BOOL m_bAttachingFlag; BOOL m_bAttachingFlag;
DWORD m_dwAttachingType; DWORD m_dwAttachingType;
DWORD m_dwAttachingIndex; DWORD m_dwAttachingIndex;
DWORD m_dwAttachingSlotNumber; DWORD m_dwAttachingSlotNumber;
BYTE m_byAttachingIconWidth; BYTE m_byAttachingIconWidth;
BYTE m_byAttachingIconHeight; BYTE m_byAttachingIconHeight;
// Attaching Icon // Attaching Icon
CWindow * m_pActiveWindow; CWindow * m_pActiveWindow;
TWindowContainer m_ActiveWindowList; TWindowContainer m_ActiveWindowList;
CWindow * m_pLockWindow; CWindow * m_pLockWindow;
TWindowContainer m_LockWindowList; TWindowContainer m_LockWindowList;
CWindow * m_pPointWindow; CWindow * m_pPointWindow;
CWindow * m_pLeftCaptureWindow; CWindow * m_pLeftCaptureWindow;
CWindow * m_pRightCaptureWindow; CWindow * m_pRightCaptureWindow;
CWindow * m_pMiddleCaptureWindow; CWindow * m_pMiddleCaptureWindow;
TKeyCaptureWindowMap m_KeyCaptureWindowMap; TKeyCaptureWindowMap m_KeyCaptureWindowMap;
TWindowContainer m_ReserveDeleteWindowList; std::unordered_set<CWindow*> m_ReserveDeleteWindowList;
TWindowContainer m_PickAlwaysWindowList; TWindowContainer m_PickAlwaysWindowList;
CWindow * m_pRootWindow; CWindow * m_pRootWindow;
TWindowContainer m_LayerWindowList; TWindowContainer m_LayerWindowList;
TLayerContainer m_LayerWindowMap; TLayerContainer m_LayerWindowMap;
}; };
PyObject * BuildEmptyTuple(); PyObject * BuildEmptyTuple();