Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: d27194909794562e8ec457840a31ca25362817e5
https://github.com/WebKit/WebKit/commit/d27194909794562e8ec457840a31ca25362817e5
Author: Jean-Yves Avenard <[email protected]>
Date: 2026-05-18 (Mon, 18 May 2026)
Changed paths:
M LayoutTests/platform/mac/TestExpectations
M Source/WebCore/html/HTMLMediaElement.cpp
Log Message:
-----------
[Media] timeupdate event can dispatch ahead of 'seeking' under stress
https://bugs.webkit.org/show_bug.cgi?id=314792
rdar://177044662
Reviewed by Eric Carlson.
imported/w3c/web-platform-tests/media-source/mediasource-duration.html
test 2 ("Test appendBuffer completes previous seek to truncated duration")
intermittently fails with:
assert_equals: Event types match. expected "seeking" but got "timeupdate"
A `timeupdate` event dispatches ahead of the seek's `seeking` event,
violating the spec-required ordering for the seek algorithm's events.
The test's flow:
1. play() and append all media to a SourceBuffer.
2. mediaElement.currentTime = duration / 2; wait for seeking, timeupdate,
seeked.
3. sourceBuffer.remove(truncatedDuration = duration / 4, Infinity) —
removes data covering the current playback position.
4. Wait for sourceBuffer's updateend.
5. mediaSource.duration = truncatedDuration — the duration-change
algorithm internally seeks to the new (smaller) duration.
6. Expect 'seeking' as the next event on the media element.
Three independent race windows can each let a `timeupdate` slip in front of
that 'seeking':
(a) `seekWithTolerance` synchronously sets `m_seeking = true` and queues
`seekTask`. For fromDOM=true seeks, `seekTask` runs asynchronously, and the
existing cancel of `m_periodicTimeupdateCancellationGroup` lived inside
`seekTask` — too late: a `playbackProgressTimer` periodic `timeupdate`
queued just before `setCurrentTime` already dispatches before `seekTask`
runs. Move the cancel up into `seekWithTolerance`, right after
`setSeeking(true)`, so it runs in the same synchronous chain as
`setCurrentTime`. The existing `m_seeking` guard in
`scheduleTimeupdateEvent` continues to suppress any new periodic queued in
the window between the cancel and `seekTask` running.
(b) `mediaPlayerTimeChanged`'s else-branch unconditionally calls
`scheduleTimeupdateEvent(false)` for media-engine-reported time
discontinuities. Between `seekWithTolerance` setting `m_seeking = true` and
`seekTask` running, `m_seekRequested` is still `false` (it is set inside
`seekTask`), so the if-branch above (which calls `finishSeek` only when
`m_seekRequested` is set and the player has stopped seeking) cannot catch
this case and the else-branch fires a `timeupdate` that races ahead of
'seeking'. Gate the call on `!m_seeking` so the seek's own
seeking/timeupdate/seeked events take over once a seek is in flight; this
covers both the pre-`seekTask` gap and the period while the player itself
is still seeking.
(c) When a media element is detached from the document during an in-flight
seek, `pauseAfterDetachedTask` calls `pause()`, which schedules a
spec-mandated `timeupdate` from `pauseInternal`. The element retains its
event listeners after detach, so an active sibling test (notably a
parallel async_test in the same WPT page) still observes this `timeupdate`,
racing with the seek's `seeking`. Skip the `pause()` call when `m_seeking`
is true — the seek path will fire the relevant events when it completes.
The four spec-mandated `scheduleEvent(timeupdate)` paths (`pauseInternal`,
`setReadyState`'s readyState-drop branch, `seekTask`'s noSeekRequired
short-circuit, and `finishSeek`'s step-16 timeupdate) remain
non-cancellable; only periodic and discontinuity timeupdates are routed
through the cancellation group / suppressed during seek.
No new layout test: mediasource-duration.html (already in the tree) is the
regression sentinel for this race.
* Source/WebCore/html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::pauseAfterDetachedTask):
(WebCore::HTMLMediaElement::seekWithTolerance):
(WebCore::HTMLMediaElement::seekTask):
(WebCore::HTMLMediaElement::mediaPlayerTimeChanged):
Canonical link: https://commits.webkit.org/313447@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications