Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 42ca5cc802a1492a3d701874b0e7cbd03aa2f948
https://github.com/WebKit/WebKit/commit/42ca5cc802a1492a3d701874b0e7cbd03aa2f948
Author: Chris Dumez <[email protected]>
Date: 2026-09-10 (Thu, 10 Sep 2026)
Changed paths:
M Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp
M Source/WebCore/platform/mock/MockRealtimeVideoSource.h
Log Message:
-----------
MockRealtimeVideoSource shares five members between its capture run loop and
its caller's thread without synchronization
https://bugs.webkit.org/show_bug.cgi?id=323742
Reviewed by Jean-Yves Avenard.
Frames are generated on m_runLoop, a dedicated run loop, while the source is
controlled from
the caller's thread; generateFrame() and generatePhoto() assert !isMainThread()
to say so. The
class already guards m_imageBuffer and m_drawingState with a lock, makes
m_isTakingPhoto and
m_captureWasInterrupted atomic, and marshals timer start and stop onto
m_runLoop. Five members
were left out of all of that, and the run loop reaches four of them indirectly,
through helper
calls, which is what kept them hidden:
- m_startTime and m_elapsedTime are written by startProducingData() and
stopProducingData(),
and read by elapsedTime(), which drawText() and
MockRealtimeVideoSourceMac::updateSampleBuffer()
both call while generating a frame.
- m_preset is written by applyFrameRateAndZoomWithPreset() and read by
captureSize(), which the
whole draw path calls.
- m_deviceOrientation is written by orientationChanged() and
rotationAngleForHorizonLevelDisplayChanged(), and read by
videoFrameRotation() from
updateSampleBuffer().
- m_delayUntil is written by delaySamples() and both read and cleared by
generateFrame().
Each is fixed by whichever mechanism matches how it is reached rather than by
one blanket
approach. m_startTime, m_elapsedTime and m_preset become WTF_GUARDED_BY_LOCK:
every reader on
the run loop already held the lock, so only the writers needed changing, and
elapsedTime() and
captureSize() get assertIsHeld() to match how the surrounding code already
declares this.
m_deviceOrientation becomes atomic instead, because the lock does not fit it:
videoFrameRotation()
is virtual on RealtimeMediaSource and so may be called from anywhere, and
settings() reads the
member on the caller's thread. m_delayUntil moves entirely onto m_runLoop by
dispatching from
delaySamples(), the same way startCaptureTimer() and stopCaptureTimer() already
work; the
deadline is still computed at call time so it does not shift with dispatch
latency.
Annotating m_preset immediately turned up a third accessor that reading the
code had not:
settings() reads it on the caller's thread, which now takes the lock for that
one read.
applyFrameRateAndZoomWithPreset() is restructured so setIntrinsicSize(), which
notifies
observers, is not called while holding the lock.
The lock is renamed from m_imageBufferLock to m_frameGenerationLock. It already
guarded
m_drawingState and now covers three further members that are not image buffers.
None of this is reachable by web content: MockRealtimeVideoSource is only
created by
MockRealtimeMediaSourceCenter, that is, when mock capture devices are enabled
for testing. Nor
was any of it a memory-safety problem, since everything read across the thread
boundary is
plain data, a MonotonicTime, a Seconds, an enum, or the IntSize inside
m_preset. The visible
symptom would have been a wrong timestamp, rotation or frame size in a
generated mock frame.
* Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp:
(WebCore::MockRealtimeVideoSource::takePhotoInternal):
(WebCore::MockRealtimeVideoSource::settings):
(WebCore::MockRealtimeVideoSource::applyFrameRateAndZoomWithPreset):
(WebCore::MockRealtimeVideoSource::captureSize const):
(WebCore::MockRealtimeVideoSource::invalidateDrawingState):
(WebCore::MockRealtimeVideoSource::drawingState):
(WebCore::MockRealtimeVideoSource::settingsDidChange):
(WebCore::MockRealtimeVideoSource::startProducingData):
(WebCore::MockRealtimeVideoSource::stopProducingData):
(WebCore::MockRealtimeVideoSource::elapsedTime):
(WebCore::MockRealtimeVideoSource::drawText):
(WebCore::MockRealtimeVideoSource::delaySamples):
(WebCore::MockRealtimeVideoSource::generatePhoto):
(WebCore::MockRealtimeVideoSource::generateFrameInternal):
(WebCore::MockRealtimeVideoSource::generateFrame):
(WebCore::MockRealtimeVideoSource::imageBuffer):
(WebCore::MockRealtimeVideoSource::imageBufferInternal):
(WebCore::MockRealtimeVideoSource::orientationChanged):
* Source/WebCore/platform/mock/MockRealtimeVideoSource.h:
(WebCore::MockRealtimeVideoSource::WTF_GUARDED_BY_LOCK):
Canonical link: https://commits.webkit.org/320813@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications