Skip to content

fix(windows): don't tear down the native player while an open/seek or frame read is using it - #256

Open
muthuraj57 wants to merge 1 commit into
kdroidFilter:masterfrom
muthuraj57:fix-windows-dispose-race
Open

muthuraj57 wants to merge 1 commit into
kdroidFilter:masterfrom
muthuraj57:fix-windows-dispose-race

Conversation

@muthuraj57

@muthuraj57 muthuraj57 commented Oct 24, 2026 •

Copy link
Copy Markdown

Summary

Fixes #249. Two races in dispose() crash with EXCEPTION_ACCESS_VIOLATION:

  1. Dispose during open/seek: dispose() never takes mediaOperationMutex, so removing the player from composition while openUri is inside native OpenMedia destroys the instance underneath it. Reproduced on Windows 11: a player removed from composition 0.3–1.2 s after openUri(PLAY) on a local 720p MP4 crashes in NativeVideoPlayer.dll with WindowsNativeBridge.nOpenMedia on the stack, in the first round. dispose() now does the native teardown while holding the mutex, spinning (not suspending, as it often runs on the EDT) for up to 2 s; if an open is still blocked in native code after that (e.g. a slow HTTP connect), the teardown finishes on a background thread once the open returns.
  2. Dispose during a frame read: after jobToJoin.cancel() it waited while (jobToJoin.isActive …), but a cancelled job is no longer active, so it never waited for the producer to leave ReadVideoFrame. It now waits for isCompleted.

Test plan

Windows 11 x64, a player shown then removed from composition 20 times (random 0.3–1.2 s apart) while playing a local 720p H.264 MP4:

  • v0.11.4: crashes in round 1 (EXCEPTION_ACCESS_VIOLATION, nOpenMedia on the stack)
  • this PR: 20 rounds without a crash, twice
  • :mediaplayer:compileKotlinJvm, ktlintCheck adds no findings

… frame read is using it

Two races in dispose() crashed with EXCEPTION_ACCESS_VIOLATION (kdroidFilter#249):
- It never took mediaOperationMutex, so disposing while openUri was inside
  native OpenMedia destroyed the instance underneath it (reproduced: removing a
  playing player from composition shortly after opening crashes in
  nOpenMedia). dispose() now tears down while holding the mutex, waiting up to
  2 s; if an open is still blocked in native code after that (slow HTTP
  connect), the teardown finishes on a background thread once it returns.
- It waited while jobToJoin.isActive after cancel(), but a cancelled job is no
  longer active, so it never waited for the producer to leave ReadVideoFrame.
  It now waits for isCompleted.
@muthuraj57
muthuraj57 force-pushed the fix-windows-dispose-race branch from df0985a to b7d7689 Compare October 24, 2026 11:31
@muthuraj57 muthuraj57 changed the title fix(windows): wait for the frame job to finish before closing native media on dispose fix(windows): don't tear down the native player while an open/seek or frame read is using it Oct 24, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

EXCEPTION_ACCESS_VIOLATION crash on Windows 10.

2 participants