← All reports

`ThreadSafeWeakPtr` torn dual-pointer replaced with lock-protected storage

Component: WTF | a90ff51

ThreadSafeWeakPtr is WTF's cross-thread-safe weak reference, backed by a shared control block that tracks strong and weak refcounts plus a raw pointer to the target. Because C++ multiple inheritance means a base-class pointer and the most-derived object pointer can differ in address, the weak pointer previously stored a full second pointer — the interior object pointer — alongside the control-block RefPtr, as two separately-writable fields with no atomicity guarantee.

This commit replaces the interior pointer with a 16-bit offset from the control block's tracked object, freeing enough space to add a Lock, and moves both fields into a ThreadSafeWeakPtrStorage guarded by it. It also fixes RemoteAudioVideoRendererProxyManager, which had been reusing GPUConnectionToWebProcess's control block and computing an offset between two unrelated objects.

Tests added alongside it — ControlBlockFreedUnderReader, DoubleWeakDeref, TornPairOnAssignment — demonstrate the old code could free a control block while a reader was still using it, or double-deref a weak reference under concurrency. A writer thread reassigning the weak pointer could race a reader calling get(), letting the reader observe a new object pointer paired with a stale, unrelated control block, so the refcount and deref logic ended up operating on the wrong object's bookkeeping. The tradeoff is real: this roughly doubles the cost of a very hot, pervasively-used primitive, which matters for GPU process and media code paths that lean on it heavily.

The reusable pattern is a smart pointer or handle whose invariant spans two independently-writable fields — the pair must be updated atomically for the invariant to hold, but the type provides no mechanism enforcing that. Audit WTF's other multi-field handle types and any WebKit code that caches a control block and an interior pointer separately. Separately, the RemoteAudioVideoRendererProxyManager bug is its own pattern worth hunting: an object borrowing another object's control block, which makes the stored offset meaningless. Grep for ThreadSafeWeakPtr construction where the control-block source and the pointee are not the same object — the code-review tell is a weak pointer built from *this in one class but referencing a member or peer of a different class.