From c635cee7282e9ea23b9ccb2adbc3ddbdfe61e625 Mon Sep 17 00:00:00 2001 From: Perry Jiang Date: Tue, 21 Jan 2020 13:33:04 +0000 Subject: [PATCH] Bug 1601024 - ThreadSafeWeakReference::tryDetach must acquire its lock r=froydnj Differential Revision: https://phabricator.services.mozilla.com/D60037 --HG-- extra : moz-landing-system : lando --- mfbt/ThreadSafeWeakPtr.h | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/mfbt/ThreadSafeWeakPtr.h b/mfbt/ThreadSafeWeakPtr.h index 355c8ee2504c..ca9e777133e1 100644 --- a/mfbt/ThreadSafeWeakPtr.h +++ b/mfbt/ThreadSafeWeakPtr.h @@ -111,10 +111,16 @@ class ReadWriteSpinLock { // Decrement the counter to remove a read lock. void readUnlock() { mCounter--; } - // Try to acquire the write lock, but only if there are no readers. - // If successful, sets the counter to a negative value. - bool tryWriteLock() { - return mCounter.compareExchange(0, std::numeric_limits::min()); + // Spins until a write lock is acquired. This can only occur if there are no + // readers or writers. Once it is acquired, the counter is set to a negative + // value. + void writeLock() { + while (true) { + if (mCounter.compareExchange(0, + std::numeric_limits::min())) { + return; + } + } } // Reset the counter to 0. @@ -169,12 +175,11 @@ class ThreadSafeWeakReference // to check the refcount and verify that this is the last reference to // the tracked object, so the weak reference can be safely detached. void tryDetach(const SupportsThreadSafeWeakPtr* aOwner) { - if (mLock.tryWriteLock()) { - if (aOwner->hasOneRef()) { - mPtr = nullptr; - } - mLock.writeUnlock(); + mLock.writeLock(); + if (aOwner->hasOneRef()) { + mPtr = nullptr; } + mLock.writeUnlock(); } ReadWriteSpinLock mLock;