зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 2 changesets (bug 1618121, bug 1617993) for assertion failure at nsTArray.h . CLOSED TREE
Backed out changeset e4d228335a49 (bug 1617993) Backed out changeset b874484bdeb7 (bug 1618121)
This commit is contained in:
Родитель
20b5709c6a
Коммит
02dfadf8c9
|
@ -20,37 +20,45 @@ enum class CheckingSupport {
|
|||
Disabled,
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class CheckedUnsafePtr;
|
||||
|
||||
namespace detail {
|
||||
class CheckedUnsafePtrBaseCheckingEnabled;
|
||||
template <CheckingSupport>
|
||||
class CheckedUnsafePtrBase;
|
||||
|
||||
struct CheckedUnsafePtrCheckData {
|
||||
using Data = nsTArray<CheckedUnsafePtrBaseCheckingEnabled*>;
|
||||
using Data = nsTArray<CheckedUnsafePtrBase<CheckingSupport::Enabled>*>;
|
||||
|
||||
DataMutex<Data> mPtrs{"mozilla::SupportsCheckedUnsafePtr"};
|
||||
};
|
||||
|
||||
class CheckedUnsafePtrBaseCheckingEnabled {
|
||||
template <>
|
||||
class CheckedUnsafePtrBase<CheckingSupport::Disabled> {
|
||||
protected:
|
||||
template <typename Ptr>
|
||||
void CopyDanglingFlagIfAvailableFrom(const Ptr&) {}
|
||||
|
||||
template <typename Ptr, typename F>
|
||||
void WithCheckedUnsafePtrsImpl(Ptr, F&&) {}
|
||||
};
|
||||
|
||||
template <>
|
||||
class CheckedUnsafePtrBase<CheckingSupport::Enabled> {
|
||||
friend class CheckedUnsafePtrBaseAccess;
|
||||
|
||||
protected:
|
||||
constexpr CheckedUnsafePtrBaseCheckingEnabled() = default;
|
||||
CheckedUnsafePtrBaseCheckingEnabled(
|
||||
const CheckedUnsafePtrBaseCheckingEnabled& aOther) = default;
|
||||
CheckedUnsafePtrBase() = default;
|
||||
CheckedUnsafePtrBase(const CheckedUnsafePtrBase& aOther) = default;
|
||||
|
||||
// When copying an CheckedUnsafePtr, its mIsDangling member must be copied as
|
||||
// well; otherwise the new copy might try to dereference a dangling pointer
|
||||
// when destructed.
|
||||
void CopyDanglingFlagIfAvailableFrom(
|
||||
const CheckedUnsafePtrBaseCheckingEnabled& aOther) {
|
||||
const CheckedUnsafePtrBase<CheckingSupport::Enabled>& aOther) {
|
||||
mIsDangling = aOther.mIsDangling;
|
||||
}
|
||||
|
||||
template <typename Ptr>
|
||||
using DisableForCheckedUnsafePtr = std::enable_if_t<
|
||||
!std::is_base_of<CheckedUnsafePtrBaseCheckingEnabled, Ptr>::value>;
|
||||
using DisableForCheckedUnsafePtr =
|
||||
std::enable_if_t<!std::is_base_of<CheckedUnsafePtrBase, Ptr>::value>;
|
||||
|
||||
// When constructing an CheckedUnsafePtr from a different kind of pointer it's
|
||||
// not possible to determine whether it's dangling; therefore it's undefined
|
||||
|
@ -74,136 +82,11 @@ class CheckedUnsafePtrBaseCheckingEnabled {
|
|||
|
||||
class CheckedUnsafePtrBaseAccess {
|
||||
protected:
|
||||
static void SetDanglingFlag(CheckedUnsafePtrBaseCheckingEnabled& aBase) {
|
||||
static void SetDanglingFlag(
|
||||
CheckedUnsafePtrBase<CheckingSupport::Enabled>& aBase) {
|
||||
aBase.mIsDangling = true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, CheckingSupport = T::SupportsChecking::value>
|
||||
class CheckedUnsafePtrBase;
|
||||
|
||||
template <typename T, typename U, typename S = std::nullptr_t>
|
||||
using EnableIfCompatible =
|
||||
std::enable_if_t<std::is_base_of<T, std::remove_reference_t<decltype(
|
||||
*std::declval<U>())>>::value,
|
||||
S>;
|
||||
|
||||
template <typename T>
|
||||
class CheckedUnsafePtrBase<T, CheckingSupport::Enabled>
|
||||
: detail::CheckedUnsafePtrBaseCheckingEnabled {
|
||||
public:
|
||||
MOZ_IMPLICIT constexpr CheckedUnsafePtrBase(const std::nullptr_t = nullptr)
|
||||
: mRawPtr(nullptr) {}
|
||||
|
||||
template <typename U, typename = EnableIfCompatible<T, U>>
|
||||
MOZ_IMPLICIT CheckedUnsafePtrBase(const U& aPtr) {
|
||||
Set(aPtr);
|
||||
}
|
||||
|
||||
CheckedUnsafePtrBase(const CheckedUnsafePtrBase& aOther) {
|
||||
Set(aOther.Downcast());
|
||||
}
|
||||
|
||||
~CheckedUnsafePtrBase() { Reset(); }
|
||||
|
||||
CheckedUnsafePtr<T>& operator=(const std::nullptr_t) {
|
||||
Reset();
|
||||
return Downcast();
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
EnableIfCompatible<T, U, CheckedUnsafePtr<T>&> operator=(const U& aPtr) {
|
||||
Replace(aPtr);
|
||||
return Downcast();
|
||||
}
|
||||
|
||||
CheckedUnsafePtr<T>& operator=(const CheckedUnsafePtr<T>& aOther) {
|
||||
if (&aOther != this) {
|
||||
Replace(aOther);
|
||||
}
|
||||
return Downcast();
|
||||
}
|
||||
|
||||
constexpr T* get() const { return mRawPtr; }
|
||||
|
||||
private:
|
||||
template <typename U, CheckingSupport>
|
||||
friend class CheckedUnsafePtrBase;
|
||||
|
||||
CheckedUnsafePtr<T>& Downcast() {
|
||||
return static_cast<CheckedUnsafePtr<T>&>(*this);
|
||||
}
|
||||
const CheckedUnsafePtr<T>& Downcast() const {
|
||||
return static_cast<const CheckedUnsafePtr<T>&>(*this);
|
||||
}
|
||||
|
||||
using Base = detail::CheckedUnsafePtrBaseCheckingEnabled;
|
||||
|
||||
template <typename U>
|
||||
void Replace(const U& aPtr) {
|
||||
Reset();
|
||||
Set(aPtr);
|
||||
}
|
||||
|
||||
void Reset() {
|
||||
WithCheckedUnsafePtrs(
|
||||
[](Base* const aSelf,
|
||||
detail::CheckedUnsafePtrCheckData::Data& aCheckedUnsafePtrs) {
|
||||
const auto index = aCheckedUnsafePtrs.IndexOf(aSelf);
|
||||
aCheckedUnsafePtrs.UnorderedRemoveElementAt(index);
|
||||
});
|
||||
mRawPtr = nullptr;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void Set(const U& aPtr) {
|
||||
this->CopyDanglingFlagIfAvailableFrom(aPtr);
|
||||
mRawPtr = &*aPtr;
|
||||
WithCheckedUnsafePtrs(
|
||||
[](Base* const aSelf,
|
||||
detail::CheckedUnsafePtrCheckData::Data& aCheckedUnsafePtrs) {
|
||||
aCheckedUnsafePtrs.AppendElement(aSelf);
|
||||
});
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void WithCheckedUnsafePtrs(F&& aClosure) {
|
||||
this->WithCheckedUnsafePtrsImpl(mRawPtr, std::forward<F>(aClosure));
|
||||
}
|
||||
|
||||
T* mRawPtr;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class CheckedUnsafePtrBase<T, CheckingSupport::Disabled> {
|
||||
public:
|
||||
MOZ_IMPLICIT constexpr CheckedUnsafePtrBase(const std::nullptr_t = nullptr)
|
||||
: mRawPtr(nullptr) {}
|
||||
|
||||
template <typename U, typename = EnableIfCompatible<T, U>>
|
||||
MOZ_IMPLICIT constexpr CheckedUnsafePtrBase(const U& aPtr) : mRawPtr(aPtr) {}
|
||||
|
||||
constexpr CheckedUnsafePtr<T>& operator=(const std::nullptr_t) {
|
||||
mRawPtr = nullptr;
|
||||
return Downcast();
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
constexpr EnableIfCompatible<T, U, CheckedUnsafePtr<T>&> operator=(
|
||||
const U& aPtr) {
|
||||
mRawPtr = aPtr;
|
||||
return Downcast();
|
||||
}
|
||||
|
||||
constexpr T* get() const { return mRawPtr; }
|
||||
|
||||
private:
|
||||
constexpr CheckedUnsafePtr<T>& Downcast() {
|
||||
return static_cast<CheckedUnsafePtr<T>&>(*this);
|
||||
}
|
||||
|
||||
T* mRawPtr;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
class CheckingPolicyAccess {
|
||||
|
@ -335,46 +218,117 @@ class SupportsCheckedUnsafePtr
|
|||
// can be used, has the same size, and imposes no additional thread-safety
|
||||
// restrictions.
|
||||
template <typename T>
|
||||
class CheckedUnsafePtr : public detail::CheckedUnsafePtrBase<T> {
|
||||
class CheckedUnsafePtr
|
||||
: private detail::CheckedUnsafePtrBase<T::SupportsChecking::value> {
|
||||
static_assert(
|
||||
std::is_base_of<detail::SupportsCheckedUnsafePtrTag, T>::value,
|
||||
"type T must be derived from instantiation of SupportsCheckedUnsafePtr");
|
||||
|
||||
template <typename U>
|
||||
friend class CheckedUnsafePtr;
|
||||
|
||||
template <typename U, typename S = std::nullptr_t>
|
||||
using EnableIfCompatible =
|
||||
std::enable_if_t<std::is_base_of<T, std::remove_reference_t<decltype(
|
||||
*std::declval<U>())>>::value,
|
||||
S>;
|
||||
|
||||
public:
|
||||
using detail::CheckedUnsafePtrBase<T>::CheckedUnsafePtrBase;
|
||||
using detail::CheckedUnsafePtrBase<T>::get;
|
||||
|
||||
constexpr T* operator->() const { return get(); }
|
||||
|
||||
constexpr T& operator*() const { return *get(); }
|
||||
|
||||
MOZ_IMPLICIT constexpr operator T*() const { return get(); }
|
||||
MOZ_IMPLICIT CheckedUnsafePtr(const std::nullptr_t = nullptr)
|
||||
: mRawPtr(nullptr){};
|
||||
|
||||
template <typename U>
|
||||
constexpr bool operator==(
|
||||
detail::EnableIfCompatible<T, U, const U&> aRhs) const {
|
||||
return get() == aRhs.get();
|
||||
MOZ_IMPLICIT CheckedUnsafePtr(const U& aPtr,
|
||||
EnableIfCompatible<U> = nullptr) {
|
||||
Set(aPtr);
|
||||
}
|
||||
|
||||
CheckedUnsafePtr(const CheckedUnsafePtr& aOther) { Set(aOther); }
|
||||
|
||||
~CheckedUnsafePtr() { Reset(); }
|
||||
|
||||
CheckedUnsafePtr& operator=(const std::nullptr_t) {
|
||||
Reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
friend constexpr bool operator==(
|
||||
detail::EnableIfCompatible<T, U, const U&> aLhs,
|
||||
const CheckedUnsafePtr& aRhs) {
|
||||
EnableIfCompatible<U, CheckedUnsafePtr&> operator=(const U& aPtr) {
|
||||
Replace(aPtr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CheckedUnsafePtr& operator=(const CheckedUnsafePtr& aOther) {
|
||||
if (&aOther != this) {
|
||||
Replace(aOther);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
T* operator->() const { return mRawPtr; }
|
||||
|
||||
T& operator*() const { return *operator->(); }
|
||||
|
||||
MOZ_IMPLICIT operator T*() const { return operator->(); }
|
||||
|
||||
template <typename U>
|
||||
bool operator==(EnableIfCompatible<U, const U&> aRhs) const {
|
||||
return mRawPtr == &*aRhs;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
friend bool operator==(EnableIfCompatible<U, const U&> aLhs,
|
||||
const CheckedUnsafePtr& aRhs) {
|
||||
return aRhs == aLhs;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
constexpr bool operator!=(
|
||||
detail::EnableIfCompatible<T, U, const U&> aRhs) const {
|
||||
bool operator!=(EnableIfCompatible<U, const U&> aRhs) const {
|
||||
return !(*this == aRhs);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
friend constexpr bool operator!=(
|
||||
detail::EnableIfCompatible<T, U, const U&> aLhs,
|
||||
const CheckedUnsafePtr& aRhs) {
|
||||
friend bool operator!=(EnableIfCompatible<U, const U&> aLhs,
|
||||
const CheckedUnsafePtr& aRhs) {
|
||||
return aRhs != aLhs;
|
||||
}
|
||||
|
||||
private:
|
||||
using Base = detail::CheckedUnsafePtrBase<CheckingSupport::Enabled>;
|
||||
|
||||
template <typename U>
|
||||
void Replace(const U& aPtr) {
|
||||
Reset();
|
||||
Set(aPtr);
|
||||
}
|
||||
|
||||
void Reset() {
|
||||
WithCheckedUnsafePtrs(
|
||||
[](Base* const aSelf,
|
||||
detail::CheckedUnsafePtrCheckData::Data& aCheckedUnsafePtrs) {
|
||||
const auto index = aCheckedUnsafePtrs.IndexOf(aSelf);
|
||||
aCheckedUnsafePtrs.UnorderedRemoveElementAt(index);
|
||||
});
|
||||
mRawPtr = nullptr;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void Set(const U& aPtr) {
|
||||
this->CopyDanglingFlagIfAvailableFrom(aPtr);
|
||||
mRawPtr = &*aPtr;
|
||||
WithCheckedUnsafePtrs(
|
||||
[](Base* const aSelf,
|
||||
detail::CheckedUnsafePtrCheckData::Data& aCheckedUnsafePtrs) {
|
||||
aCheckedUnsafePtrs.AppendElement(aSelf);
|
||||
});
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void WithCheckedUnsafePtrs(F&& aClosure) {
|
||||
this->WithCheckedUnsafePtrsImpl(mRawPtr, std::forward<F>(aClosure));
|
||||
}
|
||||
|
||||
T* mRawPtr;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -8,19 +8,6 @@
|
|||
|
||||
using namespace mozilla;
|
||||
|
||||
class NoCheckTestType
|
||||
: public SupportsCheckedUnsafePtr<DoNotCheckCheckedUnsafePtrs> {};
|
||||
|
||||
static_assert(std::is_literal_type_v<CheckedUnsafePtr<NoCheckTestType>>);
|
||||
static_assert(
|
||||
std::is_trivially_copy_constructible_v<CheckedUnsafePtr<NoCheckTestType>>);
|
||||
static_assert(
|
||||
std::is_trivially_copy_assignable_v<CheckedUnsafePtr<NoCheckTestType>>);
|
||||
static_assert(
|
||||
std::is_trivially_move_constructible_v<CheckedUnsafePtr<NoCheckTestType>>);
|
||||
static_assert(
|
||||
std::is_trivially_move_assignable_v<CheckedUnsafePtr<NoCheckTestType>>);
|
||||
|
||||
class TestCheckingPolicy : public CheckCheckedUnsafePtrs<TestCheckingPolicy> {
|
||||
protected:
|
||||
explicit TestCheckingPolicy(bool& aPassedCheck)
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#define mozilla_dom_SharedWorkerManager_h
|
||||
|
||||
#include "mozilla/dom/RemoteWorkerController.h"
|
||||
#include "mozilla/dom/quota/CheckedUnsafePtr.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
|
@ -26,8 +25,7 @@ class SharedWorkerParent;
|
|||
// Main-thread only object that keeps a manager and the service alive.
|
||||
// When the last SharedWorkerManagerHolder is released, the corresponding
|
||||
// manager unregisters itself from the service and terminates the worker.
|
||||
class SharedWorkerManagerHolder final
|
||||
: public SupportsCheckedUnsafePtr<CheckIf<DiagnosticAssertEnabled>> {
|
||||
class SharedWorkerManagerHolder final {
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(SharedWorkerManagerHolder);
|
||||
|
||||
|
@ -41,8 +39,8 @@ class SharedWorkerManagerHolder final
|
|||
private:
|
||||
~SharedWorkerManagerHolder();
|
||||
|
||||
const RefPtr<SharedWorkerManager> mManager;
|
||||
const RefPtr<SharedWorkerService> mService;
|
||||
RefPtr<SharedWorkerManager> mManager;
|
||||
RefPtr<SharedWorkerService> mService;
|
||||
};
|
||||
|
||||
// Thread-safe wrapper for SharedWorkerManagerHolder.
|
||||
|
@ -126,23 +124,23 @@ class SharedWorkerManager final : public RemoteWorkerObserver {
|
|||
nsCOMPtr<nsIEventTarget> mPBackgroundEventTarget;
|
||||
|
||||
nsCOMPtr<nsIPrincipal> mLoadingPrincipal;
|
||||
const nsCString mDomain;
|
||||
const OriginAttributes mStoragePrincipalAttrs;
|
||||
const nsCOMPtr<nsIURI> mResolvedScriptURL;
|
||||
const nsString mName;
|
||||
const bool mIsSecureContext;
|
||||
nsCString mDomain;
|
||||
OriginAttributes mStoragePrincipalAttrs;
|
||||
nsCOMPtr<nsIURI> mResolvedScriptURL;
|
||||
nsString mName;
|
||||
bool mIsSecureContext;
|
||||
bool mSuspended;
|
||||
bool mFrozen;
|
||||
|
||||
// Raw pointers because SharedWorkerParent unregisters itself in
|
||||
// ActorDestroy().
|
||||
nsTArray<CheckedUnsafePtr<SharedWorkerParent>> mActors;
|
||||
nsTArray<SharedWorkerParent*> mActors;
|
||||
|
||||
RefPtr<RemoteWorkerController> mRemoteWorkerController;
|
||||
|
||||
// Main-thread only. Raw Pointers because holders keep the manager alive and
|
||||
// they unregister themselves in their DTOR.
|
||||
nsTArray<CheckedUnsafePtr<SharedWorkerManagerHolder>> mHolders;
|
||||
nsTArray<SharedWorkerManagerHolder*> mHolders;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#define mozilla_dom_dom_SharedWorkerParent_h
|
||||
|
||||
#include "mozilla/dom/PSharedWorkerParent.h"
|
||||
#include "mozilla/dom/quota/CheckedUnsafePtr.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
|
@ -19,9 +18,7 @@ class MessagePortIdentifier;
|
|||
class RemoteWorkerData;
|
||||
class SharedWorkerManagerWrapper;
|
||||
|
||||
class SharedWorkerParent final
|
||||
: public mozilla::dom::PSharedWorkerParent,
|
||||
public SupportsCheckedUnsafePtr<CheckIf<DiagnosticAssertEnabled>> {
|
||||
class SharedWorkerParent final : public mozilla::dom::PSharedWorkerParent {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedWorkerParent)
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ StaticMutex sSharedWorkerMutex;
|
|||
|
||||
// Raw pointer because SharedWorkerParent keeps this object alive, indirectly
|
||||
// via SharedWorkerManagerHolder.
|
||||
CheckedUnsafePtr<SharedWorkerService> sSharedWorkerService;
|
||||
SharedWorkerService* MOZ_NON_OWNING_REF sSharedWorkerService;
|
||||
|
||||
class GetOrCreateWorkerManagerRunnable final : public Runnable {
|
||||
public:
|
||||
|
@ -119,7 +119,7 @@ already_AddRefed<SharedWorkerService> SharedWorkerService::GetOrCreate() {
|
|||
StaticMutexAutoLock lock(sSharedWorkerMutex);
|
||||
|
||||
if (sSharedWorkerService) {
|
||||
RefPtr<SharedWorkerService> instance = sSharedWorkerService.get();
|
||||
RefPtr<SharedWorkerService> instance = sSharedWorkerService;
|
||||
return instance.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#ifndef mozilla_dom_SharedWorkerService_h
|
||||
#define mozilla_dom_SharedWorkerService_h
|
||||
|
||||
#include "mozilla/dom/quota/CheckedUnsafePtr.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
|
@ -25,8 +24,7 @@ class SharedWorkerManager;
|
|||
class SharedWorkerParent;
|
||||
class UniqueMessagePortId;
|
||||
|
||||
class SharedWorkerService final
|
||||
: public SupportsCheckedUnsafePtr<CheckIf<DiagnosticAssertEnabled>> {
|
||||
class SharedWorkerService final {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedWorkerService);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче