Bug 1623278 - Use SafeRefPtr for IDBFactory. r=dom-workers-and-storage-reviewers,asuth

Differential Revision: https://phabricator.services.mozilla.com/D66972

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Simon Giesecke 2020-04-01 09:54:43 +00:00
parent e614684d09
commit da859a31b2
13 changed files with 135 additions and 158 deletions

View File

@ -4625,7 +4625,12 @@ Storage* nsGlobalWindowInner::GetLocalStorage(ErrorResult& aError) {
IDBFactory* nsGlobalWindowInner::GetIndexedDB(ErrorResult& aError) {
if (!mIndexedDB) {
// This may keep mIndexedDB null without setting an error.
aError = IDBFactory::CreateForWindow(this, getter_AddRefs(mIndexedDB));
auto res = IDBFactory::CreateForWindow(this);
if (res.isErr()) {
aError = res.unwrapErr();
} else {
mIndexedDB = res.unwrap();
}
}
return mIndexedDB;

View File

@ -491,18 +491,18 @@ class MOZ_STACK_CLASS ResultHelper final : public IDBRequest::ResultCallback {
class PermissionRequestMainProcessHelper final : public PermissionRequestBase {
BackgroundFactoryRequestChild* mActor;
RefPtr<IDBFactory> mFactory;
SafeRefPtr<IDBFactory> mFactory;
public:
PermissionRequestMainProcessHelper(BackgroundFactoryRequestChild* aActor,
IDBFactory* aFactory,
SafeRefPtr<IDBFactory> aFactory,
Element* aOwnerElement,
nsIPrincipal* aPrincipal)
: PermissionRequestBase(aOwnerElement, aPrincipal),
mActor(aActor),
mFactory(aFactory) {
mFactory(std::move(aFactory)) {
MOZ_ASSERT(aActor);
MOZ_ASSERT(aFactory);
MOZ_ASSERT(mFactory);
aActor->AssertIsOnOwningThread();
}
@ -857,16 +857,16 @@ class WorkerPermissionChallenge final : public Runnable {
public:
WorkerPermissionChallenge(WorkerPrivate* aWorkerPrivate,
BackgroundFactoryRequestChild* aActor,
IDBFactory* aFactory,
SafeRefPtr<IDBFactory> aFactory,
PrincipalInfo&& aPrincipalInfo)
: Runnable("indexedDB::WorkerPermissionChallenge"),
mWorkerPrivate(aWorkerPrivate),
mActor(aActor),
mFactory(aFactory),
mFactory(std::move(aFactory)),
mPrincipalInfo(std::move(aPrincipalInfo)) {
MOZ_ASSERT(mWorkerPrivate);
MOZ_ASSERT(aActor);
MOZ_ASSERT(aFactory);
MOZ_ASSERT(mFactory);
mWorkerPrivate->AssertIsOnWorkerThread();
}
@ -908,7 +908,7 @@ class WorkerPermissionChallenge final : public Runnable {
MaybeCollectGarbageOnIPCMessage();
const RefPtr<IDBFactory> factory = std::move(mFactory);
const SafeRefPtr<IDBFactory> factory = std::move(mFactory);
Unused << factory; // XXX see Bug 1605075
mActor->SendPermissionRetry();
@ -976,7 +976,7 @@ class WorkerPermissionChallenge final : public Runnable {
private:
WorkerPrivate* const mWorkerPrivate;
BackgroundFactoryRequestChild* mActor;
RefPtr<IDBFactory> mFactory;
SafeRefPtr<IDBFactory> mFactory;
const PrincipalInfo mPrincipalInfo;
};
@ -1442,11 +1442,10 @@ void BackgroundRequestChildBase::AssertIsOnOwningThread() const {
* BackgroundFactoryChild
******************************************************************************/
BackgroundFactoryChild::BackgroundFactoryChild(IDBFactory* aFactory)
: mFactory(aFactory) {
BackgroundFactoryChild::BackgroundFactoryChild(IDBFactory& aFactory)
: mFactory(&aFactory) {
AssertIsOnOwningThread();
MOZ_ASSERT(aFactory);
aFactory->AssertIsOnOwningThread();
mFactory->AssertIsOnOwningThread();
MOZ_COUNT_CTOR(indexedDB::BackgroundFactoryChild);
}
@ -1531,16 +1530,16 @@ BackgroundFactoryChild::RecvPBackgroundIDBDatabaseConstructor(
******************************************************************************/
BackgroundFactoryRequestChild::BackgroundFactoryRequestChild(
IDBFactory* aFactory, IDBOpenDBRequest* aOpenRequest, bool aIsDeleteOp,
uint64_t aRequestedVersion)
SafeRefPtr<IDBFactory> aFactory, IDBOpenDBRequest* aOpenRequest,
bool aIsDeleteOp, uint64_t aRequestedVersion)
: BackgroundRequestChildBase(aOpenRequest),
mFactory(aFactory),
mFactory(std::move(aFactory)),
mDatabaseActor(nullptr),
mRequestedVersion(aRequestedVersion),
mIsDeleteOp(aIsDeleteOp) {
// Can't assert owning thread here because IPDL has not yet set our manager!
MOZ_ASSERT(aFactory);
aFactory->AssertIsOnOwningThread();
MOZ_ASSERT(mFactory);
mFactory->AssertIsOnOwningThread();
MOZ_ASSERT(aOpenRequest);
MOZ_COUNT_CTOR(indexedDB::BackgroundFactoryRequestChild);
@ -1702,7 +1701,7 @@ mozilla::ipc::IPCResult BackgroundFactoryRequestChild::RecvPermissionChallenge(
workerPrivate->AssertIsOnWorkerThread();
RefPtr<WorkerPermissionChallenge> challenge = new WorkerPermissionChallenge(
workerPrivate, this, mFactory, std::move(aPrincipalInfo));
workerPrivate, this, mFactory.clonePtr(), std::move(aPrincipalInfo));
if (!challenge->Dispatch()) {
return IPC_FAIL_NO_REASON(this);
}
@ -1733,8 +1732,8 @@ mozilla::ipc::IPCResult BackgroundFactoryRequestChild::RecvPermissionChallenge(
}
RefPtr<PermissionRequestMainProcessHelper> helper =
new PermissionRequestMainProcessHelper(this, mFactory, ownerElement,
principal);
new PermissionRequestMainProcessHelper(this, mFactory.clonePtr(),
ownerElement, principal);
PermissionRequestBase::PermissionValue permission;
if (NS_WARN_IF(NS_FAILED(helper->PromptIfNeeded(&permission)))) {
@ -1854,12 +1853,15 @@ void BackgroundDatabaseChild::EnsureDOMObject() {
auto request = mOpenRequestActor->GetOpenDBRequest();
MOZ_ASSERT(request);
auto factory =
auto& factory =
static_cast<BackgroundFactoryChild*>(Manager())->GetDOMObject();
MOZ_ASSERT(factory);
mTemporaryStrongDatabase =
IDBDatabase::Create(request, factory, this, std::move(mSpec));
// TODO: This AcquireStrongRefFromRawPtr looks suspicious. This should be
// changed or at least well explained, see also comment on
// BackgroundFactoryChild.
mTemporaryStrongDatabase = IDBDatabase::Create(
request, SafeRefPtr{&factory, AcquireStrongRefFromRawPtr{}}, this,
std::move(mSpec));
MOZ_ASSERT(mTemporaryStrongDatabase);
mTemporaryStrongDatabase->AssertIsOnOwningThread();

View File

@ -145,6 +145,10 @@ class BackgroundFactoryChild final : public PBackgroundIDBFactoryChild {
friend class mozilla::ipc::BackgroundChildImpl;
friend IDBFactory;
// TODO: This long-lived raw pointer is very suspicious, in particular as it
// is used in BackgroundDatabaseChild::EnsureDOMObject to reacquire a strong
// reference. What ensures it is kept alive, and why can't we store a strong
// reference here?
IDBFactory* mFactory;
NS_DECL_OWNINGTHREAD
@ -154,16 +158,17 @@ class BackgroundFactoryChild final : public PBackgroundIDBFactoryChild {
NS_ASSERT_OWNINGTHREAD(BackgroundFactoryChild);
}
IDBFactory* GetDOMObject() const {
IDBFactory& GetDOMObject() const {
AssertIsOnOwningThread();
return mFactory;
MOZ_ASSERT(mFactory);
return *mFactory;
}
bool SendDeleteMe() = delete;
private:
// Only created by IDBFactory.
explicit BackgroundFactoryChild(IDBFactory* aFactory);
explicit BackgroundFactoryChild(IDBFactory& aFactory);
// Only destroyed by mozilla::ipc::BackgroundChildImpl.
~BackgroundFactoryChild();
@ -222,7 +227,7 @@ class BackgroundFactoryRequestChild final
friend class PermissionRequestChild;
friend class PermissionRequestParent;
const RefPtr<IDBFactory> mFactory;
const SafeRefPtr<IDBFactory> mFactory;
// Normally when opening of a database is successful, we receive a database
// actor in request response, so we can use it to call ReleaseDOMObject()
@ -245,7 +250,7 @@ class BackgroundFactoryRequestChild final
private:
// Only created by IDBFactory.
BackgroundFactoryRequestChild(IDBFactory* aFactory,
BackgroundFactoryRequestChild(SafeRefPtr<IDBFactory> aFactory,
IDBOpenDBRequest* aOpenRequest,
bool aIsDeleteOp, uint64_t aRequestedVersion);

View File

@ -146,11 +146,12 @@ class IDBDatabase::Observer final : public nsIObserver {
NS_DECL_NSIOBSERVER
};
IDBDatabase::IDBDatabase(IDBOpenDBRequest* aRequest, IDBFactory* aFactory,
IDBDatabase::IDBDatabase(IDBOpenDBRequest* aRequest,
SafeRefPtr<IDBFactory> aFactory,
BackgroundDatabaseChild* aActor,
UniquePtr<DatabaseSpec> aSpec)
: DOMEventTargetHelper(aRequest),
mFactory(aFactory),
mFactory(std::move(aFactory)),
mSpec(std::move(aSpec)),
mBackgroundActor(aActor),
mFileHandleDisabled(aRequest->IsFileHandleDisabled()),
@ -159,8 +160,8 @@ IDBDatabase::IDBDatabase(IDBOpenDBRequest* aRequest, IDBFactory* aFactory,
mQuotaExceeded(false),
mIncreasedActiveDatabaseCount(false) {
MOZ_ASSERT(aRequest);
MOZ_ASSERT(aFactory);
aFactory->AssertIsOnOwningThread();
MOZ_ASSERT(mFactory);
mFactory->AssertIsOnOwningThread();
MOZ_ASSERT(aActor);
MOZ_ASSERT(mSpec);
}
@ -173,7 +174,7 @@ IDBDatabase::~IDBDatabase() {
// static
RefPtr<IDBDatabase> IDBDatabase::Create(IDBOpenDBRequest* aRequest,
IDBFactory* aFactory,
SafeRefPtr<IDBFactory> aFactory,
BackgroundDatabaseChild* aActor,
UniquePtr<DatabaseSpec> aSpec) {
MOZ_ASSERT(aRequest);
@ -183,7 +184,7 @@ RefPtr<IDBDatabase> IDBDatabase::Create(IDBOpenDBRequest* aRequest,
MOZ_ASSERT(aSpec);
RefPtr<IDBDatabase> db =
new IDBDatabase(aRequest, aFactory, aActor, std::move(aSpec));
new IDBDatabase(aRequest, aFactory.clonePtr(), aActor, std::move(aSpec));
if (NS_IsMainThread()) {
nsCOMPtr<nsPIDOMWindowInner> window =
@ -228,7 +229,7 @@ void IDBDatabase::AssertIsOnOwningThread() const {
nsIEventTarget* IDBDatabase::EventTarget() const {
AssertIsOnOwningThread();
return Factory()->EventTarget();
return mFactory->EventTarget();
}
void IDBDatabase::CloseInternal() {
@ -1042,7 +1043,7 @@ void IDBDatabase::LastRelease() {
nsresult IDBDatabase::PostHandleEvent(EventChainPostVisitor& aVisitor) {
nsresult rv =
IndexedDatabaseManager::CommonPostHandleEvent(aVisitor, mFactory);
IndexedDatabaseManager::CommonPostHandleEvent(aVisitor, *mFactory);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

View File

@ -61,7 +61,7 @@ class IDBDatabase final : public DOMEventTargetHelper {
// The factory must be kept alive when IndexedDB is used in multiple
// processes. If it dies then the entire actor tree will be destroyed with it
// and the world will explode.
RefPtr<IDBFactory> mFactory;
SafeRefPtr<IDBFactory> mFactory;
UniquePtr<DatabaseSpec> mSpec;
@ -89,7 +89,7 @@ class IDBDatabase final : public DOMEventTargetHelper {
public:
static MOZ_MUST_USE RefPtr<IDBDatabase> Create(
IDBOpenDBRequest* aRequest, IDBFactory* aFactory,
IDBOpenDBRequest* aRequest, SafeRefPtr<IDBFactory> aFactory,
indexedDB::BackgroundDatabaseChild* aActor,
UniquePtr<DatabaseSpec> aSpec);
@ -147,12 +147,6 @@ class IDBDatabase final : public DOMEventTargetHelper {
// DatabaseInfo.
void RevertToPreviousState();
IDBFactory* Factory() const {
AssertIsOnOwningThread();
return mFactory;
}
void RegisterTransaction(IDBTransaction* aTransaction);
void UnregisterTransaction(IDBTransaction* aTransaction);
@ -238,7 +232,7 @@ class IDBDatabase final : public DOMEventTargetHelper {
JS::Handle<JSObject*> aGivenProto) override;
private:
IDBDatabase(IDBOpenDBRequest* aRequest, IDBFactory* aFactory,
IDBDatabase(IDBOpenDBRequest* aRequest, SafeRefPtr<IDBFactory> aFactory,
indexedDB::BackgroundDatabaseChild* aActor,
UniquePtr<DatabaseSpec> aSpec);

View File

@ -113,7 +113,7 @@ struct IDBFactory::PendingRequestInfo {
}
};
IDBFactory::IDBFactory()
IDBFactory::IDBFactory(const IDBFactoryGuard&)
: mBackgroundActor(nullptr),
mInnerWindowID(0),
mActiveTransactionCount(0),
@ -133,26 +133,24 @@ IDBFactory::~IDBFactory() {
}
// static
nsresult IDBFactory::CreateForWindow(nsPIDOMWindowInner* aWindow,
IDBFactory** aFactory) {
Result<RefPtr<IDBFactory>, nsresult> IDBFactory::CreateForWindow(
nsPIDOMWindowInner* aWindow) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aWindow);
MOZ_ASSERT(aFactory);
nsCOMPtr<nsIPrincipal> principal;
nsresult rv = AllowedForWindowInternal(aWindow, &principal);
if (rv == NS_ERROR_DOM_NOT_SUPPORTED_ERR) {
NS_WARNING("IndexedDB is not permitted in a third-party window.");
*aFactory = nullptr;
return NS_OK;
return RefPtr<IDBFactory>{};
}
if (NS_WARN_IF(NS_FAILED(rv))) {
if (rv == NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR) {
IDB_REPORT_INTERNAL_ERR();
}
return rv;
return Err(rv);
}
MOZ_ASSERT(principal);
@ -161,7 +159,7 @@ nsresult IDBFactory::CreateForWindow(nsPIDOMWindowInner* aWindow,
rv = PrincipalToPrincipalInfo(principal, principalInfo.get());
if (NS_WARN_IF(NS_FAILED(rv))) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
MOZ_ASSERT(principalInfo->type() == PrincipalInfo::TContentPrincipalInfo ||
@ -169,13 +167,13 @@ nsresult IDBFactory::CreateForWindow(nsPIDOMWindowInner* aWindow,
if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(*principalInfo))) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aWindow);
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(webNav);
RefPtr<IDBFactory> factory = new IDBFactory();
auto factory = MakeRefPtr<IDBFactory>(IDBFactoryGuard{});
factory->mPrincipalInfo = std::move(principalInfo);
factory->mGlobal = do_QueryInterface(aWindow);
@ -188,19 +186,18 @@ nsresult IDBFactory::CreateForWindow(nsPIDOMWindowInner* aWindow,
factory->mPrivateBrowsingMode =
loadContext && loadContext->UsePrivateBrowsing();
factory.forget(aFactory);
return NS_OK;
return factory;
}
// static
nsresult IDBFactory::CreateForMainThreadJS(nsIGlobalObject* aGlobal,
IDBFactory** aFactory) {
Result<RefPtr<IDBFactory>, nsresult> IDBFactory::CreateForMainThreadJS(
nsIGlobalObject* aGlobal) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aGlobal);
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(aGlobal);
if (NS_WARN_IF(!sop)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
auto principalInfo = MakeUnique<PrincipalInfo>();
@ -208,52 +205,36 @@ nsresult IDBFactory::CreateForMainThreadJS(nsIGlobalObject* aGlobal,
MOZ_ASSERT(principal);
bool isSystem;
if (!AllowedForPrincipal(principal, &isSystem)) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
nsresult rv = PrincipalToPrincipalInfo(principal, principalInfo.get());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
return Err(rv);
}
if (NS_WARN_IF(!QuotaManager::IsPrincipalInfoValid(*principalInfo))) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
rv = CreateForMainThreadJSInternal(aGlobal, std::move(principalInfo),
aFactory);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
MOZ_ASSERT(!principalInfo);
return NS_OK;
return CreateForMainThreadJSInternal(aGlobal, std::move(principalInfo));
}
// static
nsresult IDBFactory::CreateForWorker(nsIGlobalObject* aGlobal,
const PrincipalInfo& aPrincipalInfo,
uint64_t aInnerWindowID,
IDBFactory** aFactory) {
Result<RefPtr<IDBFactory>, nsresult> IDBFactory::CreateForWorker(
nsIGlobalObject* aGlobal, const PrincipalInfo& aPrincipalInfo,
uint64_t aInnerWindowID) {
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(aGlobal);
MOZ_ASSERT(aPrincipalInfo.type() != PrincipalInfo::T__None);
nsresult rv =
CreateInternal(aGlobal, MakeUnique<PrincipalInfo>(aPrincipalInfo),
aInnerWindowID, aFactory);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
return CreateInternal(aGlobal, MakeUnique<PrincipalInfo>(aPrincipalInfo),
aInnerWindowID);
}
// static
nsresult IDBFactory::CreateForMainThreadJSInternal(
nsIGlobalObject* aGlobal, UniquePtr<PrincipalInfo> aPrincipalInfo,
IDBFactory** aFactory) {
Result<RefPtr<IDBFactory>, nsresult> IDBFactory::CreateForMainThreadJSInternal(
nsIGlobalObject* aGlobal, UniquePtr<PrincipalInfo> aPrincipalInfo) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aGlobal);
MOZ_ASSERT(aPrincipalInfo);
@ -261,44 +242,34 @@ nsresult IDBFactory::CreateForMainThreadJSInternal(
IndexedDatabaseManager* mgr = IndexedDatabaseManager::GetOrCreate();
if (NS_WARN_IF(!mgr)) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
nsresult rv = CreateInternal(aGlobal, std::move(aPrincipalInfo),
/* aInnerWindowID */ 0, aFactory);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
return CreateInternal(aGlobal, std::move(aPrincipalInfo),
/* aInnerWindowID */ 0);
}
// static
nsresult IDBFactory::CreateInternal(nsIGlobalObject* aGlobal,
UniquePtr<PrincipalInfo> aPrincipalInfo,
uint64_t aInnerWindowID,
IDBFactory** aFactory) {
Result<RefPtr<IDBFactory>, nsresult> IDBFactory::CreateInternal(
nsIGlobalObject* aGlobal, UniquePtr<PrincipalInfo> aPrincipalInfo,
uint64_t aInnerWindowID) {
MOZ_ASSERT(aGlobal);
MOZ_ASSERT(aPrincipalInfo);
MOZ_ASSERT(aPrincipalInfo->type() != PrincipalInfo::T__None);
MOZ_ASSERT(aFactory);
if (aPrincipalInfo->type() != PrincipalInfo::TContentPrincipalInfo &&
aPrincipalInfo->type() != PrincipalInfo::TSystemPrincipalInfo) {
NS_WARNING("IndexedDB not allowed for this principal!");
aPrincipalInfo = nullptr;
*aFactory = nullptr;
return NS_OK;
return RefPtr<IDBFactory>{};
}
RefPtr<IDBFactory> factory = new IDBFactory();
auto factory = MakeRefPtr<IDBFactory>(IDBFactoryGuard{});
factory->mPrincipalInfo = std::move(aPrincipalInfo);
factory->mGlobal = aGlobal;
factory->mEventTarget = GetCurrentThreadEventTarget();
factory->mInnerWindowID = aInnerWindowID;
factory.forget(aFactory);
return NS_OK;
return factory;
}
// static
@ -686,7 +657,7 @@ RefPtr<IDBOpenDBRequest> IDBFactory::OpenInternal(
}
{
BackgroundFactoryChild* actor = new BackgroundFactoryChild(this);
BackgroundFactoryChild* actor = new BackgroundFactoryChild(*this);
// Set EventTarget for the top-level actor.
// All child actors created later inherit the same event target.
@ -715,8 +686,8 @@ RefPtr<IDBOpenDBRequest> IDBFactory::OpenInternal(
}
}
RefPtr<IDBOpenDBRequest> request =
IDBOpenDBRequest::Create(aCx, this, mGlobal);
RefPtr<IDBOpenDBRequest> request = IDBOpenDBRequest::Create(
aCx, SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, mGlobal);
if (!request) {
MOZ_ASSERT(!NS_IsMainThread());
aRv.ThrowUncatchableException();
@ -776,8 +747,9 @@ nsresult IDBFactory::InitiateRequest(IDBOpenDBRequest* aRequest,
MOZ_CRASH("Should never get here!");
}
auto actor = new BackgroundFactoryRequestChild(this, aRequest, deleting,
requestedVersion);
auto actor = new BackgroundFactoryRequestChild(
SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, aRequest, deleting,
requestedVersion);
if (!mBackgroundActor->SendPBackgroundIDBFactoryRequestConstructor(actor,
aParams)) {

View File

@ -56,6 +56,7 @@ class IDBFactory final : public nsISupports, public nsWrapperCache {
class BackgroundCreateCallback;
struct PendingRequestInfo;
struct IDBFactoryGuard {};
UniquePtr<PrincipalInfo> mPrincipalInfo;
@ -79,16 +80,17 @@ class IDBFactory final : public nsISupports, public nsWrapperCache {
bool mPrivateBrowsingMode;
public:
static nsresult CreateForWindow(nsPIDOMWindowInner* aWindow,
IDBFactory** aFactory);
explicit IDBFactory(const IDBFactoryGuard&);
static nsresult CreateForMainThreadJS(nsIGlobalObject* aGlobal,
IDBFactory** aFactory);
static Result<RefPtr<IDBFactory>, nsresult> CreateForWindow(
nsPIDOMWindowInner* aWindow);
static nsresult CreateForWorker(nsIGlobalObject* aGlobal,
const PrincipalInfo& aPrincipalInfo,
uint64_t aInnerWindowID,
IDBFactory** aFactory);
static Result<RefPtr<IDBFactory>, nsresult> CreateForMainThreadJS(
nsIGlobalObject* aGlobal);
static Result<RefPtr<IDBFactory>, nsresult> CreateForWorker(
nsIGlobalObject* aGlobal, const PrincipalInfo& aPrincipalInfo,
uint64_t aInnerWindowID);
static bool AllowedForWindow(nsPIDOMWindowInner* aWindow);
@ -182,17 +184,14 @@ class IDBFactory final : public nsISupports, public nsWrapperCache {
JS::Handle<JSObject*> aGivenProto) override;
private:
IDBFactory();
~IDBFactory();
static nsresult CreateForMainThreadJSInternal(
nsIGlobalObject* aGlobal, UniquePtr<PrincipalInfo> aPrincipalInfo,
IDBFactory** aFactory);
static Result<RefPtr<IDBFactory>, nsresult> CreateForMainThreadJSInternal(
nsIGlobalObject* aGlobal, UniquePtr<PrincipalInfo> aPrincipalInfo);
static nsresult CreateInternal(nsIGlobalObject* aGlobal,
UniquePtr<PrincipalInfo> aPrincipalInfo,
uint64_t aInnerWindowID,
IDBFactory** aFactory);
static Result<RefPtr<IDBFactory>, nsresult> CreateInternal(
nsIGlobalObject* aGlobal, UniquePtr<PrincipalInfo> aPrincipalInfo,
uint64_t aInnerWindowID);
static nsresult AllowedForWindowInternal(nsPIDOMWindowInner* aWindow,
nsCOMPtr<nsIPrincipal>* aPrincipal);

View File

@ -369,15 +369,15 @@ void IDBRequest::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
aVisitor.SetParentTarget(mTransaction, false);
}
IDBOpenDBRequest::IDBOpenDBRequest(IDBFactory* aFactory,
IDBOpenDBRequest::IDBOpenDBRequest(SafeRefPtr<IDBFactory> aFactory,
nsIGlobalObject* aGlobal,
bool aFileHandleDisabled)
: IDBRequest(aGlobal),
mFactory(aFactory),
mFactory(std::move(aFactory)),
mFileHandleDisabled(aFileHandleDisabled),
mIncreasedActiveDatabaseCount(false) {
AssertIsOnOwningThread();
MOZ_ASSERT(aFactory);
MOZ_ASSERT(mFactory);
MOZ_ASSERT(aGlobal);
}
@ -387,9 +387,8 @@ IDBOpenDBRequest::~IDBOpenDBRequest() {
}
// static
RefPtr<IDBOpenDBRequest> IDBOpenDBRequest::Create(JSContext* aCx,
IDBFactory* aFactory,
nsIGlobalObject* aGlobal) {
RefPtr<IDBOpenDBRequest> IDBOpenDBRequest::Create(
JSContext* aCx, SafeRefPtr<IDBFactory> aFactory, nsIGlobalObject* aGlobal) {
MOZ_ASSERT(aFactory);
aFactory->AssertIsOnOwningThread();
MOZ_ASSERT(aGlobal);
@ -397,7 +396,7 @@ RefPtr<IDBOpenDBRequest> IDBOpenDBRequest::Create(JSContext* aCx,
bool fileHandleDisabled = !IndexedDatabaseManager::IsFileHandleEnabled();
RefPtr<IDBOpenDBRequest> request =
new IDBOpenDBRequest(aFactory, aGlobal, fileHandleDisabled);
new IDBOpenDBRequest(std::move(aFactory), aGlobal, fileHandleDisabled);
CaptureCaller(aCx, request->mFilename, &request->mLineNo, &request->mColumn);
if (!NS_IsMainThread()) {
@ -500,7 +499,7 @@ NS_IMPL_RELEASE_INHERITED(IDBOpenDBRequest, IDBRequest)
nsresult IDBOpenDBRequest::PostHandleEvent(EventChainPostVisitor& aVisitor) {
nsresult rv =
IndexedDatabaseManager::CommonPostHandleEvent(aVisitor, mFactory);
IndexedDatabaseManager::CommonPostHandleEvent(aVisitor, *mFactory);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

View File

@ -13,6 +13,7 @@
#include "mozilla/dom/IDBRequestBinding.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "nsCycleCollectionParticipant.h"
#include "SafeRefPtr.h"
#define PRIVATE_IDBREQUEST_IID \
{ \
@ -181,7 +182,7 @@ class NS_NO_VTABLE IDBRequest::ResultCallback {
class IDBOpenDBRequest final : public IDBRequest {
// Only touched on the owning thread.
RefPtr<IDBFactory> mFactory;
SafeRefPtr<IDBFactory> mFactory;
RefPtr<StrongWorkerRef> mWorkerRef;
@ -189,9 +190,9 @@ class IDBOpenDBRequest final : public IDBRequest {
bool mIncreasedActiveDatabaseCount;
public:
static MOZ_MUST_USE RefPtr<IDBOpenDBRequest> Create(JSContext* aCx,
IDBFactory* aFactory,
nsIGlobalObject* aGlobal);
static MOZ_MUST_USE RefPtr<IDBOpenDBRequest> Create(
JSContext* aCx, SafeRefPtr<IDBFactory> aFactory,
nsIGlobalObject* aGlobal);
bool IsFileHandleDisabled() const { return mFileHandleDisabled; }
@ -204,8 +205,6 @@ class IDBOpenDBRequest final : public IDBRequest {
// EventTarget
virtual nsresult PostHandleEvent(EventChainPostVisitor& aVisitor) override;
IDBFactory* Factory() const { return mFactory; }
IMPL_EVENT_HANDLER(blocked);
IMPL_EVENT_HANDLER(upgradeneeded);
@ -217,7 +216,7 @@ class IDBOpenDBRequest final : public IDBRequest {
JS::Handle<JSObject*> aGivenProto) override;
private:
IDBOpenDBRequest(IDBFactory* aFactory, nsIGlobalObject* aGlobal,
IDBOpenDBRequest(SafeRefPtr<IDBFactory> aFactory, nsIGlobalObject* aGlobal,
bool aFileHandleDisabled);
~IDBOpenDBRequest();

View File

@ -16,6 +16,7 @@
#include "nsIRunnable.h"
#include "nsString.h"
#include "nsTArray.h"
#include "SafeRefPtr.h"
namespace mozilla {

View File

@ -380,9 +380,8 @@ void IndexedDatabaseManager::Destroy() {
// static
nsresult IndexedDatabaseManager::CommonPostHandleEvent(
EventChainPostVisitor& aVisitor, IDBFactory* aFactory) {
EventChainPostVisitor& aVisitor, const IDBFactory& aFactory) {
MOZ_ASSERT(aVisitor.mDOMEvent);
MOZ_ASSERT(aFactory);
if (!gPrefErrorEventToSelfError) {
return NS_OK;
@ -475,8 +474,8 @@ nsresult IndexedDatabaseManager::CommonPostHandleEvent(
// Log the error to the error console.
ScriptErrorHelper::Dump(errorName, init.mFilename, init.mLineno, init.mColno,
nsIScriptError::errorFlag, aFactory->IsChrome(),
aFactory->InnerWindowID());
nsIScriptError::errorFlag, aFactory.IsChrome(),
aFactory.InnerWindowID());
return NS_OK;
}
@ -525,12 +524,13 @@ bool IndexedDatabaseManager::DefineIndexedDB(JSContext* aCx,
return false;
}
RefPtr<IDBFactory> factory;
if (NS_FAILED(
IDBFactory::CreateForMainThreadJS(global, getter_AddRefs(factory)))) {
auto res = IDBFactory::CreateForMainThreadJS(global);
if (res.isErr()) {
return false;
}
auto factory = res.unwrap();
MOZ_ASSERT(factory, "This should never fail for chrome!");
JS::Rooted<JS::Value> indexedDB(aCx);

View File

@ -133,7 +133,7 @@ class IndexedDatabaseManager final {
static const nsCString& GetLocale();
static nsresult CommonPostHandleEvent(EventChainPostVisitor& aVisitor,
IDBFactory* aFactory);
const IDBFactory& aFactory);
static bool ResolveSandboxBinding(JSContext* aCx);

View File

@ -480,14 +480,14 @@ already_AddRefed<IDBFactory> WorkerGlobalScope::GetIndexedDB(
const PrincipalInfo& principalInfo =
mWorkerPrivate->GetEffectiveStoragePrincipalInfo();
nsresult rv = IDBFactory::CreateForWorker(this, principalInfo,
mWorkerPrivate->WindowID(),
getter_AddRefs(indexedDB));
if (NS_WARN_IF(NS_FAILED(rv))) {
aErrorResult = rv;
auto res = IDBFactory::CreateForWorker(this, principalInfo,
mWorkerPrivate->WindowID());
if (NS_WARN_IF(res.isErr())) {
aErrorResult = res.unwrapErr();
return nullptr;
}
indexedDB = res.unwrap();
mIndexedDB = indexedDB;
}