fix(windows): shut down IMFMediaSource deterministically to stop fatal 0xC000070A threadpool crash - #2117
Open
aacarcrash wants to merge 1 commit into
Open
Conversation
…atal 0xC000070A A handle was being closed while an ntdll threadpool wait was still registered on it, killing the process with a non-catchable 0xC000070A. Full-dump analysis (CapSoftware#2115) places the dangling wait in Media Foundation's camera KS layer; nothing in the repo ever called IMFMediaSource::Shutdown(), leaving teardown to COM refcount order, which races the KS proxy's waits. - MediaSourceGuard: Arc-shared RAII owner that calls Shutdown() when the last Device clone drops - CaptureHandle co-owns the guard so an active capture can't have its source shut down underneath it - Drop for DeviceSourcesIterator: release each IMFActivate and CoTaskMemFree the MFEnumDeviceSources array (previously leaked on every enumeration) Fixes the crash in CapSoftware#2115. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the Windows crash reported in #2115.
Problem
0xC000070Ais ntdll's fatal threadpool assertion: a HANDLE was closed while athreadpool wait was still registered on it. Full-dump analysis (see #2115) places the
dangling wait in Media Foundation's camera kernel-streaming layer (
mfksproxy.dll,mf.dll/mfplat.dllobjects adjacent to the failedTP_WAIT).Nothing in the repo ever calls
IMFMediaSource::Shutdown(). Teardown is left to COMrefcount release, which runs on whatever thread drops the last reference and races the
KS proxy's registered waits. MF documents Shutdown-before-release as the required
teardown order for media sources.
Because camera enumeration runs continuously (
spawn_devices_snapshot_emitterevery500ms→5s plus the frontend's 5s poll), fresh
IMFMediaSourceobjects are created andrefcount-dropped several times a minute for the app's whole lifetime, so the race
window recurs constantly. On the reporting machine this crashed the app 9 times in
about an hour, including 4 seconds after launch, with no camera selected
(
cameraId: null) — enumeration alone triggers it.Fix (
crates/camera-mediafoundation/src/lib.rs)MediaSourceGuard— RAII owner of theIMFMediaSourcethat callsShutdown()ondrop. Held as
ArcbyDevice(which derivesClone), so shutdown fires exactlyonce, when the last clone drops.
CaptureHandleholds a clone of the guard, so a source cannot be shut down while acapture engine is still using it, even if the originating
Devicedropsmid-capture.
Drop for DeviceSourcesIterator— releases eachIMFActivateand frees theMFEnumDeviceSourcesarray withCoTaskMemFree. Previously the array leaked onevery enumeration (i.e. every few seconds, forever).
media_sourcealso goes frompubfield to private; external access already wentthrough
Deref, so no callers change.Verification
RTX 3070 laptop, one camera in PnP Error state — roster in Windows: fatal 0xC000070A — camera enumeration (MF/mfksproxy) closes a handle with a threadpool wait still registered (0.5.9) #2115).
camera re-enabled deliberately), survived multiple sessions including one ~3-hour
session of active use (record → edit → export → idle) ending in a clean tray quit:
zero unclean shutdowns, zero WER events, zero panics in captured logs. WER
LocalDumps was armed at DumpType=2 the whole time and captured nothing.
(
STATUS_INVALID_HANDLEwhen the slot is empty,STATUS_ACCESS_DENIEDwhen thehandle slot was recycled), consistent with close-while-registered.
Happy to split the iterator leak fix into its own commit if preferred.
🤖 Generated with Claude Code
Greptile Summary
This PR makes Windows Media Foundation camera-source teardown deterministic and fixes enumeration resource leaks.
Confidence Score: 5/5
The PR appears safe to merge with deterministic source shutdown and enumeration cleanup correctly tied to existing ownership lifetimes.
The source remains owned through active capture, Shutdown runs before the guard’s final COM release, and iterator entries are cloned rather than moved so their new centralized cleanup does not double-release them.
Important Files Changed
Reviews (1): Last reviewed commit: "fix(windows): shut down IMFMediaSource d..." | Re-trigger Greptile
Context used: