Bug 1408333 Get rid of nsIIPCBackgroundChildCreateCallback - part 12 - Cache API, r=asuth

This commit is contained in:
Andrea Marchesini
2017-10-24 12:02:40 +02:00
parent 5c96afaee0
commit cb19ddfd01
2 changed files with 39 additions and 97 deletions

View File

@@ -50,11 +50,10 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(mozilla::dom::cache::CacheStorage,
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CacheStorage) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CacheStorage)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsIIPCBackgroundChildCreateCallback)
NS_INTERFACE_MAP_END NS_INTERFACE_MAP_END
// We cannot reference IPC types in a webidl binding implementation header. So // We cannot reference IPC types in a webidl binding implementation header. So
// define this in the .cpp and use heap storage in the mPendingRequests list. // define this in the .cpp.
struct CacheStorage::Entry final struct CacheStorage::Entry final
{ {
RefPtr<Promise> mPromise; RefPtr<Promise> mPromise;
@@ -275,7 +274,6 @@ CacheStorage::CacheStorage(Namespace aNamespace, nsIGlobalObject* aGlobal,
: mNamespace(aNamespace) : mNamespace(aNamespace)
, mGlobal(aGlobal) , mGlobal(aGlobal)
, mPrincipalInfo(MakeUnique<PrincipalInfo>(aPrincipalInfo)) , mPrincipalInfo(MakeUnique<PrincipalInfo>(aPrincipalInfo))
, mWorkerHolder(aWorkerHolder)
, mActor(nullptr) , mActor(nullptr)
, mStatus(NS_OK) , mStatus(NS_OK)
{ {
@@ -283,19 +281,26 @@ CacheStorage::CacheStorage(Namespace aNamespace, nsIGlobalObject* aGlobal,
// If the PBackground actor is already initialized then we can // If the PBackground actor is already initialized then we can
// immediately use it // immediately use it
PBackgroundChild* actor = BackgroundChild::GetForCurrentThread(); PBackgroundChild* actor = BackgroundChild::GetOrCreateForCurrentThread();
if (actor) { if (NS_WARN_IF(!actor)) {
ActorCreated(actor); mStatus = NS_ERROR_UNEXPECTED;
return; return;
} }
// Otherwise we must begin the PBackground initialization process and // WorkerHolder ownership is passed to the CacheStorageChild actor and any
// wait for the async ActorCreated() callback. // actors it may create. The WorkerHolder will keep the worker thread alive
MOZ_ASSERT(NS_IsMainThread()); // until the actors can gracefully shutdown.
bool ok = BackgroundChild::GetOrCreateForCurrentThread(this); CacheStorageChild* newActor = new CacheStorageChild(this, aWorkerHolder);
if (NS_WARN_IF(!ok)) { PCacheStorageChild* constructedActor =
ActorFailed(); actor->SendPCacheStorageConstructor(newActor, mNamespace, *mPrincipalInfo);
if (NS_WARN_IF(!constructedActor)) {
mStatus = NS_ERROR_UNEXPECTED;
return;
} }
MOZ_DIAGNOSTIC_ASSERT(constructedActor == newActor);
mActor = newActor;
} }
CacheStorage::CacheStorage(nsresult aFailureResult) CacheStorage::CacheStorage(nsresult aFailureResult)
@@ -336,8 +341,7 @@ CacheStorage::Match(JSContext* aCx, const RequestOrUSVString& aRequest,
entry->mArgs = StorageMatchArgs(CacheRequest(), params, GetOpenMode()); entry->mArgs = StorageMatchArgs(CacheRequest(), params, GetOpenMode());
entry->mRequest = request; entry->mRequest = request;
mPendingRequests.AppendElement(entry.forget()); RunRequest(Move(entry));
MaybeRunPendingRequests();
return promise.forget(); return promise.forget();
} }
@@ -361,8 +365,7 @@ CacheStorage::Has(const nsAString& aKey, ErrorResult& aRv)
entry->mPromise = promise; entry->mPromise = promise;
entry->mArgs = StorageHasArgs(nsString(aKey)); entry->mArgs = StorageHasArgs(nsString(aKey));
mPendingRequests.AppendElement(entry.forget()); RunRequest(Move(entry));
MaybeRunPendingRequests();
return promise.forget(); return promise.forget();
} }
@@ -386,8 +389,7 @@ CacheStorage::Open(const nsAString& aKey, ErrorResult& aRv)
entry->mPromise = promise; entry->mPromise = promise;
entry->mArgs = StorageOpenArgs(nsString(aKey)); entry->mArgs = StorageOpenArgs(nsString(aKey));
mPendingRequests.AppendElement(entry.forget()); RunRequest(Move(entry));
MaybeRunPendingRequests();
return promise.forget(); return promise.forget();
} }
@@ -411,8 +413,7 @@ CacheStorage::Delete(const nsAString& aKey, ErrorResult& aRv)
entry->mPromise = promise; entry->mPromise = promise;
entry->mArgs = StorageDeleteArgs(nsString(aKey)); entry->mArgs = StorageDeleteArgs(nsString(aKey));
mPendingRequests.AppendElement(entry.forget()); RunRequest(Move(entry));
MaybeRunPendingRequests();
return promise.forget(); return promise.forget();
} }
@@ -436,8 +437,7 @@ CacheStorage::Keys(ErrorResult& aRv)
entry->mPromise = promise; entry->mPromise = promise;
entry->mArgs = StorageKeysArgs(); entry->mArgs = StorageKeysArgs();
mPendingRequests.AppendElement(entry.forget()); RunRequest(Move(entry));
MaybeRunPendingRequests();
return promise.forget(); return promise.forget();
} }
@@ -498,66 +498,19 @@ CacheStorage::WrapObject(JSContext* aContext, JS::Handle<JSObject*> aGivenProto)
return mozilla::dom::CacheStorageBinding::Wrap(aContext, this, aGivenProto); return mozilla::dom::CacheStorageBinding::Wrap(aContext, this, aGivenProto);
} }
void
CacheStorage::ActorCreated(PBackgroundChild* aActor)
{
NS_ASSERT_OWNINGTHREAD(CacheStorage);
MOZ_DIAGNOSTIC_ASSERT(aActor);
if (NS_WARN_IF(mWorkerHolder && mWorkerHolder->Notified())) {
ActorFailed();
return;
}
// WorkerHolder ownership is passed to the CacheStorageChild actor and any
// actors it may create. The WorkerHolder will keep the worker thread alive
// until the actors can gracefully shutdown.
CacheStorageChild* newActor = new CacheStorageChild(this, mWorkerHolder);
PCacheStorageChild* constructedActor =
aActor->SendPCacheStorageConstructor(newActor, mNamespace, *mPrincipalInfo);
if (NS_WARN_IF(!constructedActor)) {
ActorFailed();
return;
}
mWorkerHolder = nullptr;
MOZ_DIAGNOSTIC_ASSERT(constructedActor == newActor);
mActor = newActor;
MaybeRunPendingRequests();
MOZ_DIAGNOSTIC_ASSERT(mPendingRequests.IsEmpty());
}
void
CacheStorage::ActorFailed()
{
NS_ASSERT_OWNINGTHREAD(CacheStorage);
MOZ_DIAGNOSTIC_ASSERT(!NS_FAILED(mStatus));
mStatus = NS_ERROR_UNEXPECTED;
mWorkerHolder = nullptr;
for (uint32_t i = 0; i < mPendingRequests.Length(); ++i) {
nsAutoPtr<Entry> entry(mPendingRequests[i].forget());
entry->mPromise->MaybeReject(NS_ERROR_UNEXPECTED);
}
mPendingRequests.Clear();
}
void void
CacheStorage::DestroyInternal(CacheStorageChild* aActor) CacheStorage::DestroyInternal(CacheStorageChild* aActor)
{ {
NS_ASSERT_OWNINGTHREAD(CacheStorage); NS_ASSERT_OWNINGTHREAD(CacheStorage);
MOZ_DIAGNOSTIC_ASSERT(mActor); MOZ_DIAGNOSTIC_ASSERT(mActor);
MOZ_DIAGNOSTIC_ASSERT(mActor == aActor); MOZ_DIAGNOSTIC_ASSERT(mActor == aActor);
MOZ_DIAGNOSTIC_ASSERT(!NS_FAILED(mStatus));
mActor->ClearListener(); mActor->ClearListener();
mActor = nullptr; mActor = nullptr;
mStatus = NS_ERROR_UNEXPECTED;
// Note that we will never get an actor again in case another request is // Note that we will never get an actor again in case another request is
// made before this object is destructed. // made before this object is destructed.
ActorFailed();
} }
nsIGlobalObject* nsIGlobalObject*
@@ -595,26 +548,24 @@ CacheStorage::~CacheStorage()
} }
void void
CacheStorage::MaybeRunPendingRequests() CacheStorage::RunRequest(nsAutoPtr<Entry>&& aEntry)
{ {
if (!mActor) { MOZ_ASSERT(mActor);
return;
}
for (uint32_t i = 0; i < mPendingRequests.Length(); ++i) { nsAutoPtr<Entry> entry(Move(aEntry));
AutoChildOpArgs args(this, entry->mArgs, 1);
if (entry->mRequest) {
ErrorResult rv; ErrorResult rv;
nsAutoPtr<Entry> entry(mPendingRequests[i].forget()); args.Add(entry->mRequest, IgnoreBody, IgnoreInvalidScheme, rv);
AutoChildOpArgs args(this, entry->mArgs, 1);
if (entry->mRequest) {
args.Add(entry->mRequest, IgnoreBody, IgnoreInvalidScheme, rv);
}
if (NS_WARN_IF(rv.Failed())) { if (NS_WARN_IF(rv.Failed())) {
entry->mPromise->MaybeReject(rv); entry->mPromise->MaybeReject(rv);
continue; return;
} }
mActor->ExecuteOp(mGlobal, entry->mPromise, this, args.SendAsOpArgs());
} }
mPendingRequests.Clear();
mActor->ExecuteOp(mGlobal, entry->mPromise, this, args.SendAsOpArgs());
} }
OpenMode OpenMode

View File

@@ -14,7 +14,6 @@
#include "nsISupportsImpl.h" #include "nsISupportsImpl.h"
#include "nsTArray.h" #include "nsTArray.h"
#include "nsWrapperCache.h" #include "nsWrapperCache.h"
#include "nsIIPCBackgroundChildCreateCallback.h"
class nsIGlobalObject; class nsIGlobalObject;
@@ -40,7 +39,7 @@ namespace cache {
class CacheStorageChild; class CacheStorageChild;
class CacheWorkerHolder; class CacheWorkerHolder;
class CacheStorage final : public nsIIPCBackgroundChildCreateCallback class CacheStorage final : public nsISupports
, public nsWrapperCache , public nsWrapperCache
, public TypeUtils , public TypeUtils
{ {
@@ -79,10 +78,6 @@ public:
nsISupports* GetParentObject() const; nsISupports* GetParentObject() const;
virtual JSObject* WrapObject(JSContext* aContext, JS::Handle<JSObject*> aGivenProto) override; virtual JSObject* WrapObject(JSContext* aContext, JS::Handle<JSObject*> aGivenProto) override;
// nsIIPCbackgroundChildCreateCallback methods
virtual void ActorCreated(PBackgroundChild* aActor) override;
virtual void ActorFailed() override;
// Called when CacheStorageChild actor is being destroyed // Called when CacheStorageChild actor is being destroyed
void DestroyInternal(CacheStorageChild* aActor); void DestroyInternal(CacheStorageChild* aActor);
@@ -102,7 +97,8 @@ private:
explicit CacheStorage(nsresult aFailureResult); explicit CacheStorage(nsresult aFailureResult);
~CacheStorage(); ~CacheStorage();
void MaybeRunPendingRequests(); struct Entry;
void RunRequest(nsAutoPtr<Entry>&& aEntry);
OpenMode OpenMode
GetOpenMode() const; GetOpenMode() const;
@@ -110,20 +106,15 @@ private:
const Namespace mNamespace; const Namespace mNamespace;
nsCOMPtr<nsIGlobalObject> mGlobal; nsCOMPtr<nsIGlobalObject> mGlobal;
UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo; UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
RefPtr<CacheWorkerHolder> mWorkerHolder;
// weak ref cleared in DestroyInternal // weak ref cleared in DestroyInternal
CacheStorageChild* mActor; CacheStorageChild* mActor;
struct Entry;
nsTArray<nsAutoPtr<Entry>> mPendingRequests;
nsresult mStatus; nsresult mStatus;
public: public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(CacheStorage, NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CacheStorage)
nsIIPCBackgroundChildCreateCallback)
}; };
} // namespace cache } // namespace cache