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 f03a80287c
commit cc1500cb67
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_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsIIPCBackgroundChildCreateCallback)
NS_INTERFACE_MAP_END
// 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
{
RefPtr<Promise> mPromise;
@ -275,7 +274,6 @@ CacheStorage::CacheStorage(Namespace aNamespace, nsIGlobalObject* aGlobal,
: mNamespace(aNamespace)
, mGlobal(aGlobal)
, mPrincipalInfo(MakeUnique<PrincipalInfo>(aPrincipalInfo))
, mWorkerHolder(aWorkerHolder)
, mActor(nullptr)
, mStatus(NS_OK)
{
@ -283,19 +281,26 @@ CacheStorage::CacheStorage(Namespace aNamespace, nsIGlobalObject* aGlobal,
// If the PBackground actor is already initialized then we can
// immediately use it
PBackgroundChild* actor = BackgroundChild::GetForCurrentThread();
if (actor) {
ActorCreated(actor);
PBackgroundChild* actor = BackgroundChild::GetOrCreateForCurrentThread();
if (NS_WARN_IF(!actor)) {
mStatus = NS_ERROR_UNEXPECTED;
return;
}
// Otherwise we must begin the PBackground initialization process and
// wait for the async ActorCreated() callback.
MOZ_ASSERT(NS_IsMainThread());
bool ok = BackgroundChild::GetOrCreateForCurrentThread(this);
if (NS_WARN_IF(!ok)) {
ActorFailed();
// 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, aWorkerHolder);
PCacheStorageChild* constructedActor =
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)
@ -336,8 +341,7 @@ CacheStorage::Match(JSContext* aCx, const RequestOrUSVString& aRequest,
entry->mArgs = StorageMatchArgs(CacheRequest(), params, GetOpenMode());
entry->mRequest = request;
mPendingRequests.AppendElement(entry.forget());
MaybeRunPendingRequests();
RunRequest(Move(entry));
return promise.forget();
}
@ -361,8 +365,7 @@ CacheStorage::Has(const nsAString& aKey, ErrorResult& aRv)
entry->mPromise = promise;
entry->mArgs = StorageHasArgs(nsString(aKey));
mPendingRequests.AppendElement(entry.forget());
MaybeRunPendingRequests();
RunRequest(Move(entry));
return promise.forget();
}
@ -386,8 +389,7 @@ CacheStorage::Open(const nsAString& aKey, ErrorResult& aRv)
entry->mPromise = promise;
entry->mArgs = StorageOpenArgs(nsString(aKey));
mPendingRequests.AppendElement(entry.forget());
MaybeRunPendingRequests();
RunRequest(Move(entry));
return promise.forget();
}
@ -411,8 +413,7 @@ CacheStorage::Delete(const nsAString& aKey, ErrorResult& aRv)
entry->mPromise = promise;
entry->mArgs = StorageDeleteArgs(nsString(aKey));
mPendingRequests.AppendElement(entry.forget());
MaybeRunPendingRequests();
RunRequest(Move(entry));
return promise.forget();
}
@ -436,8 +437,7 @@ CacheStorage::Keys(ErrorResult& aRv)
entry->mPromise = promise;
entry->mArgs = StorageKeysArgs();
mPendingRequests.AppendElement(entry.forget());
MaybeRunPendingRequests();
RunRequest(Move(entry));
return promise.forget();
}
@ -498,66 +498,19 @@ CacheStorage::WrapObject(JSContext* aContext, JS::Handle<JSObject*> 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
CacheStorage::DestroyInternal(CacheStorageChild* aActor)
{
NS_ASSERT_OWNINGTHREAD(CacheStorage);
MOZ_DIAGNOSTIC_ASSERT(mActor);
MOZ_DIAGNOSTIC_ASSERT(mActor == aActor);
MOZ_DIAGNOSTIC_ASSERT(!NS_FAILED(mStatus));
mActor->ClearListener();
mActor = nullptr;
mStatus = NS_ERROR_UNEXPECTED;
// Note that we will never get an actor again in case another request is
// made before this object is destructed.
ActorFailed();
}
nsIGlobalObject*
@ -595,26 +548,24 @@ CacheStorage::~CacheStorage()
}
void
CacheStorage::MaybeRunPendingRequests()
CacheStorage::RunRequest(nsAutoPtr<Entry>&& aEntry)
{
if (!mActor) {
return;
}
MOZ_ASSERT(mActor);
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;
nsAutoPtr<Entry> entry(mPendingRequests[i].forget());
AutoChildOpArgs args(this, entry->mArgs, 1);
if (entry->mRequest) {
args.Add(entry->mRequest, IgnoreBody, IgnoreInvalidScheme, rv);
}
args.Add(entry->mRequest, IgnoreBody, IgnoreInvalidScheme, rv);
if (NS_WARN_IF(rv.Failed())) {
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

View File

@ -14,7 +14,6 @@
#include "nsISupportsImpl.h"
#include "nsTArray.h"
#include "nsWrapperCache.h"
#include "nsIIPCBackgroundChildCreateCallback.h"
class nsIGlobalObject;
@ -40,7 +39,7 @@ namespace cache {
class CacheStorageChild;
class CacheWorkerHolder;
class CacheStorage final : public nsIIPCBackgroundChildCreateCallback
class CacheStorage final : public nsISupports
, public nsWrapperCache
, public TypeUtils
{
@ -79,10 +78,6 @@ public:
nsISupports* GetParentObject() const;
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
void DestroyInternal(CacheStorageChild* aActor);
@ -102,7 +97,8 @@ private:
explicit CacheStorage(nsresult aFailureResult);
~CacheStorage();
void MaybeRunPendingRequests();
struct Entry;
void RunRequest(nsAutoPtr<Entry>&& aEntry);
OpenMode
GetOpenMode() const;
@ -110,20 +106,15 @@ private:
const Namespace mNamespace;
nsCOMPtr<nsIGlobalObject> mGlobal;
UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
RefPtr<CacheWorkerHolder> mWorkerHolder;
// weak ref cleared in DestroyInternal
CacheStorageChild* mActor;
struct Entry;
nsTArray<nsAutoPtr<Entry>> mPendingRequests;
nsresult mStatus;
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(CacheStorage,
nsIIPCBackgroundChildCreateCallback)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CacheStorage)
};
} // namespace cache