Bug 1207753 - dom misc thread-safety annotations r=hsivonen,smaug

Differential Revision: https://phabricator.services.mozilla.com/D130598
This commit is contained in:
Randell Jesup 2022-03-25 13:32:35 +00:00
parent 398deea5b2
commit 258c7cbfe7
7 changed files with 60 additions and 46 deletions

View File

@ -78,10 +78,10 @@ class ConsoleReportCollector final : public nsIConsoleReportCollector {
const CopyableTArray<nsString> mStringParams;
};
Mutex mMutex MOZ_UNANNOTATED;
Mutex mMutex;
// protected by mMutex
nsTArray<PendingReport> mPendingReports;
nsTArray<PendingReport> mPendingReports GUARDED_BY(mMutex);
public:
NS_DECL_THREADSAFE_ISUPPORTS

View File

@ -148,26 +148,29 @@ class HangMonitorChild : public PProcessHangMonitorChild,
static Atomic<HangMonitorChild*, SequentiallyConsistent> sInstance;
const RefPtr<ProcessHangMonitor> mHangMonitor;
Monitor mMonitor MOZ_UNANNOTATED;
Monitor mMonitor;
// Main thread-only.
bool mSentReport;
// These fields must be accessed with mMonitor held.
bool mTerminateScript;
bool mStartDebugger;
bool mFinishedStartingDebugger;
bool mPaintWhileInterruptingJS;
TabId mPaintWhileInterruptingJSTab;
MOZ_INIT_OUTSIDE_CTOR LayersObserverEpoch mPaintWhileInterruptingJSEpoch;
bool mCancelContentJS;
TabId mCancelContentJSTab;
nsIRemoteTab::NavigationType mCancelContentJSNavigationType;
int32_t mCancelContentJSNavigationIndex;
mozilla::Maybe<nsCString> mCancelContentJSNavigationURI;
int32_t mCancelContentJSEpoch;
JSContext* mContext;
bool mShutdownDone;
bool mTerminateScript GUARDED_BY(mMonitor);
bool mStartDebugger GUARDED_BY(mMonitor);
bool mFinishedStartingDebugger GUARDED_BY(mMonitor);
bool mPaintWhileInterruptingJS GUARDED_BY(mMonitor);
TabId mPaintWhileInterruptingJSTab GUARDED_BY(mMonitor);
MOZ_INIT_OUTSIDE_CTOR LayersObserverEpoch mPaintWhileInterruptingJSEpoch
GUARDED_BY(mMonitor);
bool mCancelContentJS GUARDED_BY(mMonitor);
TabId mCancelContentJSTab GUARDED_BY(mMonitor);
nsIRemoteTab::NavigationType mCancelContentJSNavigationType
GUARDED_BY(mMonitor);
int32_t mCancelContentJSNavigationIndex GUARDED_BY(mMonitor);
mozilla::Maybe<nsCString> mCancelContentJSNavigationURI GUARDED_BY(mMonitor);
int32_t mCancelContentJSEpoch GUARDED_BY(mMonitor);
bool mShutdownDone GUARDED_BY(mMonitor);
JSContext* mContext; // const after constructor
// This field is only accessed on the hang thread.
bool mIPCOpen;
@ -282,16 +285,20 @@ class HangMonitorParent : public PProcessHangMonitorParent,
// This field is only accessed on the hang thread.
bool mIPCOpen;
Monitor mMonitor MOZ_UNANNOTATED;
Monitor mMonitor;
// MainThread only
RefPtr<HangMonitoredProcess> mProcess;
// Must be accessed with mMonitor held.
RefPtr<HangMonitoredProcess> mProcess;
bool mShutdownDone;
bool mShutdownDone GUARDED_BY(mMonitor);
// Map from plugin ID to crash dump ID. Protected by
// mBrowserCrashDumpHashLock.
nsTHashMap<nsUint32HashKey, nsString> mBrowserCrashDumpIds;
Mutex mBrowserCrashDumpHashLock MOZ_UNANNOTATED;
mozilla::ipc::TaskFactory<HangMonitorParent> mMainThreadTaskFactory;
nsTHashMap<nsUint32HashKey, nsString> mBrowserCrashDumpIds
GUARDED_BY(mMonitor);
Mutex mBrowserCrashDumpHashLock GUARDED_BY(mMonitor);
mozilla::ipc::TaskFactory<HangMonitorParent> mMainThreadTaskFactory
GUARDED_BY(mMonitor);
};
} // namespace
@ -315,6 +322,7 @@ HangMonitorChild::HangMonitorChild(ProcessHangMonitor* aMonitor)
mPaintWhileInterruptingJSActive(false) {
MOZ_RELEASE_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!sInstance);
mContext = danger::GetJSContext();
BackgroundHangMonitor::RegisterAnnotator(*this);

View File

@ -20,30 +20,32 @@ namespace mozilla {
// Default reader locking strategy, using a mutex to ensure that concurrent
// PopAll calls won't overlap.
class MultiWriterQueueReaderLocking_Mutex {
class CAPABILITY MultiWriterQueueReaderLocking_Mutex {
public:
MultiWriterQueueReaderLocking_Mutex()
: mMutex("MultiWriterQueueReaderLocking_Mutex") {}
PUSH_IGNORE_THREAD_SAFETY
void Lock() { mMutex.Lock(); };
void Unlock() { mMutex.Unlock(); };
POP_THREAD_SAFETY
void Lock() CAPABILITY_ACQUIRE(mMutex) { mMutex.Lock(); };
void Unlock() CAPABILITY_RELEASE(mMutex) { mMutex.Unlock(); };
private:
Mutex mMutex MOZ_UNANNOTATED;
Mutex mMutex;
};
// Reader non-locking strategy, trusting that PopAll will never be called
// concurrently (e.g., by only calling it from a specific thread).
class MultiWriterQueueReaderLocking_None {
class CAPABILITY MultiWriterQueueReaderLocking_None {
public:
#ifndef DEBUG
void Lock(){};
void Unlock(){};
void Lock() CAPABILITY_ACQUIRE(){};
void Unlock() CAPABILITY_RELEASE(){};
#else
// DEBUG-mode checks to catch concurrent misuses.
void Lock() { MOZ_ASSERT(mLocked.compareExchange(false, true)); };
void Unlock() { MOZ_ASSERT(mLocked.compareExchange(true, false)); };
void Lock() CAPABILITY_ACQUIRE() {
MOZ_ASSERT(mLocked.compareExchange(false, true));
};
void Unlock() CAPABILITY_RELEASE() {
MOZ_ASSERT(mLocked.compareExchange(true, false));
};
private:
Atomic<bool> mLocked{false};

View File

@ -73,6 +73,7 @@ already_AddRefed<PerformanceStorageWorker> PerformanceStorageWorker::Create(
RefPtr<PerformanceStorageWorker> storage = new PerformanceStorageWorker();
MutexAutoLock lock(storage->mMutex); // for thread-safety analysis
storage->mWorkerRef = WeakWorkerRef::Create(
aWorkerPrivate, [storage]() { storage->ShutdownOnWorker(); });

View File

@ -37,11 +37,11 @@ class PerformanceStorageWorker final : public PerformanceStorage {
PerformanceStorageWorker();
~PerformanceStorageWorker();
Mutex mMutex MOZ_UNANNOTATED;
Mutex mMutex;
// Protected by mutex.
// Created and released on worker-thread. Used also on main-thread.
RefPtr<WeakWorkerRef> mWorkerRef;
RefPtr<WeakWorkerRef> mWorkerRef GUARDED_BY(mMutex);
};
} // namespace dom

View File

@ -116,18 +116,19 @@ class ArrayBufferBuilder {
ArrayBufferBuilder& operator=(const ArrayBufferBuilder&) = delete;
ArrayBufferBuilder& operator=(const ArrayBufferBuilder&&) = delete;
bool SetCapacityInternal(uint32_t aNewCap, const MutexAutoLock& aProofOfLock);
bool SetCapacityInternal(uint32_t aNewCap, const MutexAutoLock& aProofOfLock)
REQUIRES(mMutex);
static bool AreOverlappingRegions(const uint8_t* aStart1, uint32_t aLength1,
const uint8_t* aStart2, uint32_t aLength2);
Mutex mMutex MOZ_UNANNOTATED;
Mutex mMutex;
// All of these are protected by mMutex.
uint8_t* mDataPtr;
uint32_t mCapacity;
uint32_t mLength;
void* mMapPtr;
uint8_t* mDataPtr GUARDED_BY(mMutex);
uint32_t mCapacity GUARDED_BY(mMutex);
uint32_t mLength GUARDED_BY(mMutex);
void* mMapPtr GUARDED_BY(mMutex);
// This is used in assertions only.
bool mNeutered;

View File

@ -26,10 +26,12 @@ class XMLHttpRequestStringBuffer final {
return mData.Length();
}
uint32_t UnsafeLength() const { return mData.Length(); }
uint32_t UnsafeLength() const NO_THREAD_SAFETY_ANALYSIS {
return mData.Length();
}
mozilla::Result<mozilla::BulkWriteHandle<char16_t>, nsresult> UnsafeBulkWrite(
uint32_t aCapacity) {
uint32_t aCapacity) NO_THREAD_SAFETY_ANALYSIS {
return mData.BulkWrite(aCapacity, UnsafeLength(), false);
}
@ -82,10 +84,10 @@ class XMLHttpRequestStringBuffer final {
nsString& UnsafeData() { return mData; }
Mutex mMutex MOZ_UNANNOTATED;
Mutex mMutex;
// The following member variable is protected by mutex.
nsString mData;
nsString mData GUARDED_BY(mMutex);
};
// ---------------------------------------------------------------------------