forked from mirrors/gecko-dev
Bug 1384395 - Use nsAutoOwningThread for mfbt/WeakPtr.h thread assertions (r=froydnj)
MozReview-Commit-ID: DF4DiffL4Qq
This commit is contained in:
parent
bc07dbc87a
commit
7e43e5439d
3 changed files with 25 additions and 19 deletions
|
|
@ -70,12 +70,20 @@
|
||||||
#include "mozilla/ArrayUtils.h"
|
#include "mozilla/ArrayUtils.h"
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/Maybe.h"
|
||||||
#include "mozilla/RefCounted.h"
|
#include "mozilla/RefCounted.h"
|
||||||
#include "mozilla/RefPtr.h"
|
#include "mozilla/RefPtr.h"
|
||||||
#include "mozilla/TypeTraits.h"
|
#include "mozilla/TypeTraits.h"
|
||||||
|
|
||||||
#include <string.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
|
// Weak referencing is not implemeted as thread safe. When a WeakPtr
|
||||||
// is created or dereferenced on thread A but the real object is just
|
// 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
|
// 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
|
// on a single thread. The following macros implement assertions for
|
||||||
// checking these conditions.
|
// checking these conditions.
|
||||||
//
|
//
|
||||||
// We disable this on MinGW. MinGW has two threading models: win32
|
// We re-use XPCOM's nsAutoOwningThread checks when they are available. This has
|
||||||
// API based, which disables std::thread; and POSIX based which
|
// the advantage that it works with cooperative thread pools.
|
||||||
// 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
|
|
||||||
|
|
||||||
#if !defined(__MINGW32__) && (defined(DEBUG) || (defined(NIGHTLY_BUILD) && !defined(MOZ_PROFILING)))
|
|
||||||
|
|
||||||
#include <thread>
|
|
||||||
#define MOZ_WEAKPTR_DECLARE_THREAD_SAFETY_CHECK \
|
#define MOZ_WEAKPTR_DECLARE_THREAD_SAFETY_CHECK \
|
||||||
std::thread::id _owningThread; \
|
/* Will be none if mPtr = nullptr. */ \
|
||||||
bool _empty; // If it was initialized as a placeholder with mPtr = nullptr.
|
Maybe<nsAutoOwningThread> _owningThread;
|
||||||
#define MOZ_WEAKPTR_INIT_THREAD_SAFETY_CHECK() \
|
#define MOZ_WEAKPTR_INIT_THREAD_SAFETY_CHECK() \
|
||||||
do { \
|
do { \
|
||||||
_owningThread = std::this_thread::get_id(); \
|
if (p) { \
|
||||||
_empty = !p; \
|
_owningThread.emplace(); \
|
||||||
|
} \
|
||||||
} while (false)
|
} while (false)
|
||||||
#define MOZ_WEAKPTR_ASSERT_THREAD_SAFETY() \
|
#define MOZ_WEAKPTR_ASSERT_THREAD_SAFETY() \
|
||||||
do { \
|
do { \
|
||||||
if (!(_empty || _owningThread == std::this_thread::get_id())) { \
|
if (_owningThread.isSome() && !_owningThread.ref().IsCurrentThread()) { \
|
||||||
WeakPtrTraits<T>::AssertSafeToAccessFromNonOwningThread(); \
|
WeakPtrTraits<T>::AssertSafeToAccessFromNonOwningThread(); \
|
||||||
} \
|
} \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,15 @@ nsAutoOwningThread::nsAutoOwningThread()
|
||||||
void
|
void
|
||||||
nsAutoOwningThread::AssertCurrentThreadOwnsMe(const char* msg) const
|
nsAutoOwningThread::AssertCurrentThreadOwnsMe(const char* msg) const
|
||||||
{
|
{
|
||||||
if (MOZ_UNLIKELY(mThread != GetCurrentVirtualThread())) {
|
if (MOZ_UNLIKELY(!IsCurrentThread())) {
|
||||||
// `msg` is a string literal by construction.
|
// `msg` is a string literal by construction.
|
||||||
MOZ_CRASH_UNSAFE_OOL(msg);
|
MOZ_CRASH_UNSAFE_OOL(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsAutoOwningThread::IsCurrentThread() const
|
||||||
|
{
|
||||||
|
return mThread == GetCurrentVirtualThread();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,8 @@ public:
|
||||||
AssertCurrentThreadOwnsMe(aMsg);
|
AssertCurrentThreadOwnsMe(aMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsCurrentThread() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void AssertCurrentThreadOwnsMe(const char* aMsg) const;
|
void AssertCurrentThreadOwnsMe(const char* aMsg) const;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue