зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1384395 - Use nsAutoOwningThread for mfbt/WeakPtr.h thread assertions (r=froydnj)
MozReview-Commit-ID: DF4DiffL4Qq
This commit is contained in:
Родитель
bc07dbc87a
Коммит
7e43e5439d
|
@ -70,12 +70,20 @@
|
|||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/RefCounted.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MOZILLA_INTERNAL_API)
|
||||
// For thread safety checking.
|
||||
#include "nsISupportsImpl.h"
|
||||
#endif
|
||||
|
||||
#if defined(MOZILLA_INTERNAL_API) && defined(MOZ_THREAD_SAFETY_OWNERSHIP_CHECKS_SUPPORTED)
|
||||
|
||||
// Weak referencing is not implemeted as thread safe. When a WeakPtr
|
||||
// is created or dereferenced on thread A but the real object is just
|
||||
// being Released() on thread B, there is a possibility of a race
|
||||
|
@ -89,31 +97,21 @@
|
|||
// on a single thread. The following macros implement assertions for
|
||||
// checking these conditions.
|
||||
//
|
||||
// We disable this on MinGW. MinGW has two threading models: win32
|
||||
// API based, which disables std::thread; and POSIX based which
|
||||
// enables it but requires an emulation library (winpthreads).
|
||||
// Rather than attempting to switch to pthread emulation at this point,
|
||||
// we are disabling the std::thread based assertion checking.
|
||||
//
|
||||
// In the future, to enable it we could
|
||||
// a. have libgcc/stdc++ support win32 threads natively
|
||||
// b. switch to POSIX-based threading in MinGW with pthread emulation
|
||||
// c. refactor it to not use std::thread
|
||||
// We re-use XPCOM's nsAutoOwningThread checks when they are available. This has
|
||||
// the advantage that it works with cooperative thread pools.
|
||||
|
||||
#if !defined(__MINGW32__) && (defined(DEBUG) || (defined(NIGHTLY_BUILD) && !defined(MOZ_PROFILING)))
|
||||
|
||||
#include <thread>
|
||||
#define MOZ_WEAKPTR_DECLARE_THREAD_SAFETY_CHECK \
|
||||
std::thread::id _owningThread; \
|
||||
bool _empty; // If it was initialized as a placeholder with mPtr = nullptr.
|
||||
/* Will be none if mPtr = nullptr. */ \
|
||||
Maybe<nsAutoOwningThread> _owningThread;
|
||||
#define MOZ_WEAKPTR_INIT_THREAD_SAFETY_CHECK() \
|
||||
do { \
|
||||
_owningThread = std::this_thread::get_id(); \
|
||||
_empty = !p; \
|
||||
if (p) { \
|
||||
_owningThread.emplace(); \
|
||||
} \
|
||||
} while (false)
|
||||
#define MOZ_WEAKPTR_ASSERT_THREAD_SAFETY() \
|
||||
do { \
|
||||
if (!(_empty || _owningThread == std::this_thread::get_id())) { \
|
||||
if (_owningThread.isSome() && !_owningThread.ref().IsCurrentThread()) { \
|
||||
WeakPtrTraits<T>::AssertSafeToAccessFromNonOwningThread(); \
|
||||
} \
|
||||
} while (false)
|
||||
|
|
|
@ -38,9 +38,15 @@ nsAutoOwningThread::nsAutoOwningThread()
|
|||
void
|
||||
nsAutoOwningThread::AssertCurrentThreadOwnsMe(const char* msg) const
|
||||
{
|
||||
if (MOZ_UNLIKELY(mThread != GetCurrentVirtualThread())) {
|
||||
if (MOZ_UNLIKELY(!IsCurrentThread())) {
|
||||
// `msg` is a string literal by construction.
|
||||
MOZ_CRASH_UNSAFE_OOL(msg);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsAutoOwningThread::IsCurrentThread() const
|
||||
{
|
||||
return mThread == GetCurrentVirtualThread();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -69,6 +69,8 @@ public:
|
|||
AssertCurrentThreadOwnsMe(aMsg);
|
||||
}
|
||||
|
||||
bool IsCurrentThread() const;
|
||||
|
||||
private:
|
||||
void AssertCurrentThreadOwnsMe(const char* aMsg) const;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче