Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: f2535d35a033d8a1d80b0ff0b1b713941dd98675
https://github.com/WebKit/WebKit/commit/f2535d35a033d8a1d80b0ff0b1b713941dd98675
Author: Chris Dumez <[email protected]>
Date: 2026-09-08 (Tue, 08 Sep 2026)
Changed paths:
M Source/JavaScriptCore/assembler/PerfLog.h
M Source/JavaScriptCore/ftl/FTLThunks.h
M Source/JavaScriptCore/heap/Heap.h
M Source/JavaScriptCore/heap/HeapSnapshotBuilder.h
M Source/JavaScriptCore/heap/ParallelSourceAdapter.h
M Source/JavaScriptCore/heap/SlotVisitor.cpp
M Source/JavaScriptCore/inspector/remote/RemoteConnectionToTarget.h
M Source/JavaScriptCore/jit/ExecutableAllocator.cpp
M Source/JavaScriptCore/jit/GdbJIT.h
M Source/JavaScriptCore/profiler/ProfilerDatabase.h
M Source/JavaScriptCore/runtime/JSRunLoopTimer.h
M Source/JavaScriptCore/runtime/NumberPredictionFuzzerAgent.h
M Source/JavaScriptCore/runtime/ProfilerSupport.h
M Source/JavaScriptCore/runtime/RandomizingFuzzerAgent.h
M Source/JavaScriptCore/runtime/RegExpCache.h
M Source/JavaScriptCore/wasm/WasmCalleeGroup.h
M Source/JavaScriptCore/wasm/WasmPlan.h
M Source/JavaScriptCore/wasm/WasmStreamingCompiler.h
M Source/JavaScriptCore/wasm/WasmThunks.cpp
M Source/JavaScriptCore/wasm/WasmThunks.h
M Source/WTF/wtf/ConcurrentPtrHashSet.h
M Source/WTF/wtf/CryptographicallyRandomNumber.cpp
M Source/WTF/wtf/RunLoop.h
M Source/WTF/wtf/darwin/OSLogPrintStream.h
M Source/WebCore/Modules/webaudio/AudioBufferSourceNode.h
M Source/WebCore/Modules/webaudio/AudioWorkletNode.h
M Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp
M Source/WebCore/dom/Event.cpp
M Source/WebCore/page/scrolling/ScrollingTreeLatchingController.cpp
M Source/WebCore/page/scrolling/ScrollingTreeLatchingController.h
M
Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.h
M Source/WebCore/platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm
M
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h
M Source/WebCore/platform/libwebrtc/LibWebRTCVPXVideoDecoder.cpp
M
Source/WebCore/platform/mediastream/cocoa/MediaStreamTrackAudioSourceProviderCocoa.h
M
Source/WebCore/platform/mediastream/cocoa/RealtimeIncomingVideoSourceCocoa.h
M
Source/WebCore/platform/mediastream/cocoa/RealtimeIncomingVideoSourceCocoa.mm
M Source/WebCore/platform/mediastream/cocoa/WebAudioSourceProviderCocoa.h
M Source/WebCore/platform/mediastream/cocoa/WebAudioSourceProviderCocoa.mm
M Source/WebCore/platform/mock/MockRealtimeVideoSource.h
M Source/WebKit/UIProcess/DisplayLinkProcessProxyClient.h
M
Source/WebKit/UIProcess/RemoteLayerTree/mac/RemoteLayerTreeEventDispatcher.h
M Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp
M Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.h
M Source/WebKit/WebProcess/GPU/webrtc/SharedVideoFrame.cpp
M Source/WebKit/WebProcess/GPU/webrtc/SharedVideoFrame.h
M Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.cpp
M Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.h
M Source/WebKit/WebProcess/WebPage/mac/WKAccessibilityWebPageObjectBase.h
M Source/WebKitLegacy/Storage/StorageAreaSync.h
M Source/WebKitLegacy/Storage/StorageTracker.cpp
M Source/WebKitLegacy/Storage/StorageTracker.h
Log Message:
-----------
Add missing thread-safety annotations and address potential issues they
uncovered
https://bugs.webkit.org/show_bug.cgi?id=323492
Reviewed by Keith Miller and Darin Adler.
Audited data members of type Lock across Source/ and annotated the state
each one actually protects with WTF_GUARDED_BY_LOCK, so that -Wthread-safety
enforces the locking discipline at compile time instead of leaving it to
comments and runtime assertions.
A member was only annotated where accessing it without the lock would be a bug,
i.e. where it is genuinely reached from more than one thread (parallel GC
markers, concurrent JIT/Wasm compiler threads, audio render vs. capture threads,
IPC and media work queues, the scrolling and accessibility threads, worker and
storage threads). Members that merely happen to be touched inside a critical
section that exists for a different member were deliberately left alone; for
example AudioBufferSourceNode::m_wasBufferSet is only used on the main thread in
setBufferForBindings(), and just happens to sit inside the m_processLock region
that synchronizes m_buffer with the audio thread.
Enforcing the annotations exposed several pre-existing bugs, fixed here:
- Event::initEvent() cleared m_target without holding m_targetLock, racing the
locked read in Event::visitInGCThread() on the GC thread. Every other write
goes through setTarget(), which does lock.
- ImageDecoderAVFObjC::readTrackMetadata() replaced m_imageRotationSession on
the main thread with no lock, while createFrameImageAtIndex() dereferences it
on the org.webkit.ImageDecoder work queue under m_sampleGeneratorLock.
- LibWebRTCCodecs::failedDecoding() set Decoder::hasError on the work queue
without m_connectionLock, which flushDecoder() and decodeFrameInternal() hold
when reading it. Taken in a scope that closes before decodedImageCallbackLock
is acquired, since the two locks are nowhere else nested.
- SharedVideoFrameWriter::m_isDisabled was a plain bool written by disable()
from another thread and read by wait(). disable() is intentionally called
without m_encodersConnectionLock (a writer blocked in wait() holds that lock,
so locking here would deadlock), so it is now accessed with
WTF::atomicLoad/atomicStore. It stays a plain bool rather than becoming a
std::atomic so that SharedVideoFrameWriter remains assignable from a
default-constructed temporary, which two call sites rely on to reset it.
- WebAudioSourceProviderCocoa::setNeedsFlush() mutated m_readCount and
m_underflowed from the work queue without m_lock, racing
provideInputInternal()
on the audio render thread. The render thread is unaffected because
provideInput() uses tryLock().
- MediaStreamTrackAudioSourceProviderCocoa::m_writeCount was written unlocked on
the capture thread and read under m_lock on the render thread. Made atomic
rather than locked, because prepare() already takes m_lock and is called from
audioSamplesAvailable(), so locking the callback would self-deadlock.
- WebServiceWorkerFetchTaskClient::convertFetchToDownload() set m_isDownload
without m_connectionLock, which the five reads hold. Taken in a scope that
closes before continueDidReceiveResponse() re-acquires the same lock.
- StorageAreaSync::m_syncCloseDatabase was set on the main thread and cleared on
the sync thread with no synchronization. Made atomic. Note the set/clear
interleaving is unchanged and still pre-existing: a close request landing
exactly as the sync thread clears the flag can be dropped.
- MockRealtimeVideoSource::m_isTakingPhoto was cleared on m_runLoop's thread and
read on the caller's thread. Made atomic, matching its sibling
m_captureWasInterrupted, which already was for that same thread pair.
- StorageTracker::finishedImportingOriginIdentifiers() guarded m_client with
m_databaseMutex, while the five other m_client accesses use m_clientMutex.
Two analysis escape hatches were replaced with real enforcement:
RealtimeIncomingVideoSourceCocoa::pixelBufferPool() was marked
WTF_IGNORES_THREAD_SAFETY_ANALYSIS and is now WTF_REQUIRES_LOCK, and the
ASSERT(!mutex.tryLock()) contracts in StorageTracker became WTF_REQUIRES_LOCK.
Two of those assertions were dropped rather than converted, because they
asserted a caller context rather than a requirement of the function's own
accesses: trackerDatabasePath() only reads m_storageDirectoryPath, which is set
in the constructor and never reassigned (now const), and canDeleteOrigin()
acquires m_originSetMutex itself and never touches m_database.
Where the lock is provably held but the analyzer cannot see it -- inside a
lambda
body, or through an opaque AbstractLocker& witness parameter -- assertIsHeld()
records the invariant rather than suppressing the check.
* Source/JavaScriptCore/assembler/PerfLog.h:
* Source/JavaScriptCore/ftl/FTLThunks.h:
* Source/JavaScriptCore/heap/Heap.h:
* Source/JavaScriptCore/heap/HeapSnapshotBuilder.h:
* Source/JavaScriptCore/heap/ParallelSourceAdapter.h:
* Source/JavaScriptCore/heap/SlotVisitor.cpp:
(JSC::SlotVisitor::drainFromShared):
* Source/JavaScriptCore/inspector/remote/RemoteConnectionToTarget.h:
(Inspector::RemoteConnectionToTarget::queueMutex):
(Inspector::RemoteConnectionToTarget::queue const):
* Source/JavaScriptCore/jit/ExecutableAllocator.cpp:
* Source/JavaScriptCore/jit/GdbJIT.h:
* Source/JavaScriptCore/profiler/ProfilerDatabase.h:
* Source/JavaScriptCore/runtime/JSRunLoopTimer.h:
* Source/JavaScriptCore/runtime/NumberPredictionFuzzerAgent.h:
* Source/JavaScriptCore/runtime/ProfilerSupport.h:
* Source/JavaScriptCore/runtime/RandomizingFuzzerAgent.h:
* Source/JavaScriptCore/runtime/RegExpCache.h:
* Source/JavaScriptCore/wasm/WasmCalleeGroup.h:
* Source/JavaScriptCore/wasm/WasmPlan.h:
* Source/JavaScriptCore/wasm/WasmStreamingCompiler.h:
* Source/JavaScriptCore/wasm/WasmThunks.cpp:
(JSC::Wasm::Thunks::stub):
* Source/JavaScriptCore/wasm/WasmThunks.h:
* Source/WTF/wtf/ConcurrentPtrHashSet.h:
* Source/WTF/wtf/CryptographicallyRandomNumber.cpp:
* Source/WTF/wtf/RunLoop.h:
* Source/WTF/wtf/darwin/OSLogPrintStream.h:
* Source/WebCore/Modules/webaudio/AudioBufferSourceNode.h:
* Source/WebCore/Modules/webaudio/AudioWorkletNode.h:
* Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp:
(WebCore::notificationQueue):
* Source/WebCore/dom/Event.cpp:
(WebCore::Event::initEvent):
* Source/WebCore/page/scrolling/ScrollingTreeLatchingController.cpp:
(WebCore::ScrollingTreeLatchingController::nodeDidHandleEvent):
* Source/WebCore/page/scrolling/ScrollingTreeLatchingController.h:
*
Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.h:
* Source/WebCore/platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm:
(WebCore::ImageDecoderAVFObjC::readTrackMetadata):
*
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
* Source/WebCore/platform/libwebrtc/LibWebRTCVPXVideoDecoder.cpp:
*
Source/WebCore/platform/mediastream/cocoa/MediaStreamTrackAudioSourceProviderCocoa.h:
* Source/WebCore/platform/mediastream/cocoa/RealtimeIncomingVideoSourceCocoa.h:
* Source/WebCore/platform/mediastream/cocoa/RealtimeIncomingVideoSourceCocoa.mm:
(WebCore::RealtimeIncomingVideoSourceCocoa::pixelBufferPool):
* Source/WebCore/platform/mediastream/cocoa/WebAudioSourceProviderCocoa.h:
* Source/WebCore/platform/mediastream/cocoa/WebAudioSourceProviderCocoa.mm:
(WebCore::WebAudioSourceProviderCocoa::setNeedsFlush):
* Source/WebCore/platform/mock/MockRealtimeVideoSource.h:
* Source/WebKit/UIProcess/DisplayLinkProcessProxyClient.h:
* Source/WebKit/UIProcess/RemoteLayerTree/mac/RemoteLayerTreeEventDispatcher.h:
* Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp:
(WebKit::LibWebRTCCodecs::failedDecoding):
* Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.h:
* Source/WebKit/WebProcess/GPU/webrtc/SharedVideoFrame.cpp:
(WebKit::SharedVideoFrameWriter::wait):
(WebKit::SharedVideoFrameWriter::disable):
* Source/WebKit/WebProcess/GPU/webrtc/SharedVideoFrame.h:
* Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.cpp:
(WebKit::WebServiceWorkerFetchTaskClient::convertFetchToDownload):
* Source/WebKit/WebProcess/Storage/WebServiceWorkerFetchTaskClient.h:
* Source/WebKit/WebProcess/WebPage/mac/WKAccessibilityWebPageObjectBase.h:
* Source/WebKitLegacy/Storage/StorageAreaSync.h:
* Source/WebKitLegacy/Storage/StorageTracker.cpp:
(WebKit::StorageTracker::trackerDatabasePath):
(WebKit::StorageTracker::openTrackerDatabase):
(WebKit::StorageTracker::finishedImportingOriginIdentifiers):
(WebKit::StorageTracker::willDeleteAllOrigins):
(WebKit::StorageTracker::willDeleteOrigin):
(WebKit::StorageTracker::canDeleteOrigin):
(WebKit::StorageTracker::databasePathForOrigin):
* Source/WebKitLegacy/Storage/StorageTracker.h:
Canonical link: https://commits.webkit.org/320645@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications