ResumeThread failure leaks suspended refresh thread objects
Summary¶
GeoLocation and IPFilter refresh workers are created suspended, marked
auto-delete, and then resumed after the context is released. If ResumeThread
fails, the thread never runs, so MFC auto-delete never executes. The suspended
CWinThread object and native thread handle can leak.
This is a major Beta 0.7.3 blocker because the failure path is rare and easy to miss, but it violates the release resource-lifetime bar and can leave refresh state partially initialized.
Evidence¶
srchybrid/GeoLocation.cpp:797setspThread->m_bAutoDelete = TRUE.srchybrid/GeoLocation.cpp:801-802releases the context before handlingResumeThreadfailure.srchybrid/IPFilterUpdater.cpp:398setspThread->m_bAutoDelete = TRUE.srchybrid/IPFilterUpdater.cpp:401-402releases the context before handlingResumeThreadfailure.
Execution Plan¶
- Revalidate the exact MFC
AfxBeginThreadownership contract in this code path on currentmain. - Keep explicit ownership of the
CWinThreadobject untilResumeThreadsucceeds, or use a small local guard that can close/delete the suspended thread on launch failure. - Avoid releasing worker context ownership until the thread is guaranteed to run or until failure cleanup has consumed the context.
- Ensure launch failure clears the refresh queued/running state and removes any temporary files created for the attempted refresh.
- Apply the same launch-failure ownership model to GeoLocation and IPFilter.
- Add a focused seam or injection point for
ResumeThreadfailure and assert no context,CWinThread, or handle leak remains.
Acceptance Criteria¶
ResumeThreadfailure leaves no suspendedCWinThreadobject or native thread handle behind.- Refresh state is reset after launch failure.
- Worker context ownership is never released into a never-started thread.
- Normal successful worker launch remains unchanged.
- The item has commit evidence and targeted validation in this file before Beta 0.7.3.
Validation¶
- 2026-05-08: Done in app commit
e5d770e. python -m emule_workspace validate --workspace-root .passed.python -m emule_workspace build app --workspace-root . --config Release --platform x64 --variant mainpassed; log rootworkspaces\v0.72a\state\build-logs\20260508-102041.python -m emule_workspace build app --workspace-root . --config Debug --platform x64 --variant mainpassed; log rootworkspaces\v0.72a\state\build-logs\20260508-102102.- Code validation: GeoLocation and IPFilter refresh launch failure now captures
the original
ResumeThreaderror, releases the never-resumed suspended MFC worker object, resets refresh state, and removes temporary artifacts.