mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out changeset 19f871364039 (bug 1110485) for causing bc1 winxp memory leaks on a CLOSED TREE
This commit is contained in:
parent
2b2cc53c16
commit
221df621f6
626
dom/cache/AutoUtils.cpp
vendored
626
dom/cache/AutoUtils.cpp
vendored
@ -7,7 +7,6 @@
|
||||
#include "mozilla/dom/cache/AutoUtils.h"
|
||||
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/dom/cache/CacheParent.h"
|
||||
#include "mozilla/dom/cache/CachePushStreamChild.h"
|
||||
#include "mozilla/dom/cache/CacheStreamControlParent.h"
|
||||
#include "mozilla/dom/cache/ReadStream.h"
|
||||
@ -137,381 +136,171 @@ namespace cache {
|
||||
|
||||
using mozilla::ipc::PBackgroundParent;
|
||||
|
||||
// --------------------------------------------
|
||||
|
||||
AutoChildOpArgs::AutoChildOpArgs(TypeUtils* aTypeUtils,
|
||||
const CacheOpArgs& aOpArgs)
|
||||
AutoChildBase::AutoChildBase(TypeUtils* aTypeUtils)
|
||||
: mTypeUtils(aTypeUtils)
|
||||
, mOpArgs(aOpArgs)
|
||||
, mSent(false)
|
||||
{
|
||||
MOZ_ASSERT(mTypeUtils);
|
||||
}
|
||||
|
||||
AutoChildOpArgs::~AutoChildOpArgs()
|
||||
AutoChildBase::~AutoChildBase()
|
||||
{
|
||||
CleanupAction action = mSent ? Forget : Delete;
|
||||
|
||||
switch(mOpArgs.type()) {
|
||||
case CacheOpArgs::TCacheMatchArgs:
|
||||
{
|
||||
CacheMatchArgs& args = mOpArgs.get_CacheMatchArgs();
|
||||
CleanupChild(args.request().body(), action);
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TCacheMatchAllArgs:
|
||||
{
|
||||
CacheMatchAllArgs& args = mOpArgs.get_CacheMatchAllArgs();
|
||||
if (args.requestOrVoid().type() == PCacheRequestOrVoid::Tvoid_t) {
|
||||
break;
|
||||
}
|
||||
CleanupChild(args.requestOrVoid().get_PCacheRequest().body(), action);
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TCacheAddAllArgs:
|
||||
{
|
||||
CacheAddAllArgs& args = mOpArgs.get_CacheAddAllArgs();
|
||||
auto& list = args.requestList();
|
||||
for (uint32_t i = 0; i < list.Length(); ++i) {
|
||||
CleanupChild(list[i].body(), action);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TCachePutAllArgs:
|
||||
{
|
||||
CachePutAllArgs& args = mOpArgs.get_CachePutAllArgs();
|
||||
auto& list = args.requestResponseList();
|
||||
for (uint32_t i = 0; i < list.Length(); ++i) {
|
||||
CleanupChild(list[i].request().body(), action);
|
||||
CleanupChild(list[i].response().body(), action);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TCacheDeleteArgs:
|
||||
{
|
||||
CacheDeleteArgs& args = mOpArgs.get_CacheDeleteArgs();
|
||||
CleanupChild(args.request().body(), action);
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TCacheKeysArgs:
|
||||
{
|
||||
CacheKeysArgs& args = mOpArgs.get_CacheKeysArgs();
|
||||
if (args.requestOrVoid().type() == PCacheRequestOrVoid::Tvoid_t) {
|
||||
break;
|
||||
}
|
||||
CleanupChild(args.requestOrVoid().get_PCacheRequest().body(), action);
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TStorageMatchArgs:
|
||||
{
|
||||
StorageMatchArgs& args = mOpArgs.get_StorageMatchArgs();
|
||||
CleanupChild(args.request().body(), action);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// Other types do not need cleanup
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AutoChildOpArgs::Add(InternalRequest* aRequest, BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction, SchemeAction aSchemeAction,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
|
||||
switch(mOpArgs.type()) {
|
||||
case CacheOpArgs::TCacheMatchArgs:
|
||||
{
|
||||
CacheMatchArgs& args = mOpArgs.get_CacheMatchArgs();
|
||||
mTypeUtils->ToPCacheRequest(args.request(), aRequest, aBodyAction,
|
||||
aReferrerAction, aSchemeAction, aRv);
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TCacheMatchAllArgs:
|
||||
{
|
||||
CacheMatchAllArgs& args = mOpArgs.get_CacheMatchAllArgs();
|
||||
MOZ_ASSERT(args.requestOrVoid().type() == PCacheRequestOrVoid::Tvoid_t);
|
||||
args.requestOrVoid() = PCacheRequest();
|
||||
mTypeUtils->ToPCacheRequest(args.requestOrVoid().get_PCacheRequest(),
|
||||
aRequest, aBodyAction, aReferrerAction,
|
||||
aSchemeAction, aRv);
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TCacheAddAllArgs:
|
||||
{
|
||||
CacheAddAllArgs& args = mOpArgs.get_CacheAddAllArgs();
|
||||
|
||||
// The FileDescriptorSetChild asserts in its destructor that all fds have
|
||||
// been removed. The copy constructor, however, simply duplicates the
|
||||
// fds without removing any. This means each temporary and copy must be
|
||||
// explicitly cleaned up.
|
||||
//
|
||||
// Avoid a lot of this hassle by making sure we only create one here. On
|
||||
// error we remove it.
|
||||
PCacheRequest& request = *args.requestList().AppendElement();
|
||||
|
||||
mTypeUtils->ToPCacheRequest(request, aRequest, aBodyAction,
|
||||
aReferrerAction, aSchemeAction, aRv);
|
||||
if (aRv.Failed()) {
|
||||
args.requestList().RemoveElementAt(args.requestList().Length() - 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TCacheDeleteArgs:
|
||||
{
|
||||
CacheDeleteArgs& args = mOpArgs.get_CacheDeleteArgs();
|
||||
mTypeUtils->ToPCacheRequest(args.request(), aRequest, aBodyAction,
|
||||
aReferrerAction, aSchemeAction, aRv);
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TCacheKeysArgs:
|
||||
{
|
||||
CacheKeysArgs& args = mOpArgs.get_CacheKeysArgs();
|
||||
MOZ_ASSERT(args.requestOrVoid().type() == PCacheRequestOrVoid::Tvoid_t);
|
||||
args.requestOrVoid() = PCacheRequest();
|
||||
mTypeUtils->ToPCacheRequest(args.requestOrVoid().get_PCacheRequest(),
|
||||
aRequest, aBodyAction, aReferrerAction,
|
||||
aSchemeAction, aRv);
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TStorageMatchArgs:
|
||||
{
|
||||
StorageMatchArgs& args = mOpArgs.get_StorageMatchArgs();
|
||||
mTypeUtils->ToPCacheRequest(args.request(), aRequest, aBodyAction,
|
||||
aReferrerAction, aSchemeAction, aRv);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Cache args type cannot send a Request!");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AutoChildOpArgs::Add(InternalRequest* aRequest, BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction, SchemeAction aSchemeAction,
|
||||
Response& aResponse, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
|
||||
switch(mOpArgs.type()) {
|
||||
case CacheOpArgs::TCachePutAllArgs:
|
||||
{
|
||||
CachePutAllArgs& args = mOpArgs.get_CachePutAllArgs();
|
||||
|
||||
// The FileDescriptorSetChild asserts in its destructor that all fds have
|
||||
// been removed. The copy constructor, however, simply duplicates the
|
||||
// fds without removing any. This means each temporary and copy must be
|
||||
// explicitly cleaned up.
|
||||
//
|
||||
// Avoid a lot of this hassle by making sure we only create one here. On
|
||||
// error we remove it.
|
||||
CacheRequestResponse& pair = *args.requestResponseList().AppendElement();
|
||||
pair.request().body() = void_t();
|
||||
pair.response().body() = void_t();
|
||||
|
||||
mTypeUtils->ToPCacheRequest(pair.request(), aRequest, aBodyAction,
|
||||
aReferrerAction, aSchemeAction, aRv);
|
||||
if (!aRv.Failed()) {
|
||||
mTypeUtils->ToPCacheResponse(pair.response(), aResponse, aRv);
|
||||
}
|
||||
|
||||
if (aRv.Failed()) {
|
||||
CleanupChild(pair.request().body(), Delete);
|
||||
args.requestResponseList().RemoveElementAt(
|
||||
args.requestResponseList().Length() - 1);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Cache args type cannot send a Request/Response pair!");
|
||||
}
|
||||
}
|
||||
|
||||
const CacheOpArgs&
|
||||
AutoChildOpArgs::SendAsOpArgs()
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
mSent = true;
|
||||
return mOpArgs;
|
||||
}
|
||||
|
||||
// --------------------------------------------
|
||||
|
||||
AutoParentOpResult::AutoParentOpResult(mozilla::ipc::PBackgroundParent* aManager,
|
||||
const CacheOpResult& aOpResult)
|
||||
AutoChildRequest::AutoChildRequest(TypeUtils* aTypeUtils)
|
||||
: AutoChildBase(aTypeUtils)
|
||||
{
|
||||
mRequestOrVoid = void_t();
|
||||
}
|
||||
|
||||
AutoChildRequest::~AutoChildRequest()
|
||||
{
|
||||
if (mRequestOrVoid.type() != PCacheRequestOrVoid::TPCacheRequest) {
|
||||
return;
|
||||
}
|
||||
|
||||
CleanupAction action = mSent ? Forget : Delete;
|
||||
CleanupChild(mRequestOrVoid.get_PCacheRequest().body(), action);
|
||||
}
|
||||
|
||||
void
|
||||
AutoChildRequest::Add(InternalRequest* aRequest, BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction, SchemeAction aSchemeAction,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
MOZ_ASSERT(mRequestOrVoid.type() == PCacheRequestOrVoid::Tvoid_t);
|
||||
mRequestOrVoid = PCacheRequest();
|
||||
mTypeUtils->ToPCacheRequest(mRequestOrVoid.get_PCacheRequest(), aRequest,
|
||||
aBodyAction, aReferrerAction, aSchemeAction, aRv);
|
||||
}
|
||||
|
||||
const PCacheRequest&
|
||||
AutoChildRequest::SendAsRequest()
|
||||
{
|
||||
MOZ_ASSERT(mRequestOrVoid.type() == PCacheRequestOrVoid::TPCacheRequest);
|
||||
return mRequestOrVoid.get_PCacheRequest();
|
||||
}
|
||||
|
||||
const PCacheRequestOrVoid&
|
||||
AutoChildRequest::SendAsRequestOrVoid()
|
||||
{
|
||||
return mRequestOrVoid;
|
||||
}
|
||||
|
||||
// --------------------------------------------
|
||||
|
||||
AutoChildRequestList::AutoChildRequestList(TypeUtils* aTypeUtils,
|
||||
uint32_t aCapacity)
|
||||
: AutoChildBase(aTypeUtils)
|
||||
{
|
||||
mRequestList.SetCapacity(aCapacity);
|
||||
}
|
||||
|
||||
AutoChildRequestList::~AutoChildRequestList()
|
||||
{
|
||||
CleanupAction action = mSent ? Forget : Delete;
|
||||
for (uint32_t i = 0; i < mRequestList.Length(); ++i) {
|
||||
CleanupChild(mRequestList[i].body(), action);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AutoChildRequestList::Add(InternalRequest* aRequest, BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction,
|
||||
SchemeAction aSchemeAction, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
|
||||
// The FileDescriptorSetChild asserts in its destructor that all fds have
|
||||
// been removed. The copy constructor, however, simply duplicates the
|
||||
// fds without removing any. This means each temporary and copy must be
|
||||
// explicitly cleaned up.
|
||||
//
|
||||
// Avoid a lot of this hassle by making sure we only create one here. On
|
||||
// error we remove it.
|
||||
|
||||
PCacheRequest* request = mRequestList.AppendElement();
|
||||
mTypeUtils->ToPCacheRequest(*request, aRequest, aBodyAction, aReferrerAction,
|
||||
aSchemeAction, aRv);
|
||||
if (aRv.Failed()) {
|
||||
mRequestList.RemoveElementAt(mRequestList.Length() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
const nsTArray<PCacheRequest>&
|
||||
AutoChildRequestList::SendAsRequestList()
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
mSent = true;
|
||||
return mRequestList;
|
||||
}
|
||||
|
||||
// --------------------------------------------
|
||||
|
||||
AutoChildRequestResponse::AutoChildRequestResponse(TypeUtils* aTypeUtils)
|
||||
: AutoChildBase(aTypeUtils)
|
||||
{
|
||||
// Default IPC-generated constructor does not initialize these correctly
|
||||
// and we check them later when cleaning up.
|
||||
mRequestResponse.request().body() = void_t();
|
||||
mRequestResponse.response().body() = void_t();
|
||||
}
|
||||
|
||||
AutoChildRequestResponse::~AutoChildRequestResponse()
|
||||
{
|
||||
CleanupAction action = mSent ? Forget : Delete;
|
||||
CleanupChild(mRequestResponse.request().body(), action);
|
||||
CleanupChild(mRequestResponse.response().body(), action);
|
||||
}
|
||||
|
||||
void
|
||||
AutoChildRequestResponse::Add(InternalRequest* aRequest, BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction,
|
||||
SchemeAction aSchemeAction, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
mTypeUtils->ToPCacheRequest(mRequestResponse.request(), aRequest, aBodyAction,
|
||||
aReferrerAction, aSchemeAction, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
AutoChildRequestResponse::Add(Response& aResponse, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
mTypeUtils->ToPCacheResponse(mRequestResponse.response(), aResponse, aRv);
|
||||
}
|
||||
|
||||
const CacheRequestResponse&
|
||||
AutoChildRequestResponse::SendAsRequestResponse()
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
mSent = true;
|
||||
return mRequestResponse;
|
||||
}
|
||||
|
||||
// --------------------------------------------
|
||||
|
||||
AutoParentBase::AutoParentBase(PBackgroundParent* aManager)
|
||||
: mManager(aManager)
|
||||
, mOpResult(aOpResult)
|
||||
, mStreamControl(nullptr)
|
||||
, mSent(false)
|
||||
{
|
||||
MOZ_ASSERT(mManager);
|
||||
}
|
||||
|
||||
AutoParentOpResult::~AutoParentOpResult()
|
||||
AutoParentBase::~AutoParentBase()
|
||||
{
|
||||
CleanupAction action = mSent ? Forget : Delete;
|
||||
|
||||
switch (mOpResult.type()) {
|
||||
case CacheOpResult::TCacheMatchResult:
|
||||
{
|
||||
CacheMatchResult& result = mOpResult.get_CacheMatchResult();
|
||||
if (result.responseOrVoid().type() == PCacheResponseOrVoid::Tvoid_t) {
|
||||
break;
|
||||
}
|
||||
CleanupParentFds(result.responseOrVoid().get_PCacheResponse().body(),
|
||||
action);
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TCacheMatchAllResult:
|
||||
{
|
||||
CacheMatchAllResult& result = mOpResult.get_CacheMatchAllResult();
|
||||
for (uint32_t i = 0; i < result.responseList().Length(); ++i) {
|
||||
CleanupParentFds(result.responseList()[i].body(), action);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TCacheKeysResult:
|
||||
{
|
||||
CacheKeysResult& result = mOpResult.get_CacheKeysResult();
|
||||
for (uint32_t i = 0; i < result.requestList().Length(); ++i) {
|
||||
CleanupParentFds(result.requestList()[i].body(), action);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TStorageMatchResult:
|
||||
{
|
||||
StorageMatchResult& result = mOpResult.get_StorageMatchResult();
|
||||
if (result.responseOrVoid().type() == PCacheResponseOrVoid::Tvoid_t) {
|
||||
break;
|
||||
}
|
||||
CleanupParentFds(result.responseOrVoid().get_PCacheResponse().body(),
|
||||
action);
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TStorageOpenResult:
|
||||
{
|
||||
StorageOpenResult& result = mOpResult.get_StorageOpenResult();
|
||||
if (action == Forget || result.actorParent() == nullptr) {
|
||||
break;
|
||||
}
|
||||
unused << PCacheParent::Send__delete__(result.actorParent());
|
||||
}
|
||||
default:
|
||||
// other types do not need clean up
|
||||
break;
|
||||
}
|
||||
|
||||
if (action == Delete && mStreamControl) {
|
||||
if (!mSent && mStreamControl) {
|
||||
unused << PCacheStreamControlParent::Send__delete__(mStreamControl);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AutoParentOpResult::Add(CacheId aOpenedCacheId, Manager* aManager)
|
||||
{
|
||||
MOZ_ASSERT(mOpResult.type() == CacheOpResult::TStorageOpenResult);
|
||||
MOZ_ASSERT(mOpResult.get_StorageOpenResult().actorParent() == nullptr);
|
||||
mOpResult.get_StorageOpenResult().actorParent() =
|
||||
mManager->SendPCacheConstructor(new CacheParent(aManager, aOpenedCacheId));
|
||||
}
|
||||
|
||||
void
|
||||
AutoParentOpResult::Add(const SavedResponse& aSavedResponse,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
|
||||
switch (mOpResult.type()) {
|
||||
case CacheOpResult::TCacheMatchResult:
|
||||
{
|
||||
CacheMatchResult& result = mOpResult.get_CacheMatchResult();
|
||||
MOZ_ASSERT(result.responseOrVoid().type() == PCacheResponseOrVoid::Tvoid_t);
|
||||
result.responseOrVoid() = aSavedResponse.mValue;
|
||||
SerializeResponseBody(aSavedResponse, aStreamList,
|
||||
&result.responseOrVoid().get_PCacheResponse());
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TCacheMatchAllResult:
|
||||
{
|
||||
CacheMatchAllResult& result = mOpResult.get_CacheMatchAllResult();
|
||||
result.responseList().AppendElement(aSavedResponse.mValue);
|
||||
SerializeResponseBody(aSavedResponse, aStreamList,
|
||||
&result.responseList().LastElement());
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TStorageMatchResult:
|
||||
{
|
||||
StorageMatchResult& result = mOpResult.get_StorageMatchResult();
|
||||
MOZ_ASSERT(result.responseOrVoid().type() == PCacheResponseOrVoid::Tvoid_t);
|
||||
result.responseOrVoid() = aSavedResponse.mValue;
|
||||
SerializeResponseBody(aSavedResponse, aStreamList,
|
||||
&result.responseOrVoid().get_PCacheResponse());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Cache result type cannot handle returning a Response!");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AutoParentOpResult::Add(const SavedRequest& aSavedRequest,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
|
||||
switch (mOpResult.type()) {
|
||||
case CacheOpResult::TCacheKeysResult:
|
||||
{
|
||||
CacheKeysResult& result = mOpResult.get_CacheKeysResult();
|
||||
result.requestList().AppendElement(aSavedRequest.mValue);
|
||||
PCacheRequest& request = result.requestList().LastElement();
|
||||
|
||||
if (!aSavedRequest.mHasBodyId) {
|
||||
request.body() = void_t();
|
||||
break;
|
||||
}
|
||||
|
||||
request.body() = PCacheReadStream();
|
||||
SerializeReadStream(aSavedRequest.mBodyId, aStreamList,
|
||||
&request.body().get_PCacheReadStream());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Cache result type cannot handle returning a Request!");
|
||||
}
|
||||
}
|
||||
|
||||
const CacheOpResult&
|
||||
AutoParentOpResult::SendAsOpResult()
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
mSent = true;
|
||||
return mOpResult;
|
||||
}
|
||||
|
||||
void
|
||||
AutoParentOpResult::SerializeResponseBody(const SavedResponse& aSavedResponse,
|
||||
StreamList* aStreamList,
|
||||
PCacheResponse* aResponseOut)
|
||||
{
|
||||
MOZ_ASSERT(aResponseOut);
|
||||
|
||||
if (!aSavedResponse.mHasBodyId) {
|
||||
aResponseOut->body() = void_t();
|
||||
return;
|
||||
}
|
||||
|
||||
aResponseOut->body() = PCacheReadStream();
|
||||
SerializeReadStream(aSavedResponse.mBodyId, aStreamList,
|
||||
&aResponseOut->body().get_PCacheReadStream());
|
||||
}
|
||||
|
||||
void
|
||||
AutoParentOpResult::SerializeReadStream(const nsID& aId, StreamList* aStreamList,
|
||||
PCacheReadStream* aReadStreamOut)
|
||||
AutoParentBase::SerializeReadStream(const nsID& aId, StreamList* aStreamList,
|
||||
PCacheReadStream* aReadStreamOut)
|
||||
{
|
||||
MOZ_ASSERT(aStreamList);
|
||||
MOZ_ASSERT(aReadStreamOut);
|
||||
@ -539,6 +328,139 @@ AutoParentOpResult::SerializeReadStream(const nsID& aId, StreamList* aStreamList
|
||||
readStream->Serialize(aReadStreamOut);
|
||||
}
|
||||
|
||||
// --------------------------------------------
|
||||
|
||||
AutoParentRequestList::AutoParentRequestList(PBackgroundParent* aManager,
|
||||
uint32_t aCapacity)
|
||||
: AutoParentBase(aManager)
|
||||
{
|
||||
mRequestList.SetCapacity(aCapacity);
|
||||
}
|
||||
|
||||
AutoParentRequestList::~AutoParentRequestList()
|
||||
{
|
||||
CleanupAction action = mSent ? Forget : Delete;
|
||||
for (uint32_t i = 0; i < mRequestList.Length(); ++i) {
|
||||
CleanupParentFds(mRequestList[i].body(), action);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AutoParentRequestList::Add(const SavedRequest& aSavedRequest,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
|
||||
mRequestList.AppendElement(aSavedRequest.mValue);
|
||||
PCacheRequest& request = mRequestList.LastElement();
|
||||
|
||||
if (!aSavedRequest.mHasBodyId) {
|
||||
request.body() = void_t();
|
||||
return;
|
||||
}
|
||||
|
||||
request.body() = PCacheReadStream();
|
||||
SerializeReadStream(aSavedRequest.mBodyId, aStreamList,
|
||||
&request.body().get_PCacheReadStream());
|
||||
}
|
||||
|
||||
const nsTArray<PCacheRequest>&
|
||||
AutoParentRequestList::SendAsRequestList()
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
mSent = true;
|
||||
return mRequestList;
|
||||
}
|
||||
|
||||
// --------------------------------------------
|
||||
|
||||
AutoParentResponseList::AutoParentResponseList(PBackgroundParent* aManager,
|
||||
uint32_t aCapacity)
|
||||
: AutoParentBase(aManager)
|
||||
{
|
||||
mResponseList.SetCapacity(aCapacity);
|
||||
}
|
||||
|
||||
AutoParentResponseList::~AutoParentResponseList()
|
||||
{
|
||||
CleanupAction action = mSent ? Forget : Delete;
|
||||
for (uint32_t i = 0; i < mResponseList.Length(); ++i) {
|
||||
CleanupParentFds(mResponseList[i].body(), action);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AutoParentResponseList::Add(const SavedResponse& aSavedResponse,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
|
||||
mResponseList.AppendElement(aSavedResponse.mValue);
|
||||
PCacheResponse& response = mResponseList.LastElement();
|
||||
|
||||
if (!aSavedResponse.mHasBodyId) {
|
||||
response.body() = void_t();
|
||||
return;
|
||||
}
|
||||
|
||||
response.body() = PCacheReadStream();
|
||||
SerializeReadStream(aSavedResponse.mBodyId, aStreamList,
|
||||
&response.body().get_PCacheReadStream());
|
||||
}
|
||||
|
||||
const nsTArray<PCacheResponse>&
|
||||
AutoParentResponseList::SendAsResponseList()
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
mSent = true;
|
||||
return mResponseList;
|
||||
}
|
||||
|
||||
// --------------------------------------------
|
||||
|
||||
AutoParentResponseOrVoid::AutoParentResponseOrVoid(ipc::PBackgroundParent* aManager)
|
||||
: AutoParentBase(aManager)
|
||||
{
|
||||
mResponseOrVoid = void_t();
|
||||
}
|
||||
|
||||
AutoParentResponseOrVoid::~AutoParentResponseOrVoid()
|
||||
{
|
||||
if (mResponseOrVoid.type() != PCacheResponseOrVoid::TPCacheResponse) {
|
||||
return;
|
||||
}
|
||||
|
||||
CleanupAction action = mSent ? Forget : Delete;
|
||||
CleanupParentFds(mResponseOrVoid.get_PCacheResponse().body(), action);
|
||||
}
|
||||
|
||||
void
|
||||
AutoParentResponseOrVoid::Add(const SavedResponse& aSavedResponse,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
|
||||
mResponseOrVoid = aSavedResponse.mValue;
|
||||
PCacheResponse& response = mResponseOrVoid.get_PCacheResponse();
|
||||
|
||||
if (!aSavedResponse.mHasBodyId) {
|
||||
response.body() = void_t();
|
||||
return;
|
||||
}
|
||||
|
||||
response.body() = PCacheReadStream();
|
||||
SerializeReadStream(aSavedResponse.mBodyId, aStreamList,
|
||||
&response.body().get_PCacheReadStream());
|
||||
}
|
||||
|
||||
const PCacheResponseOrVoid&
|
||||
AutoParentResponseOrVoid::SendAsResponseOrVoid()
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
mSent = true;
|
||||
return mResponseOrVoid;
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
121
dom/cache/AutoUtils.h
vendored
121
dom/cache/AutoUtils.h
vendored
@ -9,7 +9,6 @@
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/cache/PCacheTypes.h"
|
||||
#include "mozilla/dom/cache/Types.h"
|
||||
#include "mozilla/dom/cache/TypeUtils.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
@ -30,7 +29,6 @@ class InternalRequest;
|
||||
namespace cache {
|
||||
|
||||
class CacheStreamControlParent;
|
||||
class Manager;
|
||||
struct SavedRequest;
|
||||
struct SavedResponse;
|
||||
class StreamList;
|
||||
@ -43,58 +41,131 @@ class StreamList;
|
||||
// Note, these should only be used when *sending* streams across IPC. The
|
||||
// deserialization case is handled by creating a ReadStream object.
|
||||
|
||||
class MOZ_STACK_CLASS AutoChildOpArgs final
|
||||
class MOZ_STACK_CLASS AutoChildBase
|
||||
{
|
||||
public:
|
||||
protected:
|
||||
typedef TypeUtils::BodyAction BodyAction;
|
||||
typedef TypeUtils::ReferrerAction ReferrerAction;
|
||||
typedef TypeUtils::SchemeAction SchemeAction;
|
||||
|
||||
AutoChildOpArgs(TypeUtils* aTypeUtils, const CacheOpArgs& aOpArgs);
|
||||
~AutoChildOpArgs();
|
||||
AutoChildBase(TypeUtils* aTypeUtils);
|
||||
virtual ~AutoChildBase() = 0;
|
||||
|
||||
TypeUtils* mTypeUtils;
|
||||
bool mSent;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoChildRequest final : public AutoChildBase
|
||||
{
|
||||
public:
|
||||
explicit AutoChildRequest(TypeUtils* aTypeUtils);
|
||||
~AutoChildRequest();
|
||||
|
||||
void Add(InternalRequest* aRequest, BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction, SchemeAction aSchemeAction,
|
||||
ErrorResult& aRv);
|
||||
void Add(InternalRequest* aRequest, BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction, SchemeAction aSchemeAction,
|
||||
Response& aResponse, ErrorResult& aRv);
|
||||
|
||||
const CacheOpArgs& SendAsOpArgs();
|
||||
const PCacheRequest& SendAsRequest();
|
||||
const PCacheRequestOrVoid& SendAsRequestOrVoid();
|
||||
|
||||
private:
|
||||
TypeUtils* mTypeUtils;
|
||||
CacheOpArgs mOpArgs;
|
||||
bool mSent;
|
||||
PCacheRequestOrVoid mRequestOrVoid;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoParentOpResult final
|
||||
class MOZ_STACK_CLASS AutoChildRequestList final : public AutoChildBase
|
||||
{
|
||||
public:
|
||||
AutoParentOpResult(mozilla::ipc::PBackgroundParent* aManager,
|
||||
const CacheOpResult& aOpResult);
|
||||
~AutoParentOpResult();
|
||||
AutoChildRequestList(TypeUtils* aTypeUtils, uint32_t aCapacity);
|
||||
~AutoChildRequestList();
|
||||
|
||||
void Add(CacheId aOpenedCacheId, Manager* aManager);
|
||||
void Add(const SavedResponse& aSavedResponse, StreamList* aStreamList);
|
||||
void Add(const SavedRequest& aSavedRequest, StreamList* aStreamList);
|
||||
void Add(InternalRequest* aRequest, BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction, SchemeAction aSchemeAction,
|
||||
ErrorResult& aRv);
|
||||
|
||||
const CacheOpResult& SendAsOpResult();
|
||||
const nsTArray<PCacheRequest>& SendAsRequestList();
|
||||
|
||||
private:
|
||||
void SerializeResponseBody(const SavedResponse& aSavedResponse,
|
||||
StreamList* aStreamList,
|
||||
PCacheResponse* aResponseOut);
|
||||
// Allocates ~5k inline in the stack-only class
|
||||
nsAutoTArray<PCacheRequest, 32> mRequestList;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoChildRequestResponse final : public AutoChildBase
|
||||
{
|
||||
public:
|
||||
explicit AutoChildRequestResponse(TypeUtils* aTypeUtils);
|
||||
~AutoChildRequestResponse();
|
||||
|
||||
void Add(InternalRequest* aRequest, BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction, SchemeAction aSchemeAction,
|
||||
ErrorResult& aRv);
|
||||
void Add(Response& aResponse, ErrorResult& aRv);
|
||||
|
||||
const CacheRequestResponse& SendAsRequestResponse();
|
||||
|
||||
private:
|
||||
CacheRequestResponse mRequestResponse;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoParentBase
|
||||
{
|
||||
protected:
|
||||
explicit AutoParentBase(mozilla::ipc::PBackgroundParent* aManager);
|
||||
virtual ~AutoParentBase() = 0;
|
||||
|
||||
void SerializeReadStream(const nsID& aId, StreamList* aStreamList,
|
||||
PCacheReadStream* aReadStreamOut);
|
||||
|
||||
mozilla::ipc::PBackgroundParent* mManager;
|
||||
CacheOpResult mOpResult;
|
||||
CacheStreamControlParent* mStreamControl;
|
||||
bool mSent;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoParentRequestList final : public AutoParentBase
|
||||
{
|
||||
public:
|
||||
AutoParentRequestList(mozilla::ipc::PBackgroundParent* aManager,
|
||||
uint32_t aCapacity);
|
||||
~AutoParentRequestList();
|
||||
|
||||
void Add(const SavedRequest& aSavedRequest, StreamList* aStreamList);
|
||||
|
||||
const nsTArray<PCacheRequest>& SendAsRequestList();
|
||||
|
||||
private:
|
||||
// Allocates ~5k inline in the stack-only class
|
||||
nsAutoTArray<PCacheRequest, 32> mRequestList;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoParentResponseList final : public AutoParentBase
|
||||
{
|
||||
public:
|
||||
AutoParentResponseList(mozilla::ipc::PBackgroundParent* aManager,
|
||||
uint32_t aCapacity);
|
||||
~AutoParentResponseList();
|
||||
|
||||
void Add(const SavedResponse& aSavedResponse, StreamList* aStreamList);
|
||||
|
||||
const nsTArray<PCacheResponse>& SendAsResponseList();
|
||||
|
||||
private:
|
||||
// Allocates ~4k inline in the stack-only class
|
||||
nsAutoTArray<PCacheResponse, 32> mResponseList;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoParentResponseOrVoid final : public AutoParentBase
|
||||
{
|
||||
public:
|
||||
explicit AutoParentResponseOrVoid(mozilla::ipc::PBackgroundParent* aManager);
|
||||
~AutoParentResponseOrVoid();
|
||||
|
||||
void Add(const SavedResponse& aSavedResponse, StreamList* aStreamList);
|
||||
|
||||
const PCacheResponseOrVoid& SendAsResponseOrVoid();
|
||||
|
||||
private:
|
||||
PCacheResponseOrVoid mResponseOrVoid;
|
||||
};
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
337
dom/cache/Cache.cpp
vendored
337
dom/cache/Cache.cpp
vendored
@ -14,9 +14,9 @@
|
||||
#include "mozilla/dom/CacheBinding.h"
|
||||
#include "mozilla/dom/cache/AutoUtils.h"
|
||||
#include "mozilla/dom/cache/CacheChild.h"
|
||||
#include "mozilla/dom/cache/CacheOpChild.h"
|
||||
#include "mozilla/dom/cache/CachePushStreamChild.h"
|
||||
#include "mozilla/dom/cache/ReadStream.h"
|
||||
#include "mozilla/dom/cache/TypeUtils.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/unused.h"
|
||||
@ -79,7 +79,17 @@ using mozilla::dom::workers::WorkerPrivate;
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(mozilla::dom::cache::Cache);
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(mozilla::dom::cache::Cache);
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(mozilla::dom::cache::Cache, mGlobal);
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(mozilla::dom::cache::Cache)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(mozilla::dom::cache::Cache)
|
||||
tmp->DisconnectFromActor();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal, mRequestPromises)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(mozilla::dom::cache::Cache)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal, mRequestPromises)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(mozilla::dom::cache::Cache)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Cache)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
@ -101,22 +111,31 @@ Cache::Match(const RequestOrUSVString& aRequest,
|
||||
{
|
||||
MOZ_ASSERT(mActor);
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<InternalRequest> ir = ToInternalRequest(aRequest, IgnoreBody, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AutoChildRequest request(this);
|
||||
|
||||
request.Add(ir, IgnoreBody, PassThroughReferrer, IgnoreInvalidScheme, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PCacheQueryParams params;
|
||||
ToPCacheQueryParams(params, aOptions);
|
||||
|
||||
AutoChildOpArgs args(this, CacheMatchArgs(PCacheRequest(), params));
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
args.Add(ir, IgnoreBody, PassThroughReferrer, IgnoreInvalidScheme, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
unused << mActor->SendMatch(requestId, request.SendAsRequest(), params);
|
||||
|
||||
return ExecuteOp(args, aRv);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
@ -125,10 +144,12 @@ Cache::MatchAll(const Optional<RequestOrUSVString>& aRequest,
|
||||
{
|
||||
MOZ_ASSERT(mActor);
|
||||
|
||||
PCacheQueryParams params;
|
||||
ToPCacheQueryParams(params, aOptions);
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AutoChildOpArgs args(this, CacheMatchAllArgs(void_t(), params));
|
||||
AutoChildRequest request(this);
|
||||
|
||||
if (aRequest.WasPassed()) {
|
||||
nsRefPtr<InternalRequest> ir = ToInternalRequest(aRequest.Value(),
|
||||
@ -137,13 +158,21 @@ Cache::MatchAll(const Optional<RequestOrUSVString>& aRequest,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
args.Add(ir, IgnoreBody, PassThroughReferrer, IgnoreInvalidScheme, aRv);
|
||||
request.Add(ir, IgnoreBody, PassThroughReferrer, IgnoreInvalidScheme, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return ExecuteOp(args, aRv);
|
||||
PCacheQueryParams params;
|
||||
ToPCacheQueryParams(params, aOptions);
|
||||
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
unused << mActor->SendMatchAll(requestId, request.SendAsRequestOrVoid(),
|
||||
params);
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
@ -155,19 +184,27 @@ Cache::Add(const RequestOrUSVString& aRequest, ErrorResult& aRv)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<InternalRequest> ir = ToInternalRequest(aRequest, ReadBody, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AutoChildOpArgs args(this, CacheAddAllArgs());
|
||||
|
||||
args.Add(ir, ReadBody, ExpandReferrer, NetworkErrorOnInvalidScheme, aRv);
|
||||
AutoChildRequestList requests(this, 1);
|
||||
requests.Add(ir, ReadBody, ExpandReferrer, NetworkErrorOnInvalidScheme, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ExecuteOp(args, aRv);
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
unused << mActor->SendAddAll(requestId, requests.SendAsRequestList());
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
@ -176,18 +213,18 @@ Cache::AddAll(const Sequence<OwningRequestOrUSVString>& aRequests,
|
||||
{
|
||||
MOZ_ASSERT(mActor);
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// If there is no work to do, then resolve immediately
|
||||
if (aRequests.IsEmpty()) {
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
AutoChildOpArgs args(this, CacheAddAllArgs());
|
||||
AutoChildRequestList requests(this, aRequests.Length());
|
||||
|
||||
for (uint32_t i = 0; i < aRequests.Length(); ++i) {
|
||||
if (!IsValidPutRequestMethod(aRequests[i], aRv)) {
|
||||
@ -200,13 +237,18 @@ Cache::AddAll(const Sequence<OwningRequestOrUSVString>& aRequests,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
args.Add(ir, ReadBody, ExpandReferrer, NetworkErrorOnInvalidScheme, aRv);
|
||||
requests.Add(ir, ReadBody, ExpandReferrer, NetworkErrorOnInvalidScheme,
|
||||
aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return ExecuteOp(args, aRv);
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
unused << mActor->SendAddAll(requestId, requests.SendAsRequestList());
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
@ -219,20 +261,32 @@ Cache::Put(const RequestOrUSVString& aRequest, Response& aResponse,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<InternalRequest> ir = ToInternalRequest(aRequest, ReadBody, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AutoChildOpArgs args(this, CachePutAllArgs());
|
||||
|
||||
args.Add(ir, ReadBody, PassThroughReferrer, TypeErrorOnInvalidScheme,
|
||||
aResponse, aRv);
|
||||
AutoChildRequestResponse put(this);
|
||||
put.Add(ir, ReadBody, PassThroughReferrer, TypeErrorOnInvalidScheme, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ExecuteOp(args, aRv);
|
||||
put.Add(aResponse, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
unused << mActor->SendPut(requestId, put.SendAsRequestResponse());
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
@ -241,22 +295,30 @@ Cache::Delete(const RequestOrUSVString& aRequest,
|
||||
{
|
||||
MOZ_ASSERT(mActor);
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<InternalRequest> ir = ToInternalRequest(aRequest, IgnoreBody, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AutoChildRequest request(this);
|
||||
request.Add(ir, IgnoreBody, PassThroughReferrer, IgnoreInvalidScheme, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PCacheQueryParams params;
|
||||
ToPCacheQueryParams(params, aOptions);
|
||||
|
||||
AutoChildOpArgs args(this, CacheDeleteArgs(PCacheRequest(), params));
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
args.Add(ir, IgnoreBody, PassThroughReferrer, IgnoreInvalidScheme, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
unused << mActor->SendDelete(requestId, request.SendAsRequest(), params);
|
||||
|
||||
return ExecuteOp(args, aRv);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
@ -265,10 +327,12 @@ Cache::Keys(const Optional<RequestOrUSVString>& aRequest,
|
||||
{
|
||||
MOZ_ASSERT(mActor);
|
||||
|
||||
PCacheQueryParams params;
|
||||
ToPCacheQueryParams(params, aOptions);
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AutoChildOpArgs args(this, CacheKeysArgs(void_t(), params));
|
||||
AutoChildRequest request(this);
|
||||
|
||||
if (aRequest.WasPassed()) {
|
||||
nsRefPtr<InternalRequest> ir = ToInternalRequest(aRequest.Value(),
|
||||
@ -277,13 +341,20 @@ Cache::Keys(const Optional<RequestOrUSVString>& aRequest,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
args.Add(ir, IgnoreBody, PassThroughReferrer, IgnoreInvalidScheme, aRv);
|
||||
request.Add(ir, IgnoreBody, PassThroughReferrer, IgnoreInvalidScheme, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return ExecuteOp(args, aRv);
|
||||
PCacheQueryParams params;
|
||||
ToPCacheQueryParams(params, aOptions);
|
||||
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
unused << mActor->SendKeys(requestId, request.SendAsRequestOrVoid(), params);
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
@ -330,6 +401,119 @@ Cache::DestroyInternal(CacheChild* aActor)
|
||||
mActor = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
Cache::RecvMatchResponse(RequestId aRequestId, nsresult aRv,
|
||||
const PCacheResponseOrVoid& aResponse)
|
||||
{
|
||||
// Convert the response immediately if its present. This ensures that
|
||||
// any stream actors are cleaned up, even if we error out below.
|
||||
nsRefPtr<Response> response;
|
||||
if (aResponse.type() == PCacheResponseOrVoid::TPCacheResponse) {
|
||||
response = ToResponse(aResponse);
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!response) {
|
||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
return;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(response);
|
||||
}
|
||||
|
||||
void
|
||||
Cache::RecvMatchAllResponse(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<PCacheResponse>& aResponses)
|
||||
{
|
||||
// Convert responses immediately. This ensures that any stream actors are
|
||||
// cleaned up, even if we error out below.
|
||||
nsAutoTArray<nsRefPtr<Response>, 256> responses;
|
||||
responses.SetCapacity(aResponses.Length());
|
||||
|
||||
for (uint32_t i = 0; i < aResponses.Length(); ++i) {
|
||||
nsRefPtr<Response> response = ToResponse(aResponses[i]);
|
||||
responses.AppendElement(response.forget());
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(responses);
|
||||
}
|
||||
|
||||
void
|
||||
Cache::RecvAddAllResponse(RequestId aRequestId, nsresult aRv)
|
||||
{
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
}
|
||||
|
||||
void
|
||||
Cache::RecvPutResponse(RequestId aRequestId, nsresult aRv)
|
||||
{
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
}
|
||||
|
||||
void
|
||||
Cache::RecvDeleteResponse(RequestId aRequestId, nsresult aRv, bool aSuccess)
|
||||
{
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(aSuccess);
|
||||
}
|
||||
|
||||
void
|
||||
Cache::RecvKeysResponse(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<PCacheRequest>& aRequests)
|
||||
{
|
||||
// Convert requests immediately. This ensures that any stream actors are
|
||||
// cleaned up, even if we error out below.
|
||||
nsAutoTArray<nsRefPtr<Request>, 256> requests;
|
||||
requests.SetCapacity(aRequests.Length());
|
||||
|
||||
for (uint32_t i = 0; i < aRequests.Length(); ++i) {
|
||||
nsRefPtr<Request> request = ToRequest(aRequests[i]);
|
||||
requests.AppendElement(request.forget());
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(requests);
|
||||
}
|
||||
|
||||
nsIGlobalObject*
|
||||
Cache::GetGlobalObject() const
|
||||
{
|
||||
@ -356,9 +540,30 @@ Cache::CreatePushStream(nsIAsyncInputStream* aStream)
|
||||
return static_cast<CachePushStreamChild*>(actor);
|
||||
}
|
||||
|
||||
void
|
||||
Cache::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
|
||||
{
|
||||
// Do nothing. The Promise will automatically drop the ref to us after
|
||||
// calling the callback. This is what we want as we only registered in order
|
||||
// to be held alive via the Promise handle.
|
||||
}
|
||||
|
||||
void
|
||||
Cache::RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
|
||||
{
|
||||
// Do nothing. The Promise will automatically drop the ref to us after
|
||||
// calling the callback. This is what we want as we only registered in order
|
||||
// to be held alive via the Promise handle.
|
||||
}
|
||||
|
||||
Cache::~Cache()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(Cache);
|
||||
DisconnectFromActor();
|
||||
}
|
||||
|
||||
void
|
||||
Cache::DisconnectFromActor()
|
||||
{
|
||||
if (mActor) {
|
||||
mActor->StartDestroy();
|
||||
// DestroyInternal() is called synchronously by StartDestroy(). So we
|
||||
@ -367,19 +572,43 @@ Cache::~Cache()
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
Cache::ExecuteOp(AutoChildOpArgs& aOpArgs, ErrorResult& aRv)
|
||||
RequestId
|
||||
Cache::AddRequestPromise(Promise* aPromise, ErrorResult& aRv)
|
||||
{
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
MOZ_ASSERT(aPromise);
|
||||
MOZ_ASSERT(!mRequestPromises.Contains(aPromise));
|
||||
|
||||
// Register ourself as a promise handler so that the promise will hold us
|
||||
// alive. This allows the client code to drop the ref to the Cache
|
||||
// object and just keep their promise. This is fairly common in promise
|
||||
// chaining code.
|
||||
aPromise->AppendNativeHandler(this);
|
||||
|
||||
mRequestPromises.AppendElement(aPromise);
|
||||
|
||||
// (Ab)use the promise pointer as our request ID. This is a fast, thread-safe
|
||||
// way to get a unique ID for the promise to be resolved later.
|
||||
return reinterpret_cast<RequestId>(aPromise);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
Cache::RemoveRequestPromise(RequestId aRequestId)
|
||||
{
|
||||
MOZ_ASSERT(aRequestId != INVALID_REQUEST_ID);
|
||||
|
||||
for (uint32_t i = 0; i < mRequestPromises.Length(); ++i) {
|
||||
nsRefPtr<Promise>& promise = mRequestPromises.ElementAt(i);
|
||||
// To be safe, only cast promise pointers to our integer RequestId
|
||||
// type and never cast an integer to a pointer.
|
||||
if (aRequestId == reinterpret_cast<RequestId>(promise.get())) {
|
||||
nsRefPtr<Promise> ref;
|
||||
ref.swap(promise);
|
||||
mRequestPromises.RemoveElementAt(i);
|
||||
return ref.forget();
|
||||
}
|
||||
}
|
||||
|
||||
unused << mActor->SendPCacheOpConstructor(
|
||||
new CacheOpChild(mActor->GetFeature(), mGlobal, this, promise),
|
||||
aOpArgs.SendAsOpArgs());
|
||||
|
||||
return promise.forget();
|
||||
MOZ_ASSERT_UNREACHABLE("Received response without a matching promise!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
|
36
dom/cache/Cache.h
vendored
36
dom/cache/Cache.h
vendored
@ -7,6 +7,7 @@
|
||||
#ifndef mozilla_dom_cache_Cache_h
|
||||
#define mozilla_dom_cache_Cache_h
|
||||
|
||||
#include "mozilla/dom/PromiseNativeHandler.h"
|
||||
#include "mozilla/dom/cache/Types.h"
|
||||
#include "mozilla/dom/cache/TypeUtils.h"
|
||||
#include "nsCOMPtr.h"
|
||||
@ -32,10 +33,12 @@ template<typename T> class Sequence;
|
||||
|
||||
namespace cache {
|
||||
|
||||
class AutoChildOpArgs;
|
||||
class CacheChild;
|
||||
class PCacheRequest;
|
||||
class PCacheResponse;
|
||||
class PCacheResponseOrVoid;
|
||||
|
||||
class Cache final : public nsISupports
|
||||
class Cache final : public PromiseNativeHandler
|
||||
, public nsWrapperCache
|
||||
, public TypeUtils
|
||||
{
|
||||
@ -73,6 +76,19 @@ public:
|
||||
// Called when CacheChild actor is being destroyed
|
||||
void DestroyInternal(CacheChild* aActor);
|
||||
|
||||
// methods forwarded from CacheChild
|
||||
void RecvMatchResponse(RequestId aRequestId, nsresult aRv,
|
||||
const PCacheResponseOrVoid& aResponse);
|
||||
void RecvMatchAllResponse(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<PCacheResponse>& aResponses);
|
||||
void RecvAddAllResponse(RequestId aRequestId, nsresult aRv);
|
||||
void RecvPutResponse(RequestId aRequestId, nsresult aRv);
|
||||
|
||||
void RecvDeleteResponse(RequestId aRequestId, nsresult aRv,
|
||||
bool aSuccess);
|
||||
void RecvKeysResponse(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<PCacheRequest>& aRequests);
|
||||
|
||||
// TypeUtils methods
|
||||
virtual nsIGlobalObject*
|
||||
GetGlobalObject() const override;
|
||||
@ -84,14 +100,26 @@ public:
|
||||
virtual CachePushStreamChild*
|
||||
CreatePushStream(nsIAsyncInputStream* aStream) override;
|
||||
|
||||
// PromiseNativeHandler methods
|
||||
virtual void
|
||||
ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
|
||||
|
||||
virtual void
|
||||
RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
|
||||
|
||||
private:
|
||||
~Cache();
|
||||
|
||||
already_AddRefed<Promise>
|
||||
ExecuteOp(AutoChildOpArgs& aOpArgs, ErrorResult& aRv);
|
||||
// Called when we're destroyed or CCed.
|
||||
void DisconnectFromActor();
|
||||
|
||||
// TODO: Replace with actor-per-request model during refactor (bug 1110485)
|
||||
RequestId AddRequestPromise(Promise* aPromise, ErrorResult& aRv);
|
||||
already_AddRefed<Promise> RemoveRequestPromise(RequestId aRequestId);
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> mGlobal;
|
||||
CacheChild* mActor;
|
||||
nsTArray<nsRefPtr<Promise>> mRequestPromises;
|
||||
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
|
105
dom/cache/CacheChild.cpp
vendored
105
dom/cache/CacheChild.cpp
vendored
@ -9,7 +9,6 @@
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/dom/cache/ActorUtils.h"
|
||||
#include "mozilla/dom/cache/Cache.h"
|
||||
#include "mozilla/dom/cache/PCacheOpChild.h"
|
||||
#include "mozilla/dom/cache/PCachePushStreamChild.h"
|
||||
#include "mozilla/dom/cache/StreamUtils.h"
|
||||
|
||||
@ -73,8 +72,6 @@ CacheChild::StartDestroy()
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: only destroy if there are no ops or push streams still running
|
||||
|
||||
listener->DestroyInternal(this);
|
||||
|
||||
// Cache listener should call ClearListener() in DestroyInternal()
|
||||
@ -98,20 +95,6 @@ CacheChild::ActorDestroy(ActorDestroyReason aReason)
|
||||
RemoveFeature();
|
||||
}
|
||||
|
||||
PCacheOpChild*
|
||||
CacheChild::AllocPCacheOpChild(const CacheOpArgs& aOpArgs)
|
||||
{
|
||||
MOZ_CRASH("CacheOpChild should be manually constructed.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheChild::DeallocPCacheOpChild(PCacheOpChild* aActor)
|
||||
{
|
||||
delete aActor;
|
||||
return true;
|
||||
}
|
||||
|
||||
PCachePushStreamChild*
|
||||
CacheChild::AllocPCachePushStreamChild()
|
||||
{
|
||||
@ -126,6 +109,94 @@ CacheChild::DeallocPCachePushStreamChild(PCachePushStreamChild* aActor)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheChild::RecvMatchResponse(const RequestId& requestId, const nsresult& aRv,
|
||||
const PCacheResponseOrVoid& aResponse)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheChild);
|
||||
|
||||
AddFeatureToStreamChild(aResponse, GetFeature());
|
||||
|
||||
nsRefPtr<Cache> listener = mListener;
|
||||
if (!listener) {
|
||||
StartDestroyStreamChild(aResponse);
|
||||
return true;
|
||||
}
|
||||
|
||||
listener->RecvMatchResponse(requestId, aRv, aResponse);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheChild::RecvMatchAllResponse(const RequestId& requestId, const nsresult& aRv,
|
||||
nsTArray<PCacheResponse>&& aResponses)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheChild);
|
||||
|
||||
AddFeatureToStreamChild(aResponses, GetFeature());
|
||||
|
||||
nsRefPtr<Cache> listener = mListener;
|
||||
if (!listener) {
|
||||
StartDestroyStreamChild(aResponses);
|
||||
return true;
|
||||
}
|
||||
|
||||
listener->RecvMatchAllResponse(requestId, aRv, aResponses);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheChild::RecvAddAllResponse(const RequestId& requestId, const nsresult& aRv)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheChild);
|
||||
nsRefPtr<Cache> listener = mListener;
|
||||
if (listener) {
|
||||
listener->RecvAddAllResponse(requestId, aRv);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheChild::RecvPutResponse(const RequestId& aRequestId, const nsresult& aRv)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheChild);
|
||||
nsRefPtr<Cache> listener = mListener;
|
||||
if (listener) {
|
||||
listener->RecvPutResponse(aRequestId, aRv);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheChild::RecvDeleteResponse(const RequestId& requestId, const nsresult& aRv,
|
||||
const bool& result)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheChild);
|
||||
nsRefPtr<Cache> listener = mListener;
|
||||
if (listener) {
|
||||
listener->RecvDeleteResponse(requestId, aRv, result);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheChild::RecvKeysResponse(const RequestId& requestId, const nsresult& aRv,
|
||||
nsTArray<PCacheRequest>&& aRequests)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheChild);
|
||||
|
||||
AddFeatureToStreamChild(aRequests, GetFeature());
|
||||
|
||||
nsRefPtr<Cache> listener = mListener;
|
||||
if (!listener) {
|
||||
StartDestroyStreamChild(aRequests);
|
||||
return true;
|
||||
}
|
||||
|
||||
listener->RecvKeysResponse(requestId, aRv, aRequests);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namesapce mozilla
|
||||
|
25
dom/cache/CacheChild.h
vendored
25
dom/cache/CacheChild.h
vendored
@ -41,18 +41,31 @@ private:
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
virtual PCacheOpChild*
|
||||
AllocPCacheOpChild(const CacheOpArgs& aOpArgs) override;
|
||||
|
||||
virtual bool
|
||||
DeallocPCacheOpChild(PCacheOpChild* aActor) override;
|
||||
|
||||
virtual PCachePushStreamChild*
|
||||
AllocPCachePushStreamChild() override;
|
||||
|
||||
virtual bool
|
||||
DeallocPCachePushStreamChild(PCachePushStreamChild* aActor) override;
|
||||
|
||||
virtual bool
|
||||
RecvMatchResponse(const RequestId& requestId, const nsresult& aRv,
|
||||
const PCacheResponseOrVoid& aResponse) override;
|
||||
virtual bool
|
||||
RecvMatchAllResponse(const RequestId& requestId, const nsresult& aRv,
|
||||
nsTArray<PCacheResponse>&& responses) override;
|
||||
virtual bool
|
||||
RecvAddAllResponse(const RequestId& requestId,
|
||||
const nsresult& aRv) override;
|
||||
virtual bool
|
||||
RecvPutResponse(const RequestId& aRequestId,
|
||||
const nsresult& aRv) override;
|
||||
virtual bool
|
||||
RecvDeleteResponse(const RequestId& requestId, const nsresult& aRv,
|
||||
const bool& result) override;
|
||||
virtual bool
|
||||
RecvKeysResponse(const RequestId& requestId, const nsresult& aRv,
|
||||
nsTArray<PCacheRequest>&& requests) override;
|
||||
|
||||
// Use a weak ref so actor does not hold DOM object alive past content use.
|
||||
// The Cache object must call ClearListener() to null this before its
|
||||
// destroyed.
|
||||
|
24
dom/cache/CacheInitData.ipdlh
vendored
Normal file
24
dom/cache/CacheInitData.ipdlh
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include PBackgroundSharedTypes;
|
||||
|
||||
using mozilla::dom::cache::Namespace from "mozilla/dom/cache/Types.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
// Data needed to initialize a CacheStorage or Cache backend. Don't put
|
||||
// this with the other types in PCacheTypes.ipdlh since we want to import
|
||||
// it into PBackground.ipdl.
|
||||
struct CacheInitData
|
||||
{
|
||||
Namespace namespaceEnum;
|
||||
PrincipalInfo principalInfo;
|
||||
};
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
201
dom/cache/CacheOpChild.cpp
vendored
201
dom/cache/CacheOpChild.cpp
vendored
@ -1,201 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/cache/CacheOpChild.h"
|
||||
|
||||
#include "mozilla/dom/cache/Cache.h"
|
||||
#include "mozilla/dom/cache/CacheChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
CacheOpChild::CacheOpChild(Feature* aFeature, nsIGlobalObject* aGlobal,
|
||||
nsISupports* aParent, Promise* aPromise)
|
||||
: mGlobal(aGlobal)
|
||||
, mParent(aParent)
|
||||
, mPromise(aPromise)
|
||||
{
|
||||
MOZ_ASSERT(mGlobal);
|
||||
MOZ_ASSERT(mParent);
|
||||
MOZ_ASSERT(mPromise);
|
||||
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), aFeature);
|
||||
SetFeature(aFeature);
|
||||
}
|
||||
|
||||
CacheOpChild::~CacheOpChild()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpChild);
|
||||
MOZ_ASSERT(!mPromise);
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpChild::ActorDestroy(ActorDestroyReason aReason)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpChild);
|
||||
|
||||
// If the actor was terminated for some unknown reason, then indicate the
|
||||
// operation is dead.
|
||||
if (mPromise) {
|
||||
mPromise->MaybeReject(NS_ERROR_FAILURE);
|
||||
mPromise = nullptr;
|
||||
}
|
||||
|
||||
RemoveFeature();
|
||||
}
|
||||
|
||||
bool
|
||||
CacheOpChild::Recv__delete__(const nsresult& aStatus,
|
||||
const CacheOpResult& aResult)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpChild);
|
||||
|
||||
if (NS_FAILED(aStatus)) {
|
||||
mPromise->MaybeReject(aStatus);
|
||||
mPromise = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (aResult.type()) {
|
||||
case CacheOpResult::TCacheMatchResult:
|
||||
{
|
||||
HandleResponse(aResult.get_CacheMatchResult().responseOrVoid());
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TCacheMatchAllResult:
|
||||
{
|
||||
HandleResponseList(aResult.get_CacheMatchAllResult().responseList());
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TCacheAddAllResult:
|
||||
case CacheOpResult::TCachePutAllResult:
|
||||
{
|
||||
mPromise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TCacheDeleteResult:
|
||||
{
|
||||
mPromise->MaybeResolve(aResult.get_CacheDeleteResult().success());
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TCacheKeysResult:
|
||||
{
|
||||
HandleRequestList(aResult.get_CacheKeysResult().requestList());
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TStorageMatchResult:
|
||||
{
|
||||
HandleResponse(aResult.get_StorageMatchResult().responseOrVoid());
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TStorageHasResult:
|
||||
{
|
||||
mPromise->MaybeResolve(aResult.get_StorageHasResult().success());
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TStorageOpenResult:
|
||||
{
|
||||
auto actor = static_cast<CacheChild*>(
|
||||
aResult.get_StorageOpenResult().actorChild());
|
||||
actor->SetFeature(GetFeature());
|
||||
nsRefPtr<Cache> cache = new Cache(mGlobal, actor);
|
||||
mPromise->MaybeResolve(cache);
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TStorageDeleteResult:
|
||||
{
|
||||
mPromise->MaybeResolve(aResult.get_StorageDeleteResult().success());
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TStorageKeysResult:
|
||||
{
|
||||
mPromise->MaybeResolve(aResult.get_StorageKeysResult().keyList());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Unknown Cache op result type!");
|
||||
}
|
||||
|
||||
mPromise = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpChild::StartDestroy()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpChild);
|
||||
|
||||
// Do not cancel on-going operations when Feature calls this. Instead, keep
|
||||
// the Worker alive until we are done.
|
||||
}
|
||||
|
||||
nsIGlobalObject*
|
||||
CacheOpChild::GetGlobalObject() const
|
||||
{
|
||||
return mGlobal;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
CacheOpChild::AssertOwningThread() const
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpChild);
|
||||
}
|
||||
#endif
|
||||
|
||||
CachePushStreamChild*
|
||||
CacheOpChild::CreatePushStream(nsIAsyncInputStream* aStream)
|
||||
{
|
||||
MOZ_CRASH("CacheOpChild should never create a push stream actor!");
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpChild::HandleResponse(const PCacheResponseOrVoid& aResponseOrVoid)
|
||||
{
|
||||
nsRefPtr<Response> response;
|
||||
if (aResponseOrVoid.type() == PCacheResponseOrVoid::TPCacheResponse) {
|
||||
response = ToResponse(aResponseOrVoid);
|
||||
}
|
||||
|
||||
if (!response) {
|
||||
mPromise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
return;
|
||||
}
|
||||
|
||||
mPromise->MaybeResolve(response);
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpChild::HandleResponseList(const nsTArray<PCacheResponse>& aResponseList)
|
||||
{
|
||||
nsAutoTArray<nsRefPtr<Response>, 256> responses;
|
||||
responses.SetCapacity(aResponseList.Length());
|
||||
|
||||
for (uint32_t i = 0; i < aResponseList.Length(); ++i) {
|
||||
responses.AppendElement(ToResponse(aResponseList[i]));
|
||||
}
|
||||
|
||||
mPromise->MaybeResolve(responses);
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpChild::HandleRequestList(const nsTArray<PCacheRequest>& aRequestList)
|
||||
{
|
||||
nsAutoTArray<nsRefPtr<Request>, 256> requests;
|
||||
requests.SetCapacity(aRequestList.Length());
|
||||
|
||||
for (uint32_t i = 0; i < aRequestList.Length(); ++i) {
|
||||
requests.AppendElement(ToRequest(aRequestList[i]));
|
||||
}
|
||||
|
||||
mPromise->MaybeResolve(requests);
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
78
dom/cache/CacheOpChild.h
vendored
78
dom/cache/CacheOpChild.h
vendored
@ -1,78 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_cache_CacheOpChild_h
|
||||
#define mozilla_dom_cache_CacheOpChild_h
|
||||
|
||||
#include "mozilla/dom/cache/ActorChild.h"
|
||||
#include "mozilla/dom/cache/PCacheOpChild.h"
|
||||
#include "mozilla/dom/cache/TypeUtils.h"
|
||||
#include "nsRefPtr.h"
|
||||
|
||||
class nsIGlobalObject;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class Promise;
|
||||
|
||||
namespace cache {
|
||||
|
||||
class CacheOpChild final : public PCacheOpChild
|
||||
, public ActorChild
|
||||
, public TypeUtils
|
||||
{
|
||||
public:
|
||||
CacheOpChild(Feature* aFeature, nsIGlobalObject* aGlobal,
|
||||
nsISupports* aParent, Promise* aPromise);
|
||||
~CacheOpChild();
|
||||
|
||||
private:
|
||||
// PCacheOpChild methods
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
virtual bool
|
||||
Recv__delete__(const nsresult& aStatus, const CacheOpResult& aResult) override;
|
||||
|
||||
// ActorChild methods
|
||||
virtual void
|
||||
StartDestroy() override;
|
||||
|
||||
// TypeUtils methods
|
||||
virtual nsIGlobalObject*
|
||||
GetGlobalObject() const override;
|
||||
|
||||
#ifdef DEBUG
|
||||
virtual void
|
||||
AssertOwningThread() const override;
|
||||
#endif
|
||||
|
||||
virtual CachePushStreamChild*
|
||||
CreatePushStream(nsIAsyncInputStream* aStream) override;
|
||||
|
||||
// Utility methods
|
||||
void
|
||||
HandleResponse(const PCacheResponseOrVoid& aResponseOrVoid);
|
||||
|
||||
void
|
||||
HandleResponseList(const nsTArray<PCacheResponse>& aResponseList);
|
||||
|
||||
void
|
||||
HandleRequestList(const nsTArray<PCacheRequest>& aRequestList);
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> mGlobal;
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
nsRefPtr<Promise> mPromise;
|
||||
|
||||
NS_DECL_OWNINGTHREAD
|
||||
};
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_cache_CacheOpChild_h
|
284
dom/cache/CacheOpParent.cpp
vendored
284
dom/cache/CacheOpParent.cpp
vendored
@ -1,284 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/cache/CacheOpParent.h"
|
||||
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/dom/cache/AutoUtils.h"
|
||||
#include "mozilla/dom/cache/CachePushStreamParent.h"
|
||||
#include "mozilla/dom/cache/ReadStream.h"
|
||||
#include "mozilla/dom/cache/SavedTypes.h"
|
||||
#include "mozilla/ipc/FileDescriptorSetParent.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
using mozilla::ipc::FileDescriptorSetParent;
|
||||
using mozilla::ipc::PBackgroundParent;
|
||||
|
||||
CacheOpParent::CacheOpParent(PBackgroundParent* aIpcManager, CacheId aCacheId,
|
||||
const CacheOpArgs& aOpArgs)
|
||||
: mIpcManager(aIpcManager)
|
||||
, mCacheId(aCacheId)
|
||||
, mNamespace(INVALID_NAMESPACE)
|
||||
, mOpArgs(aOpArgs)
|
||||
{
|
||||
MOZ_ASSERT(mIpcManager);
|
||||
}
|
||||
|
||||
CacheOpParent::CacheOpParent(PBackgroundParent* aIpcManager,
|
||||
Namespace aNamespace, const CacheOpArgs& aOpArgs)
|
||||
: mIpcManager(aIpcManager)
|
||||
, mCacheId(INVALID_CACHE_ID)
|
||||
, mNamespace(aNamespace)
|
||||
, mOpArgs(aOpArgs)
|
||||
{
|
||||
MOZ_ASSERT(mIpcManager);
|
||||
}
|
||||
|
||||
CacheOpParent::~CacheOpParent()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpParent);
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpParent::Execute(ManagerId* aManagerId)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpParent);
|
||||
MOZ_ASSERT(!mManager);
|
||||
MOZ_ASSERT(!mVerifier);
|
||||
|
||||
nsRefPtr<Manager> manager;
|
||||
nsresult rv = Manager::GetOrCreate(aManagerId, getter_AddRefs(manager));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
unused << Send__delete__(this, rv, void_t());
|
||||
return;
|
||||
}
|
||||
|
||||
Execute(manager);
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpParent::Execute(Manager* aManager)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpParent);
|
||||
MOZ_ASSERT(!mManager);
|
||||
MOZ_ASSERT(!mVerifier);
|
||||
|
||||
mManager = aManager;
|
||||
|
||||
// Handle add/addAll op with a FetchPut object
|
||||
if (mOpArgs.type() == CacheOpArgs::TCacheAddAllArgs) {
|
||||
MOZ_ASSERT(mCacheId != INVALID_CACHE_ID);
|
||||
|
||||
const CacheAddAllArgs& args = mOpArgs.get_CacheAddAllArgs();
|
||||
const nsTArray<PCacheRequest>& list = args.requestList();
|
||||
|
||||
nsAutoTArray<nsCOMPtr<nsIInputStream>, 256> requestStreamList;
|
||||
for (uint32_t i = 0; i < list.Length(); ++i) {
|
||||
requestStreamList.AppendElement(DeserializeCacheStream(list[i].body()));
|
||||
}
|
||||
|
||||
nsRefPtr<FetchPut> fetchPut;
|
||||
nsresult rv = FetchPut::Create(this, mManager, mCacheId, list,
|
||||
requestStreamList, getter_AddRefs(fetchPut));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
OnOpComplete(rv, CacheAddAllResult());
|
||||
return;
|
||||
}
|
||||
|
||||
mFetchPutList.AppendElement(fetchPut.forget());
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle put op
|
||||
if (mOpArgs.type() == CacheOpArgs::TCachePutAllArgs) {
|
||||
MOZ_ASSERT(mCacheId != INVALID_CACHE_ID);
|
||||
|
||||
const CachePutAllArgs& args = mOpArgs.get_CachePutAllArgs();
|
||||
const nsTArray<CacheRequestResponse>& list = args.requestResponseList();
|
||||
|
||||
nsAutoTArray<nsCOMPtr<nsIInputStream>, 256> requestStreamList;
|
||||
nsAutoTArray<nsCOMPtr<nsIInputStream>, 256> responseStreamList;
|
||||
|
||||
for (uint32_t i = 0; i < list.Length(); ++i) {
|
||||
requestStreamList.AppendElement(
|
||||
DeserializeCacheStream(list[i].request().body()));
|
||||
responseStreamList.AppendElement(
|
||||
DeserializeCacheStream(list[i].response().body()));
|
||||
}
|
||||
|
||||
mManager->ExecutePutAll(this, mCacheId, args.requestResponseList(),
|
||||
requestStreamList, responseStreamList);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle all other cache ops
|
||||
if (mCacheId != INVALID_CACHE_ID) {
|
||||
MOZ_ASSERT(mNamespace == INVALID_NAMESPACE);
|
||||
mManager->ExecuteCacheOp(this, mCacheId, mOpArgs);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle all storage ops
|
||||
MOZ_ASSERT(mNamespace != INVALID_NAMESPACE);
|
||||
mManager->ExecuteStorageOp(this, mNamespace, mOpArgs);
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpParent::WaitForVerification(PrincipalVerifier* aVerifier)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpParent);
|
||||
MOZ_ASSERT(!mManager);
|
||||
MOZ_ASSERT(!mVerifier);
|
||||
|
||||
mVerifier = aVerifier;
|
||||
mVerifier->AddListener(this);
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpParent::ActorDestroy(ActorDestroyReason aReason)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpParent);
|
||||
|
||||
if (mVerifier) {
|
||||
mVerifier->RemoveListener(this);
|
||||
mVerifier = nullptr;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mFetchPutList.Length(); ++i) {
|
||||
mFetchPutList[i]->ClearListener();
|
||||
}
|
||||
mFetchPutList.Clear();
|
||||
|
||||
if (mManager) {
|
||||
mManager->RemoveListener(this);
|
||||
mManager = nullptr;
|
||||
}
|
||||
|
||||
mIpcManager = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpParent::OnPrincipalVerified(nsresult aRv, ManagerId* aManagerId)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpParent);
|
||||
|
||||
mVerifier->RemoveListener(this);
|
||||
mVerifier = nullptr;
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(aRv))) {
|
||||
unused << Send__delete__(this, aRv, void_t());
|
||||
return;
|
||||
}
|
||||
|
||||
Execute(aManagerId);
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpParent::OnOpComplete(nsresult aRv, const CacheOpResult& aResult,
|
||||
CacheId aOpenedCacheId,
|
||||
const nsTArray<SavedResponse>& aSavedResponseList,
|
||||
const nsTArray<SavedRequest>& aSavedRequestList,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpParent);
|
||||
MOZ_ASSERT(mIpcManager);
|
||||
MOZ_ASSERT(mManager);
|
||||
|
||||
// The result must contain the appropriate type at this point. It may
|
||||
// or may not contain the additional result data yet. For types that
|
||||
// do not need special processing, it should already be set. If the
|
||||
// result requires actor-specific operations, then we do that below.
|
||||
// If the type and data types don't match, then we will trigger an
|
||||
// assertion in AutoParentOpResult::Add().
|
||||
AutoParentOpResult result(mIpcManager, aResult);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
unused << Send__delete__(this, aRv, result.SendAsOpResult());
|
||||
return;
|
||||
}
|
||||
|
||||
if (aOpenedCacheId != INVALID_CACHE_ID) {
|
||||
result.Add(aOpenedCacheId, mManager);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < aSavedResponseList.Length(); ++i) {
|
||||
result.Add(aSavedResponseList[i], aStreamList);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < aSavedRequestList.Length(); ++i) {
|
||||
result.Add(aSavedRequestList[i], aStreamList);
|
||||
}
|
||||
|
||||
unused << Send__delete__(this, aRv, result.SendAsOpResult());
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpParent::OnFetchPut(FetchPut* aFetchPut, nsresult aRv)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpParent);
|
||||
MOZ_ASSERT(aFetchPut);
|
||||
|
||||
aFetchPut->ClearListener();
|
||||
MOZ_ALWAYS_TRUE(mFetchPutList.RemoveElement(aFetchPut));
|
||||
|
||||
OnOpComplete(aRv, CacheAddAllResult());
|
||||
}
|
||||
|
||||
already_AddRefed<nsIInputStream>
|
||||
CacheOpParent::DeserializeCacheStream(const PCacheReadStreamOrVoid& aStreamOrVoid)
|
||||
{
|
||||
if (aStreamOrVoid.type() == PCacheReadStreamOrVoid::Tvoid_t) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
const PCacheReadStream& readStream = aStreamOrVoid.get_PCacheReadStream();
|
||||
|
||||
// Option 1: A push stream actor was sent for nsPipe data
|
||||
if (readStream.pushStreamParent()) {
|
||||
MOZ_ASSERT(!readStream.controlParent());
|
||||
CachePushStreamParent* pushStream =
|
||||
static_cast<CachePushStreamParent*>(readStream.pushStreamParent());
|
||||
stream = pushStream->TakeReader();
|
||||
MOZ_ASSERT(stream);
|
||||
return stream.forget();
|
||||
}
|
||||
|
||||
// Option 2: One of our own ReadStreams was passed back to us with a stream
|
||||
// control actor.
|
||||
stream = ReadStream::Create(readStream);
|
||||
if (stream) {
|
||||
return stream.forget();
|
||||
}
|
||||
|
||||
// Option 3: A stream was serialized using normal methods.
|
||||
nsAutoTArray<FileDescriptor, 4> fds;
|
||||
if (readStream.fds().type() ==
|
||||
OptionalFileDescriptorSet::TPFileDescriptorSetChild) {
|
||||
|
||||
FileDescriptorSetParent* fdSetActor =
|
||||
static_cast<FileDescriptorSetParent*>(readStream.fds().get_PFileDescriptorSetParent());
|
||||
MOZ_ASSERT(fdSetActor);
|
||||
|
||||
fdSetActor->ForgetFileDescriptors(fds);
|
||||
MOZ_ASSERT(!fds.IsEmpty());
|
||||
|
||||
if (!fdSetActor->Send__delete__(fdSetActor)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("Cache failed to delete fd set actor.");
|
||||
}
|
||||
}
|
||||
|
||||
return DeserializeInputStream(readStream.params(), fds);
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
87
dom/cache/CacheOpParent.h
vendored
87
dom/cache/CacheOpParent.h
vendored
@ -1,87 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_cache_CacheOpParent_h
|
||||
#define mozilla_dom_cache_CacheOpParent_h
|
||||
|
||||
#include "mozilla/dom/cache/FetchPut.h"
|
||||
#include "mozilla/dom/cache/Manager.h"
|
||||
#include "mozilla/dom/cache/PCacheOpParent.h"
|
||||
#include "mozilla/dom/cache/PrincipalVerifier.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
class PBackgroundParent;
|
||||
}
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
class CacheOpParent final : public PCacheOpParent
|
||||
, public PrincipalVerifier::Listener
|
||||
, public Manager::Listener
|
||||
, public FetchPut::Listener
|
||||
{
|
||||
// to allow use of convenience overrides
|
||||
using Manager::Listener::OnOpComplete;
|
||||
|
||||
public:
|
||||
CacheOpParent(mozilla::ipc::PBackgroundParent* aIpcManager, CacheId aCacheId,
|
||||
const CacheOpArgs& aOpArgs);
|
||||
CacheOpParent(mozilla::ipc::PBackgroundParent* aIpcManager,
|
||||
Namespace aNamespace, const CacheOpArgs& aOpArgs);
|
||||
~CacheOpParent();
|
||||
|
||||
void
|
||||
Execute(ManagerId* aManagerId);
|
||||
|
||||
void
|
||||
Execute(Manager* aManager);
|
||||
|
||||
void
|
||||
WaitForVerification(PrincipalVerifier* aVerifier);
|
||||
|
||||
private:
|
||||
// PCacheOpParent methods
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
// PrincipalVerifier::Listener methods
|
||||
virtual void
|
||||
OnPrincipalVerified(nsresult aRv, ManagerId* aManagerId) override;
|
||||
|
||||
// Manager::Listener methods
|
||||
virtual void
|
||||
OnOpComplete(nsresult aRv, const CacheOpResult& aResult,
|
||||
CacheId aOpenedCacheId,
|
||||
const nsTArray<SavedResponse>& aSavedResponseList,
|
||||
const nsTArray<SavedRequest>& aSavedRequestList,
|
||||
StreamList* aStreamList) override;
|
||||
|
||||
// FetchPut::Listener methods
|
||||
virtual void
|
||||
OnFetchPut(FetchPut* aFetchPut, nsresult aRv) override;
|
||||
|
||||
// utility methods
|
||||
already_AddRefed<nsIInputStream>
|
||||
DeserializeCacheStream(const PCacheReadStreamOrVoid& aStreamOrVoid);
|
||||
|
||||
mozilla::ipc::PBackgroundParent* mIpcManager;
|
||||
const CacheId mCacheId;
|
||||
const Namespace mNamespace;
|
||||
const CacheOpArgs mOpArgs;
|
||||
nsRefPtr<Manager> mManager;
|
||||
nsRefPtr<PrincipalVerifier> mVerifier;
|
||||
nsTArray<nsRefPtr<FetchPut>> mFetchPutList;
|
||||
|
||||
NS_DECL_OWNINGTHREAD
|
||||
};
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_cache_CacheOpParent_h
|
280
dom/cache/CacheParent.cpp
vendored
280
dom/cache/CacheParent.cpp
vendored
@ -6,14 +6,25 @@
|
||||
|
||||
#include "mozilla/dom/cache/CacheParent.h"
|
||||
|
||||
#include "mozilla/dom/cache/CacheOpParent.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/dom/cache/AutoUtils.h"
|
||||
#include "mozilla/dom/cache/CachePushStreamParent.h"
|
||||
#include "mozilla/dom/cache/CacheStreamControlParent.h"
|
||||
#include "mozilla/dom/cache/ReadStream.h"
|
||||
#include "mozilla/dom/cache/SavedTypes.h"
|
||||
#include "mozilla/dom/cache/StreamList.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "mozilla/ipc/PBackgroundParent.h"
|
||||
#include "mozilla/ipc/FileDescriptorSetParent.h"
|
||||
#include "mozilla/ipc/PFileDescriptorSetParent.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
using mozilla::ipc::FileDescriptorSetParent;
|
||||
using mozilla::ipc::PFileDescriptorSetParent;
|
||||
|
||||
// Declared in ActorUtils.h
|
||||
void
|
||||
@ -35,48 +46,22 @@ CacheParent::~CacheParent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(cache::CacheParent);
|
||||
MOZ_ASSERT(!mManager);
|
||||
MOZ_ASSERT(mFetchPutList.IsEmpty());
|
||||
}
|
||||
|
||||
void
|
||||
CacheParent::ActorDestroy(ActorDestroyReason aReason)
|
||||
{
|
||||
MOZ_ASSERT(mManager);
|
||||
for (uint32_t i = 0; i < mFetchPutList.Length(); ++i) {
|
||||
mFetchPutList[i]->ClearListener();
|
||||
}
|
||||
mFetchPutList.Clear();
|
||||
mManager->RemoveListener(this);
|
||||
mManager->ReleaseCacheId(mCacheId);
|
||||
mManager = nullptr;
|
||||
}
|
||||
|
||||
PCacheOpParent*
|
||||
CacheParent::AllocPCacheOpParent(const CacheOpArgs& aOpArgs)
|
||||
{
|
||||
if (aOpArgs.type() != CacheOpArgs::TCacheMatchArgs &&
|
||||
aOpArgs.type() != CacheOpArgs::TCacheMatchAllArgs &&
|
||||
aOpArgs.type() != CacheOpArgs::TCacheAddAllArgs &&
|
||||
aOpArgs.type() != CacheOpArgs::TCachePutAllArgs &&
|
||||
aOpArgs.type() != CacheOpArgs::TCacheDeleteArgs &&
|
||||
aOpArgs.type() != CacheOpArgs::TCacheKeysArgs)
|
||||
{
|
||||
MOZ_CRASH("Invalid operation sent to Cache actor!");
|
||||
}
|
||||
|
||||
return new CacheOpParent(Manager(), mCacheId, aOpArgs);
|
||||
}
|
||||
|
||||
bool
|
||||
CacheParent::DeallocPCacheOpParent(PCacheOpParent* aActor)
|
||||
{
|
||||
delete aActor;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheParent::RecvPCacheOpConstructor(PCacheOpParent* aActor,
|
||||
const CacheOpArgs& aOpArgs)
|
||||
{
|
||||
auto actor = static_cast<CacheOpParent*>(aActor);
|
||||
actor->Execute(mManager);
|
||||
return true;
|
||||
}
|
||||
|
||||
PCachePushStreamParent*
|
||||
CacheParent::AllocPCachePushStreamParent()
|
||||
{
|
||||
@ -100,6 +85,235 @@ CacheParent::RecvTeardown()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheParent::RecvMatch(const RequestId& aRequestId, const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams)
|
||||
{
|
||||
MOZ_ASSERT(mManager);
|
||||
mManager->CacheMatch(this, aRequestId, mCacheId, aRequest,
|
||||
aParams);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheParent::RecvMatchAll(const RequestId& aRequestId,
|
||||
const PCacheRequestOrVoid& aRequest,
|
||||
const PCacheQueryParams& aParams)
|
||||
{
|
||||
MOZ_ASSERT(mManager);
|
||||
mManager->CacheMatchAll(this, aRequestId, mCacheId, aRequest, aParams);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheParent::RecvAddAll(const RequestId& aRequestId,
|
||||
nsTArray<PCacheRequest>&& aRequests)
|
||||
{
|
||||
nsAutoTArray<nsCOMPtr<nsIInputStream>, 256> requestStreams;
|
||||
requestStreams.SetCapacity(aRequests.Length());
|
||||
|
||||
for (uint32_t i = 0; i < aRequests.Length(); ++i) {
|
||||
requestStreams.AppendElement(DeserializeCacheStream(aRequests[i].body()));
|
||||
}
|
||||
|
||||
nsRefPtr<FetchPut> fetchPut;
|
||||
nsresult rv = FetchPut::Create(this, mManager, aRequestId, mCacheId,
|
||||
aRequests, requestStreams,
|
||||
getter_AddRefs(fetchPut));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
if (!SendAddAllResponse(aRequestId, rv)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("Cache failed to send AddAll response.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
mFetchPutList.AppendElement(fetchPut.forget());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheParent::RecvPut(const RequestId& aRequestId,
|
||||
const CacheRequestResponse& aPut)
|
||||
{
|
||||
MOZ_ASSERT(mManager);
|
||||
|
||||
nsAutoTArray<CacheRequestResponse, 1> putList;
|
||||
putList.AppendElement(aPut);
|
||||
|
||||
nsAutoTArray<nsCOMPtr<nsIInputStream>, 1> requestStreamList;
|
||||
nsAutoTArray<nsCOMPtr<nsIInputStream>, 1> responseStreamList;
|
||||
|
||||
requestStreamList.AppendElement(
|
||||
DeserializeCacheStream(aPut.request().body()));
|
||||
responseStreamList.AppendElement(
|
||||
DeserializeCacheStream(aPut.response().body()));
|
||||
|
||||
|
||||
mManager->CachePutAll(this, aRequestId, mCacheId, putList, requestStreamList,
|
||||
responseStreamList);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheParent::RecvDelete(const RequestId& aRequestId,
|
||||
const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams)
|
||||
{
|
||||
MOZ_ASSERT(mManager);
|
||||
mManager->CacheDelete(this, aRequestId, mCacheId, aRequest, aParams);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheParent::RecvKeys(const RequestId& aRequestId,
|
||||
const PCacheRequestOrVoid& aRequest,
|
||||
const PCacheQueryParams& aParams)
|
||||
{
|
||||
MOZ_ASSERT(mManager);
|
||||
mManager->CacheKeys(this, aRequestId, mCacheId, aRequest, aParams);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CacheParent::OnCacheMatch(RequestId aRequestId, nsresult aRv,
|
||||
const SavedResponse* aSavedResponse,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
AutoParentResponseOrVoid response(Manager());
|
||||
|
||||
// no match
|
||||
if (NS_FAILED(aRv) || !aSavedResponse || !aStreamList) {
|
||||
if (!SendMatchResponse(aRequestId, aRv, response.SendAsResponseOrVoid())) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("Cache failed to send Match response.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (aSavedResponse) {
|
||||
response.Add(*aSavedResponse, aStreamList);
|
||||
}
|
||||
|
||||
if (!SendMatchResponse(aRequestId, aRv, response.SendAsResponseOrVoid())) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("Cache failed to send Match response.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheParent::OnCacheMatchAll(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<SavedResponse>& aSavedResponses,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
AutoParentResponseList responses(Manager(), aSavedResponses.Length());
|
||||
|
||||
for (uint32_t i = 0; i < aSavedResponses.Length(); ++i) {
|
||||
responses.Add(aSavedResponses[i], aStreamList);
|
||||
}
|
||||
|
||||
if (!SendMatchAllResponse(aRequestId, aRv, responses.SendAsResponseList())) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("Cache failed to send MatchAll response.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheParent::OnCachePutAll(RequestId aRequestId, nsresult aRv)
|
||||
{
|
||||
if (!SendPutResponse(aRequestId, aRv)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("Cache failed to send Put response.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheParent::OnCacheDelete(RequestId aRequestId, nsresult aRv, bool aSuccess)
|
||||
{
|
||||
if (!SendDeleteResponse(aRequestId, aRv, aSuccess)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("Cache failed to send Delete response.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheParent::OnCacheKeys(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<SavedRequest>& aSavedRequests,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
AutoParentRequestList requests(Manager(), aSavedRequests.Length());
|
||||
|
||||
for (uint32_t i = 0; i < aSavedRequests.Length(); ++i) {
|
||||
requests.Add(aSavedRequests[i], aStreamList);
|
||||
}
|
||||
|
||||
if (!SendKeysResponse(aRequestId, aRv, requests.SendAsRequestList())) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("Cache failed to send Keys response.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheParent::OnFetchPut(FetchPut* aFetchPut, RequestId aRequestId, nsresult aRv)
|
||||
{
|
||||
aFetchPut->ClearListener();
|
||||
mFetchPutList.RemoveElement(aFetchPut);
|
||||
if (!SendAddAllResponse(aRequestId, aRv)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("Cache failed to send AddAll response.");
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<nsIInputStream>
|
||||
CacheParent::DeserializeCacheStream(const PCacheReadStreamOrVoid& aStreamOrVoid)
|
||||
{
|
||||
if (aStreamOrVoid.type() == PCacheReadStreamOrVoid::Tvoid_t) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
const PCacheReadStream& readStream = aStreamOrVoid.get_PCacheReadStream();
|
||||
|
||||
// Option 1: A push stream actor was sent for nsPipe data
|
||||
if (readStream.pushStreamParent()) {
|
||||
MOZ_ASSERT(!readStream.controlParent());
|
||||
CachePushStreamParent* pushStream =
|
||||
static_cast<CachePushStreamParent*>(readStream.pushStreamParent());
|
||||
stream = pushStream->TakeReader();
|
||||
MOZ_ASSERT(stream);
|
||||
return stream.forget();
|
||||
}
|
||||
|
||||
// Option 2: One of our own ReadStreams was passed back to us with a stream
|
||||
// control actor.
|
||||
stream = ReadStream::Create(readStream);
|
||||
if (stream) {
|
||||
return stream.forget();
|
||||
}
|
||||
|
||||
// Option 3: A stream was serialized using normal methods.
|
||||
nsAutoTArray<FileDescriptor, 4> fds;
|
||||
if (readStream.fds().type() ==
|
||||
OptionalFileDescriptorSet::TPFileDescriptorSetChild) {
|
||||
|
||||
FileDescriptorSetParent* fdSetActor =
|
||||
static_cast<FileDescriptorSetParent*>(readStream.fds().get_PFileDescriptorSetParent());
|
||||
MOZ_ASSERT(fdSetActor);
|
||||
|
||||
fdSetActor->ForgetFileDescriptors(fds);
|
||||
MOZ_ASSERT(!fds.IsEmpty());
|
||||
|
||||
if (!fdSetActor->Send__delete__(fdSetActor)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("Cache failed to delete fd set actor.");
|
||||
}
|
||||
}
|
||||
|
||||
return DeserializeInputStream(readStream.params(), fds);
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namesapce mozilla
|
||||
|
65
dom/cache/CacheParent.h
vendored
65
dom/cache/CacheParent.h
vendored
@ -7,46 +7,77 @@
|
||||
#ifndef mozilla_dom_cache_CacheParent_h
|
||||
#define mozilla_dom_cache_CacheParent_h
|
||||
|
||||
#include "mozilla/dom/cache/FetchPut.h"
|
||||
#include "mozilla/dom/cache/Manager.h"
|
||||
#include "mozilla/dom/cache/PCacheParent.h"
|
||||
#include "mozilla/dom/cache/Types.h"
|
||||
|
||||
struct nsID;
|
||||
template <class T> class nsRefPtr;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
class Manager;
|
||||
struct SavedResponse;
|
||||
|
||||
class CacheParent final : public PCacheParent
|
||||
, public Manager::Listener
|
||||
, public FetchPut::Listener
|
||||
{
|
||||
public:
|
||||
CacheParent(cache::Manager* aManager, CacheId aCacheId);
|
||||
virtual ~CacheParent();
|
||||
|
||||
private:
|
||||
// PCacheParent methods
|
||||
// PCacheParent method
|
||||
virtual void ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
virtual PCacheOpParent*
|
||||
AllocPCacheOpParent(const CacheOpArgs& aOpArgs) override;
|
||||
|
||||
virtual PCachePushStreamParent* AllocPCachePushStreamParent() override;
|
||||
virtual bool DeallocPCachePushStreamParent(PCachePushStreamParent* aActor) override;
|
||||
virtual bool RecvTeardown() override;
|
||||
virtual bool
|
||||
DeallocPCacheOpParent(PCacheOpParent* aActor) override;
|
||||
|
||||
RecvMatch(const RequestId& aRequestId, const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams) override;
|
||||
virtual bool
|
||||
RecvPCacheOpConstructor(PCacheOpParent* actor,
|
||||
const CacheOpArgs& aOpArgs) override;
|
||||
|
||||
virtual PCachePushStreamParent*
|
||||
AllocPCachePushStreamParent() override;
|
||||
|
||||
RecvMatchAll(const RequestId& aRequestId, const PCacheRequestOrVoid& aRequest,
|
||||
const PCacheQueryParams& aParams) override;
|
||||
virtual bool
|
||||
DeallocPCachePushStreamParent(PCachePushStreamParent* aActor) override;
|
||||
|
||||
RecvAddAll(const RequestId& aRequestId,
|
||||
nsTArray<PCacheRequest>&& aRequests) override;
|
||||
virtual bool
|
||||
RecvTeardown() override;
|
||||
RecvPut(const RequestId& aRequestId,
|
||||
const CacheRequestResponse& aPut) override;
|
||||
virtual bool
|
||||
RecvDelete(const RequestId& aRequestId, const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams) override;
|
||||
virtual bool
|
||||
RecvKeys(const RequestId& aRequestId, const PCacheRequestOrVoid& aRequest,
|
||||
const PCacheQueryParams& aParams) override;
|
||||
|
||||
// Manager::Listener methods
|
||||
virtual void OnCacheMatch(RequestId aRequestId, nsresult aRv,
|
||||
const SavedResponse* aSavedResponse,
|
||||
StreamList* aStreamList) override;
|
||||
virtual void OnCacheMatchAll(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<SavedResponse>& aSavedResponses,
|
||||
StreamList* aStreamList) override;
|
||||
virtual void OnCachePutAll(RequestId aRequestId, nsresult aRv) override;
|
||||
virtual void OnCacheDelete(RequestId aRequestId, nsresult aRv,
|
||||
bool aSuccess) override;
|
||||
virtual void OnCacheKeys(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<SavedRequest>& aSavedRequests,
|
||||
StreamList* aStreamList) override;
|
||||
|
||||
// FetchPut::Listener methods
|
||||
virtual void OnFetchPut(FetchPut* aFetchPut, RequestId aRequestId,
|
||||
nsresult aRv) override;
|
||||
|
||||
already_AddRefed<nsIInputStream>
|
||||
DeserializeCacheStream(const PCacheReadStreamOrVoid& aStreamOrVoid);
|
||||
|
||||
nsRefPtr<cache::Manager> mManager;
|
||||
const CacheId mCacheId;
|
||||
nsTArray<nsRefPtr<FetchPut>> mFetchPutList;
|
||||
};
|
||||
|
||||
} // namespace cache
|
||||
|
370
dom/cache/CacheStorage.cpp
vendored
370
dom/cache/CacheStorage.cpp
vendored
@ -13,7 +13,6 @@
|
||||
#include "mozilla/dom/cache/AutoUtils.h"
|
||||
#include "mozilla/dom/cache/Cache.h"
|
||||
#include "mozilla/dom/cache/CacheChild.h"
|
||||
#include "mozilla/dom/cache/CacheOpChild.h"
|
||||
#include "mozilla/dom/cache/CacheStorageChild.h"
|
||||
#include "mozilla/dom/cache/Feature.h"
|
||||
#include "mozilla/dom/cache/PCacheChild.h"
|
||||
@ -42,26 +41,24 @@ using mozilla::ipc::PrincipalToPrincipalInfo;
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(mozilla::dom::cache::CacheStorage);
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(mozilla::dom::cache::CacheStorage);
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(mozilla::dom::cache::CacheStorage,
|
||||
mGlobal);
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(mozilla::dom::cache::CacheStorage)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(mozilla::dom::cache::CacheStorage)
|
||||
tmp->DisconnectFromActor();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal, mRequestPromises)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(mozilla::dom::cache::CacheStorage)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal, mRequestPromises)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_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_AMBIGUOUS(nsISupports, nsIIPCBackgroundChildCreateCallback)
|
||||
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.
|
||||
struct CacheStorage::Entry final
|
||||
{
|
||||
nsRefPtr<Promise> mPromise;
|
||||
CacheOpArgs mArgs;
|
||||
// We cannot add the requests until after the actor is present. So store
|
||||
// the request data separately for now.
|
||||
nsRefPtr<InternalRequest> mRequest;
|
||||
};
|
||||
|
||||
// static
|
||||
already_AddRefed<CacheStorage>
|
||||
CacheStorage::CreateOnMainThread(Namespace aNamespace, nsIGlobalObject* aGlobal,
|
||||
@ -178,31 +175,29 @@ CacheStorage::Match(const RequestOrUSVString& aRequest,
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
if (mFailedActor) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<InternalRequest> request = ToInternalRequest(aRequest, IgnoreBody,
|
||||
aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PCacheQueryParams params;
|
||||
ToPCacheQueryParams(params, aOptions);
|
||||
if (mFailedActor) {
|
||||
promise->MaybeReject(NS_ERROR_UNEXPECTED);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
nsAutoPtr<Entry> entry(new Entry());
|
||||
entry->mPromise = promise;
|
||||
entry->mArgs = StorageMatchArgs(PCacheRequest(), params);
|
||||
entry->mRequest = request;
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
Entry entry;
|
||||
entry.mRequestId = requestId;
|
||||
entry.mOp = OP_MATCH;
|
||||
entry.mOptions = aOptions;
|
||||
entry.mRequest = ToInternalRequest(aRequest, IgnoreBody, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mPendingRequests.AppendElement(entry);
|
||||
|
||||
mPendingRequests.AppendElement(entry.forget());
|
||||
MaybeRunPendingRequests();
|
||||
|
||||
return promise.forget();
|
||||
@ -213,21 +208,23 @@ CacheStorage::Has(const nsAString& aKey, ErrorResult& aRv)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
if (mFailedActor) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsAutoPtr<Entry> entry(new Entry());
|
||||
entry->mPromise = promise;
|
||||
entry->mArgs = StorageHasArgs(nsString(aKey));
|
||||
if (mFailedActor) {
|
||||
promise->MaybeReject(NS_ERROR_UNEXPECTED);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
Entry* entry = mPendingRequests.AppendElement();
|
||||
entry->mRequestId = requestId;
|
||||
entry->mOp = OP_HAS;
|
||||
entry->mKey = aKey;
|
||||
|
||||
mPendingRequests.AppendElement(entry.forget());
|
||||
MaybeRunPendingRequests();
|
||||
|
||||
return promise.forget();
|
||||
@ -238,21 +235,23 @@ CacheStorage::Open(const nsAString& aKey, ErrorResult& aRv)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
if (mFailedActor) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsAutoPtr<Entry> entry(new Entry());
|
||||
entry->mPromise = promise;
|
||||
entry->mArgs = StorageOpenArgs(nsString(aKey));
|
||||
if (mFailedActor) {
|
||||
promise->MaybeReject(NS_ERROR_UNEXPECTED);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
Entry* entry = mPendingRequests.AppendElement();
|
||||
entry->mRequestId = requestId;
|
||||
entry->mOp = OP_OPEN;
|
||||
entry->mKey = aKey;
|
||||
|
||||
mPendingRequests.AppendElement(entry.forget());
|
||||
MaybeRunPendingRequests();
|
||||
|
||||
return promise.forget();
|
||||
@ -263,21 +262,23 @@ CacheStorage::Delete(const nsAString& aKey, ErrorResult& aRv)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
if (mFailedActor) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsAutoPtr<Entry> entry(new Entry());
|
||||
entry->mPromise = promise;
|
||||
entry->mArgs = StorageDeleteArgs(nsString(aKey));
|
||||
if (mFailedActor) {
|
||||
promise->MaybeReject(NS_ERROR_UNEXPECTED);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
Entry* entry = mPendingRequests.AppendElement();
|
||||
entry->mRequestId = requestId;
|
||||
entry->mOp = OP_DELETE;
|
||||
entry->mKey = aKey;
|
||||
|
||||
mPendingRequests.AppendElement(entry.forget());
|
||||
MaybeRunPendingRequests();
|
||||
|
||||
return promise.forget();
|
||||
@ -288,21 +289,22 @@ CacheStorage::Keys(ErrorResult& aRv)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
if (mFailedActor) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsAutoPtr<Entry> entry(new Entry());
|
||||
entry->mPromise = promise;
|
||||
entry->mArgs = StorageKeysArgs();
|
||||
if (mFailedActor) {
|
||||
promise->MaybeReject(NS_ERROR_UNEXPECTED);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
Entry* entry = mPendingRequests.AppendElement();
|
||||
entry->mRequestId = requestId;
|
||||
entry->mOp = OP_KEYS;
|
||||
|
||||
mPendingRequests.AppendElement(entry.forget());
|
||||
MaybeRunPendingRequests();
|
||||
|
||||
return promise.forget();
|
||||
@ -369,8 +371,9 @@ CacheStorage::ActorFailed()
|
||||
mFeature = nullptr;
|
||||
|
||||
for (uint32_t i = 0; i < mPendingRequests.Length(); ++i) {
|
||||
nsAutoPtr<Entry> entry(mPendingRequests[i].forget());
|
||||
entry->mPromise->MaybeReject(NS_ERROR_UNEXPECTED);
|
||||
RequestId requestId = mPendingRequests[i].mRequestId;
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(requestId);
|
||||
promise->MaybeReject(NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
mPendingRequests.Clear();
|
||||
}
|
||||
@ -389,6 +392,117 @@ CacheStorage::DestroyInternal(CacheStorageChild* aActor)
|
||||
ActorFailed();
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorage::RecvMatchResponse(RequestId aRequestId, nsresult aRv,
|
||||
const PCacheResponseOrVoid& aResponse)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
// Convert the response immediately if its present. This ensures that
|
||||
// any stream actors are cleaned up, even if we error out below.
|
||||
nsRefPtr<Response> response;
|
||||
if (aResponse.type() == PCacheResponseOrVoid::TPCacheResponse) {
|
||||
response = ToResponse(aResponse);
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
// If cache name was specified in the request options and the cache does
|
||||
// not exist, then an error code will already have been set. If we
|
||||
// still do not have a response, then we just resolve undefined like a
|
||||
// normal Cache::Match.
|
||||
if (!response) {
|
||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
return;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(response);
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorage::RecvHasResponse(RequestId aRequestId, nsresult aRv, bool aSuccess)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
promise->MaybeResolve(aSuccess);
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorage::RecvOpenResponse(RequestId aRequestId, nsresult aRv,
|
||||
CacheChild* aActor)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
// Unlike most of our async callback Recv*() methods, this one gets back
|
||||
// an actor. We need to make sure to clean it up in case of error.
|
||||
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
if (aActor) {
|
||||
// We cannot use the CacheChild::StartDestroy() method because there
|
||||
// is no Cache object associated with the actor yet. Instead, just
|
||||
// send the underlying Teardown message.
|
||||
unused << aActor->SendTeardown();
|
||||
}
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!aActor) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<Cache> cache = new Cache(mGlobal, aActor);
|
||||
promise->MaybeResolve(cache);
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorage::RecvDeleteResponse(RequestId aRequestId, nsresult aRv,
|
||||
bool aSuccess)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(aSuccess);
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorage::RecvKeysResponse(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<nsString>& aKeys)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(aKeys);
|
||||
}
|
||||
|
||||
nsIGlobalObject*
|
||||
CacheStorage::GetGlobalObject() const
|
||||
{
|
||||
@ -410,9 +524,32 @@ CacheStorage::CreatePushStream(nsIAsyncInputStream* aStream)
|
||||
MOZ_CRASH("CacheStorage should never create a push stream.");
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorage::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
|
||||
{
|
||||
// Do nothing. The Promise will automatically drop the ref to us after
|
||||
// calling the callback. This is what we want as we only registered in order
|
||||
// to be held alive via the Promise handle.
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorage::RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
|
||||
{
|
||||
// Do nothing. The Promise will automatically drop the ref to us after
|
||||
// calling the callback. This is what we want as we only registered in order
|
||||
// to be held alive via the Promise handle.
|
||||
}
|
||||
|
||||
CacheStorage::~CacheStorage()
|
||||
{
|
||||
DisconnectFromActor();
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorage::DisconnectFromActor()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
if (mActor) {
|
||||
mActor->StartDestroy();
|
||||
// DestroyInternal() is called synchronously by StartDestroy(). So we
|
||||
@ -429,24 +566,89 @@ CacheStorage::MaybeRunPendingRequests()
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mPendingRequests.Length(); ++i) {
|
||||
ErrorResult rv;
|
||||
nsAutoPtr<Entry> entry(mPendingRequests[i].forget());
|
||||
AutoChildOpArgs args(this, entry->mArgs);
|
||||
if (entry->mRequest) {
|
||||
args.Add(entry->mRequest, IgnoreBody, PassThroughReferrer,
|
||||
IgnoreInvalidScheme, rv);
|
||||
// Note, the entry can be modified below due to Request/Response body
|
||||
// being marked used.
|
||||
Entry& entry = mPendingRequests[i];
|
||||
RequestId requestId = entry.mRequestId;
|
||||
switch(entry.mOp) {
|
||||
case OP_MATCH:
|
||||
{
|
||||
AutoChildRequest request(this);
|
||||
ErrorResult rv;
|
||||
request.Add(entry.mRequest, IgnoreBody, PassThroughReferrer,
|
||||
IgnoreInvalidScheme, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(requestId);
|
||||
promise->MaybeReject(rv);
|
||||
break;
|
||||
}
|
||||
|
||||
PCacheQueryParams params;
|
||||
ToPCacheQueryParams(params, entry.mOptions);
|
||||
|
||||
unused << mActor->SendMatch(requestId, request.SendAsRequest(), params);
|
||||
break;
|
||||
}
|
||||
case OP_HAS:
|
||||
unused << mActor->SendHas(requestId, entry.mKey);
|
||||
break;
|
||||
case OP_OPEN:
|
||||
unused << mActor->SendOpen(requestId, entry.mKey);
|
||||
break;
|
||||
case OP_DELETE:
|
||||
unused << mActor->SendDelete(requestId, entry.mKey);
|
||||
break;
|
||||
case OP_KEYS:
|
||||
unused << mActor->SendKeys(requestId);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown pending CacheStorage op.");
|
||||
}
|
||||
if (rv.Failed()) {
|
||||
entry->mPromise->MaybeReject(rv);
|
||||
continue;
|
||||
}
|
||||
unused << mActor->SendPCacheOpConstructor(
|
||||
new CacheOpChild(mActor->GetFeature(), mGlobal, this, entry->mPromise),
|
||||
args.SendAsOpArgs());
|
||||
}
|
||||
mPendingRequests.Clear();
|
||||
}
|
||||
|
||||
RequestId
|
||||
CacheStorage::AddRequestPromise(Promise* aPromise, ErrorResult& aRv)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
MOZ_ASSERT(aPromise);
|
||||
MOZ_ASSERT(!mRequestPromises.Contains(aPromise));
|
||||
|
||||
// Register ourself as a promise handler so that the promise will hold us
|
||||
// alive. This allows the client code to drop the ref to the CacheStorage
|
||||
// object and just keep their promise. This is fairly common in promise
|
||||
// chaining code.
|
||||
aPromise->AppendNativeHandler(this);
|
||||
|
||||
mRequestPromises.AppendElement(aPromise);
|
||||
|
||||
// (Ab)use the promise pointer as our request ID. This is a fast, thread-safe
|
||||
// way to get a unique ID for the promise to be resolved later.
|
||||
return reinterpret_cast<RequestId>(aPromise);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
CacheStorage::RemoveRequestPromise(RequestId aRequestId)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
MOZ_ASSERT(aRequestId != INVALID_REQUEST_ID);
|
||||
|
||||
for (uint32_t i = 0; i < mRequestPromises.Length(); ++i) {
|
||||
nsRefPtr<Promise>& promise = mRequestPromises.ElementAt(i);
|
||||
// To be safe, only cast promise pointers to our integer RequestId
|
||||
// type and never cast an integer to a pointer.
|
||||
if (aRequestId == reinterpret_cast<RequestId>(promise.get())) {
|
||||
nsRefPtr<Promise> ref;
|
||||
ref.swap(promise);
|
||||
mRequestPromises.RemoveElementAt(i);
|
||||
return ref.forget();
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT_UNREACHABLE("Received response without a matching promise!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
56
dom/cache/CacheStorage.h
vendored
56
dom/cache/CacheStorage.h
vendored
@ -8,6 +8,7 @@
|
||||
#define mozilla_dom_cache_CacheStorage_h
|
||||
|
||||
#include "mozilla/dom/CacheBinding.h"
|
||||
#include "mozilla/dom/PromiseNativeHandler.h"
|
||||
#include "mozilla/dom/cache/Types.h"
|
||||
#include "mozilla/dom/cache/TypeUtils.h"
|
||||
#include "nsAutoPtr.h"
|
||||
@ -45,6 +46,7 @@ class PCacheResponseOrVoid;
|
||||
class CacheStorage final : public nsIIPCBackgroundChildCreateCallback
|
||||
, public nsWrapperCache
|
||||
, public TypeUtils
|
||||
, public PromiseNativeHandler
|
||||
{
|
||||
typedef mozilla::ipc::PBackgroundChild PBackgroundChild;
|
||||
|
||||
@ -79,6 +81,16 @@ public:
|
||||
// Called when CacheStorageChild actor is being destroyed
|
||||
void DestroyInternal(CacheStorageChild* aActor);
|
||||
|
||||
// Methods forwarded from CacheStorageChild
|
||||
void RecvMatchResponse(RequestId aRequestId, nsresult aRv,
|
||||
const PCacheResponseOrVoid& aResponse);
|
||||
void RecvHasResponse(RequestId aRequestId, nsresult aRv, bool aSuccess);
|
||||
void RecvOpenResponse(RequestId aRequestId, nsresult aRv,
|
||||
CacheChild* aActor);
|
||||
void RecvDeleteResponse(RequestId aRequestId, nsresult aRv, bool aSuccess);
|
||||
void RecvKeysResponse(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<nsString>& aKeys);
|
||||
|
||||
// TypeUtils methods
|
||||
virtual nsIGlobalObject* GetGlobalObject() const override;
|
||||
#ifdef DEBUG
|
||||
@ -88,24 +100,60 @@ public:
|
||||
virtual CachePushStreamChild*
|
||||
CreatePushStream(nsIAsyncInputStream* aStream) override;
|
||||
|
||||
// PromiseNativeHandler methods
|
||||
virtual void
|
||||
ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
|
||||
|
||||
virtual void
|
||||
RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
|
||||
|
||||
private:
|
||||
CacheStorage(Namespace aNamespace, nsIGlobalObject* aGlobal,
|
||||
const mozilla::ipc::PrincipalInfo& aPrincipalInfo, Feature* aFeature);
|
||||
~CacheStorage();
|
||||
|
||||
// Called when we're destroyed or CCed.
|
||||
void DisconnectFromActor();
|
||||
|
||||
void MaybeRunPendingRequests();
|
||||
|
||||
RequestId AddRequestPromise(Promise* aPromise, ErrorResult& aRv);
|
||||
already_AddRefed<Promise> RemoveRequestPromise(RequestId aRequestId);
|
||||
|
||||
// Would like to use CacheInitData here, but we cannot because
|
||||
// its an IPC struct which breaks webidl by including windows.h.
|
||||
const Namespace mNamespace;
|
||||
nsCOMPtr<nsIGlobalObject> mGlobal;
|
||||
UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
|
||||
nsRefPtr<Feature> mFeature;
|
||||
|
||||
// weak ref cleared in DestroyInternal
|
||||
CacheStorageChild* mActor;
|
||||
nsTArray<nsRefPtr<Promise>> mRequestPromises;
|
||||
|
||||
struct Entry;
|
||||
nsTArray<nsAutoPtr<Entry>> mPendingRequests;
|
||||
enum Op
|
||||
{
|
||||
OP_MATCH,
|
||||
OP_HAS,
|
||||
OP_OPEN,
|
||||
OP_DELETE,
|
||||
OP_KEYS
|
||||
};
|
||||
|
||||
struct Entry
|
||||
{
|
||||
RequestId mRequestId;
|
||||
Op mOp;
|
||||
// Would prefer to use PCacheRequest/PCacheCacheQueryOptions, but can't
|
||||
// because they introduce a header dependency on windows.h which
|
||||
// breaks the bindings build.
|
||||
nsRefPtr<InternalRequest> mRequest;
|
||||
CacheQueryOptions mOptions;
|
||||
// It would also be nice to union the key with the match args above,
|
||||
// but VS2013 doesn't like these types in unions because of copy
|
||||
// constructors.
|
||||
nsString mKey;
|
||||
};
|
||||
|
||||
nsTArray<Entry> mPendingRequests;
|
||||
bool mFailedActor;
|
||||
|
||||
public:
|
||||
|
89
dom/cache/CacheStorageChild.cpp
vendored
89
dom/cache/CacheStorageChild.cpp
vendored
@ -9,7 +9,6 @@
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/dom/cache/CacheChild.h"
|
||||
#include "mozilla/dom/cache/CacheStorage.h"
|
||||
#include "mozilla/dom/cache/PCacheOpChild.h"
|
||||
#include "mozilla/dom/cache/StreamUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -61,8 +60,6 @@ CacheStorageChild::StartDestroy()
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: don't destroy if we have outstanding ops
|
||||
|
||||
listener->DestroyInternal(this);
|
||||
|
||||
// CacheStorage listener should call ClearListener() in DestroyInternal()
|
||||
@ -86,17 +83,91 @@ CacheStorageChild::ActorDestroy(ActorDestroyReason aReason)
|
||||
RemoveFeature();
|
||||
}
|
||||
|
||||
PCacheOpChild*
|
||||
CacheStorageChild::AllocPCacheOpChild(const CacheOpArgs& aOpArgs)
|
||||
bool
|
||||
CacheStorageChild::RecvMatchResponse(const RequestId& aRequestId,
|
||||
const nsresult& aRv,
|
||||
const PCacheResponseOrVoid& aResponseOrVoid)
|
||||
{
|
||||
MOZ_CRASH("CacheOpChild should be manually constructed.");
|
||||
return nullptr;
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorageChild);
|
||||
|
||||
AddFeatureToStreamChild(aResponseOrVoid, GetFeature());
|
||||
|
||||
nsRefPtr<CacheStorage> listener = mListener;
|
||||
if (!listener) {
|
||||
StartDestroyStreamChild(aResponseOrVoid);
|
||||
return true;
|
||||
}
|
||||
|
||||
listener->RecvMatchResponse(aRequestId, aRv, aResponseOrVoid);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageChild::DeallocPCacheOpChild(PCacheOpChild* aActor)
|
||||
CacheStorageChild::RecvHasResponse(const RequestId& aRequestId,
|
||||
const nsresult& aRv,
|
||||
const bool& aSuccess)
|
||||
{
|
||||
delete aActor;
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorageChild);
|
||||
nsRefPtr<CacheStorage> listener = mListener;
|
||||
if (listener) {
|
||||
listener->RecvHasResponse(aRequestId, aRv, aSuccess);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageChild::RecvOpenResponse(const RequestId& aRequestId,
|
||||
const nsresult& aRv,
|
||||
PCacheChild* aActor)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorageChild);
|
||||
|
||||
nsRefPtr<CacheStorage> listener = mListener;
|
||||
if (!listener || FeatureNotified()) {
|
||||
if (aActor) {
|
||||
unused << aActor->SendTeardown();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CacheChild* cacheChild = static_cast<CacheChild*>(aActor);
|
||||
|
||||
// Since FeatureNotified() returned false above, we are guaranteed that
|
||||
// the feature won't try to shutdown the actor until after we create the
|
||||
// Cache DOM object in the listener's RecvOpenResponse() method. This
|
||||
// is important because StartShutdown() expects a Cache object listener.
|
||||
if (cacheChild) {
|
||||
cacheChild->SetFeature(GetFeature());
|
||||
}
|
||||
|
||||
listener->RecvOpenResponse(aRequestId, aRv, cacheChild);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageChild::RecvDeleteResponse(const RequestId& aRequestId,
|
||||
const nsresult& aRv,
|
||||
const bool& aResult)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorageChild);
|
||||
nsRefPtr<CacheStorage> listener = mListener;
|
||||
if (listener) {
|
||||
listener->RecvDeleteResponse(aRequestId, aRv, aResult);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageChild::RecvKeysResponse(const RequestId& aRequestId,
|
||||
const nsresult& aRv,
|
||||
nsTArray<nsString>&& aKeys)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorageChild);
|
||||
nsRefPtr<CacheStorage> listener = mListener;
|
||||
if (listener) {
|
||||
listener->RecvKeysResponse(aRequestId, aRv, aKeys);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
22
dom/cache/CacheStorageChild.h
vendored
22
dom/cache/CacheStorageChild.h
vendored
@ -27,7 +27,7 @@ public:
|
||||
~CacheStorageChild();
|
||||
|
||||
// Must be called by the associated CacheStorage listener in its
|
||||
// ActorDestroy() method. Also, CacheStorage must call SendDestroy() on the
|
||||
// ActorDestroy() method. Also, CacheStorage must Send__delete__() the
|
||||
// actor in its destructor to trigger ActorDestroy() if it has not been
|
||||
// called yet.
|
||||
void ClearListener();
|
||||
@ -42,11 +42,21 @@ private:
|
||||
// PCacheStorageChild methods
|
||||
virtual void ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
virtual PCacheOpChild*
|
||||
AllocPCacheOpChild(const CacheOpArgs& aOpArgs) override;
|
||||
|
||||
virtual bool
|
||||
DeallocPCacheOpChild(PCacheOpChild* aActor) override;
|
||||
virtual bool RecvMatchResponse(const RequestId& aRequestId,
|
||||
const nsresult& aRv,
|
||||
const PCacheResponseOrVoid& response) override;
|
||||
virtual bool RecvHasResponse(const cache::RequestId& aRequestId,
|
||||
const nsresult& aRv,
|
||||
const bool& aSuccess) override;
|
||||
virtual bool RecvOpenResponse(const cache::RequestId& aRequestId,
|
||||
const nsresult& aRv,
|
||||
PCacheChild* aActor) override;
|
||||
virtual bool RecvDeleteResponse(const cache::RequestId& aRequestId,
|
||||
const nsresult& aRv,
|
||||
const bool& aResult) override;
|
||||
virtual bool RecvKeysResponse(const cache::RequestId& aRequestId,
|
||||
const nsresult& aRv,
|
||||
nsTArray<nsString>&& aKeys) override;
|
||||
|
||||
// Use a weak ref so actor does not hold DOM object alive past content use.
|
||||
// The CacheStorage object must call ClearListener() to null this before its
|
||||
|
401
dom/cache/CacheStorageParent.cpp
vendored
401
dom/cache/CacheStorageParent.cpp
vendored
@ -6,18 +6,28 @@
|
||||
|
||||
#include "mozilla/dom/cache/CacheStorageParent.h"
|
||||
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/cache/ActorUtils.h"
|
||||
#include "mozilla/dom/cache/CacheOpParent.h"
|
||||
#include "mozilla/dom/cache/AutoUtils.h"
|
||||
#include "mozilla/dom/cache/CacheParent.h"
|
||||
#include "mozilla/dom/cache/CacheStreamControlParent.h"
|
||||
#include "mozilla/dom/cache/Manager.h"
|
||||
#include "mozilla/dom/cache/ManagerId.h"
|
||||
#include "mozilla/dom/cache/ReadStream.h"
|
||||
#include "mozilla/dom/cache/SavedTypes.h"
|
||||
#include "mozilla/dom/cache/StreamList.h"
|
||||
#include "mozilla/ipc/PBackgroundParent.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "mozilla/ipc/PFileDescriptorSetParent.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
using mozilla::ipc::PBackgroundParent;
|
||||
using mozilla::ipc::PFileDescriptorSetParent;
|
||||
using mozilla::ipc::PrincipalInfo;
|
||||
|
||||
// declared in ActorUtils.h
|
||||
@ -55,59 +65,22 @@ CacheStorageParent::~CacheStorageParent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(cache::CacheStorageParent);
|
||||
MOZ_ASSERT(!mVerifier);
|
||||
MOZ_ASSERT(!mManager);
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorageParent::ActorDestroy(ActorDestroyReason aReason)
|
||||
{
|
||||
if (mVerifier) {
|
||||
mVerifier->RemoveListener(this);
|
||||
mVerifier->ClearListener();
|
||||
mVerifier = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
PCacheOpParent*
|
||||
CacheStorageParent::AllocPCacheOpParent(const CacheOpArgs& aOpArgs)
|
||||
{
|
||||
if (aOpArgs.type() != CacheOpArgs::TStorageMatchArgs &&
|
||||
aOpArgs.type() != CacheOpArgs::TStorageHasArgs &&
|
||||
aOpArgs.type() != CacheOpArgs::TStorageOpenArgs &&
|
||||
aOpArgs.type() != CacheOpArgs::TStorageDeleteArgs &&
|
||||
aOpArgs.type() != CacheOpArgs::TStorageKeysArgs)
|
||||
{
|
||||
MOZ_CRASH("Invalid operation sent to CacheStorage actor!");
|
||||
if (mManager) {
|
||||
MOZ_ASSERT(!mActiveRequests.IsEmpty());
|
||||
mManager->RemoveListener(this);
|
||||
mManager = nullptr;
|
||||
}
|
||||
|
||||
return new CacheOpParent(Manager(), mNamespace, aOpArgs);
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageParent::DeallocPCacheOpParent(PCacheOpParent* aActor)
|
||||
{
|
||||
delete aActor;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageParent::RecvPCacheOpConstructor(PCacheOpParent* aActor,
|
||||
const CacheOpArgs& aOpArgs)
|
||||
{
|
||||
auto actor = static_cast<CacheOpParent*>(aActor);
|
||||
|
||||
if (mVerifier) {
|
||||
MOZ_ASSERT(!mManagerId);
|
||||
actor->WaitForVerification(mVerifier);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (NS_FAILED(mVerifiedStatus)) {
|
||||
unused << CacheOpParent::Send__delete__(actor, mVerifiedStatus, void_t());
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mManagerId);
|
||||
actor->Execute(mManagerId);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -120,11 +93,190 @@ CacheStorageParent::RecvTeardown()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageParent::RecvMatch(const RequestId& aRequestId,
|
||||
const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams)
|
||||
{
|
||||
if (NS_WARN_IF(NS_FAILED(mVerifiedStatus))) {
|
||||
if (!SendMatchResponse(aRequestId, mVerifiedStatus, void_t())) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Match response.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// queue requests if we are still waiting for principal verification
|
||||
if (!mManagerId) {
|
||||
Entry* entry = mPendingRequests.AppendElement();
|
||||
entry->mOp = OP_MATCH;
|
||||
entry->mRequestId = aRequestId;
|
||||
entry->mRequest = aRequest;
|
||||
entry->mParams = aParams;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<cache::Manager> manager;
|
||||
nsresult rv = RequestManager(aRequestId, getter_AddRefs(manager));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
if (!SendMatchResponse(aRequestId, rv, void_t())) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Match response.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
manager->StorageMatch(this, aRequestId, mNamespace, aRequest,
|
||||
aParams);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageParent::RecvHas(const RequestId& aRequestId, const nsString& aKey)
|
||||
{
|
||||
if (NS_WARN_IF(NS_FAILED(mVerifiedStatus))) {
|
||||
if (!SendHasResponse(aRequestId, mVerifiedStatus, false)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Has response.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// queue requests if we are still waiting for principal verification
|
||||
if (!mManagerId) {
|
||||
Entry* entry = mPendingRequests.AppendElement();
|
||||
entry->mOp = OP_HAS;
|
||||
entry->mRequestId = aRequestId;
|
||||
entry->mKey = aKey;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<cache::Manager> manager;
|
||||
nsresult rv = RequestManager(aRequestId, getter_AddRefs(manager));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
if (!SendHasResponse(aRequestId, rv, false)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Has response.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
manager->StorageHas(this, aRequestId, mNamespace, aKey);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageParent::RecvOpen(const RequestId& aRequestId, const nsString& aKey)
|
||||
{
|
||||
if (NS_WARN_IF(NS_FAILED(mVerifiedStatus))) {
|
||||
if (!SendOpenResponse(aRequestId, mVerifiedStatus, nullptr)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Open response.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// queue requests if we are still waiting for principal verification
|
||||
if (!mManagerId) {
|
||||
Entry* entry = mPendingRequests.AppendElement();
|
||||
entry->mOp = OP_OPEN;
|
||||
entry->mRequestId = aRequestId;
|
||||
entry->mKey = aKey;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<cache::Manager> manager;
|
||||
nsresult rv = RequestManager(aRequestId, getter_AddRefs(manager));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
if (!SendOpenResponse(aRequestId, rv, nullptr)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Open response.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
manager->StorageOpen(this, aRequestId, mNamespace, aKey);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageParent::RecvDelete(const RequestId& aRequestId,
|
||||
const nsString& aKey)
|
||||
{
|
||||
if (NS_WARN_IF(NS_FAILED(mVerifiedStatus))) {
|
||||
if (!SendDeleteResponse(aRequestId, mVerifiedStatus, false)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Delete response.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// queue requests if we are still waiting for principal verification
|
||||
if (!mManagerId) {
|
||||
Entry* entry = mPendingRequests.AppendElement();
|
||||
entry->mOp = OP_DELETE;
|
||||
entry->mRequestId = aRequestId;
|
||||
entry->mKey = aKey;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<cache::Manager> manager;
|
||||
nsresult rv = RequestManager(aRequestId, getter_AddRefs(manager));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
if (!SendDeleteResponse(aRequestId, rv, false)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Delete response.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
manager->StorageDelete(this, aRequestId, mNamespace, aKey);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageParent::RecvKeys(const RequestId& aRequestId)
|
||||
{
|
||||
if (NS_WARN_IF(NS_FAILED(mVerifiedStatus))) {
|
||||
if (!SendKeysResponse(aRequestId, mVerifiedStatus, nsTArray<nsString>())) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Keys response.");
|
||||
}
|
||||
}
|
||||
|
||||
// queue requests if we are still waiting for principal verification
|
||||
if (!mManagerId) {
|
||||
Entry* entry = mPendingRequests.AppendElement();
|
||||
entry->mOp = OP_DELETE;
|
||||
entry->mRequestId = aRequestId;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<cache::Manager> manager;
|
||||
nsresult rv = RequestManager(aRequestId, getter_AddRefs(manager));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
if (!SendKeysResponse(aRequestId, rv, nsTArray<nsString>())) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Keys response.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
manager->StorageKeys(this, aRequestId, mNamespace);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorageParent::OnPrincipalVerified(nsresult aRv, ManagerId* aManagerId)
|
||||
{
|
||||
MOZ_ASSERT(mVerifier);
|
||||
MOZ_ASSERT(!mManagerId);
|
||||
MOZ_ASSERT(!mManager);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(mVerifiedStatus));
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(aRv))) {
|
||||
@ -132,8 +284,165 @@ CacheStorageParent::OnPrincipalVerified(nsresult aRv, ManagerId* aManagerId)
|
||||
}
|
||||
|
||||
mManagerId = aManagerId;
|
||||
mVerifier->RemoveListener(this);
|
||||
mVerifier->ClearListener();
|
||||
mVerifier = nullptr;
|
||||
|
||||
RetryPendingRequests();
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorageParent::OnStorageMatch(RequestId aRequestId, nsresult aRv,
|
||||
const SavedResponse* aSavedResponse,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
PCacheResponseOrVoid responseOrVoid;
|
||||
|
||||
ReleaseManager(aRequestId);
|
||||
|
||||
AutoParentResponseOrVoid response(Manager());
|
||||
|
||||
// no match
|
||||
if (NS_FAILED(aRv) || !aSavedResponse) {
|
||||
if (!SendMatchResponse(aRequestId, aRv, response.SendAsResponseOrVoid())) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Match response.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (aSavedResponse) {
|
||||
response.Add(*aSavedResponse, aStreamList);
|
||||
}
|
||||
|
||||
if (!SendMatchResponse(aRequestId, aRv, response.SendAsResponseOrVoid())) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Match response.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorageParent::OnStorageHas(RequestId aRequestId, nsresult aRv,
|
||||
bool aCacheFound)
|
||||
{
|
||||
ReleaseManager(aRequestId);
|
||||
if (!SendHasResponse(aRequestId, aRv, aCacheFound)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Has response.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorageParent::OnStorageOpen(RequestId aRequestId, nsresult aRv,
|
||||
CacheId aCacheId)
|
||||
{
|
||||
if (NS_FAILED(aRv)) {
|
||||
ReleaseManager(aRequestId);
|
||||
if (!SendOpenResponse(aRequestId, aRv, nullptr)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Open response.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mManager);
|
||||
CacheParent* actor = new CacheParent(mManager, aCacheId);
|
||||
|
||||
ReleaseManager(aRequestId);
|
||||
|
||||
PCacheParent* base = Manager()->SendPCacheConstructor(actor);
|
||||
actor = static_cast<CacheParent*>(base);
|
||||
if (!SendOpenResponse(aRequestId, aRv, actor)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Open response.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorageParent::OnStorageDelete(RequestId aRequestId, nsresult aRv,
|
||||
bool aCacheDeleted)
|
||||
{
|
||||
ReleaseManager(aRequestId);
|
||||
if (!SendDeleteResponse(aRequestId, aRv, aCacheDeleted)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Delete response.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorageParent::OnStorageKeys(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<nsString>& aKeys)
|
||||
{
|
||||
ReleaseManager(aRequestId);
|
||||
if (!SendKeysResponse(aRequestId, aRv, aKeys)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Keys response.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorageParent::RetryPendingRequests()
|
||||
{
|
||||
MOZ_ASSERT(mManagerId || NS_FAILED(mVerifiedStatus));
|
||||
for (uint32_t i = 0; i < mPendingRequests.Length(); ++i) {
|
||||
const Entry& entry = mPendingRequests[i];
|
||||
switch(entry.mOp) {
|
||||
case OP_MATCH:
|
||||
RecvMatch(entry.mRequestId, entry.mRequest, entry.mParams);
|
||||
break;
|
||||
case OP_HAS:
|
||||
RecvHas(entry.mRequestId, entry.mKey);
|
||||
break;
|
||||
case OP_OPEN:
|
||||
RecvOpen(entry.mRequestId, entry.mKey);
|
||||
break;
|
||||
case OP_DELETE:
|
||||
RecvDelete(entry.mRequestId, entry.mKey);
|
||||
break;
|
||||
case OP_KEYS:
|
||||
RecvKeys(entry.mRequestId);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Pending request within unknown op");
|
||||
}
|
||||
}
|
||||
mPendingRequests.Clear();
|
||||
mPendingRequests.Compact();
|
||||
}
|
||||
|
||||
nsresult
|
||||
CacheStorageParent::RequestManager(RequestId aRequestId,
|
||||
cache::Manager** aManagerOut)
|
||||
{
|
||||
MOZ_ASSERT(!mActiveRequests.Contains(aRequestId));
|
||||
nsRefPtr<cache::Manager> ref = mManager;
|
||||
if (!ref) {
|
||||
MOZ_ASSERT(mActiveRequests.IsEmpty());
|
||||
nsresult rv = cache::Manager::GetOrCreate(mManagerId, getter_AddRefs(ref));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
mManager = ref;
|
||||
}
|
||||
mActiveRequests.AppendElement(aRequestId);
|
||||
ref.forget(aManagerOut);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorageParent::ReleaseManager(RequestId aRequestId)
|
||||
{
|
||||
// Note that if the child process dies we also clean up the mManager in
|
||||
// ActorDestroy(). There is no race with this method, however, because
|
||||
// ActorDestroy removes this object from the Manager's listener list.
|
||||
// Therefore ReleaseManager() should never be called after ActorDestroy()
|
||||
// runs.
|
||||
MOZ_ASSERT(mManager);
|
||||
MOZ_ASSERT(!mActiveRequests.IsEmpty());
|
||||
|
||||
MOZ_ALWAYS_TRUE(mActiveRequests.RemoveElement(aRequestId));
|
||||
|
||||
if (mActiveRequests.IsEmpty()) {
|
||||
mManager->RemoveListener(this);
|
||||
mManager = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
|
78
dom/cache/CacheStorageParent.h
vendored
78
dom/cache/CacheStorageParent.h
vendored
@ -7,18 +7,24 @@
|
||||
#ifndef mozilla_dom_cache_CacheStorageParent_h
|
||||
#define mozilla_dom_cache_CacheStorageParent_h
|
||||
|
||||
#include "mozilla/dom/cache/CacheInitData.h"
|
||||
#include "mozilla/dom/cache/PCacheStorageParent.h"
|
||||
#include "mozilla/dom/cache/Manager.h"
|
||||
#include "mozilla/dom/cache/PrincipalVerifier.h"
|
||||
#include "mozilla/dom/cache/Types.h"
|
||||
|
||||
template <class T> class nsRefPtr;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
class CacheStreamControlParent;
|
||||
class ManagerId;
|
||||
|
||||
class CacheStorageParent final : public PCacheStorageParent
|
||||
, public PrincipalVerifier::Listener
|
||||
, public Manager::Listener
|
||||
{
|
||||
public:
|
||||
CacheStorageParent(PBackgroundParent* aManagingActor, Namespace aNamespace,
|
||||
@ -27,30 +33,72 @@ public:
|
||||
|
||||
private:
|
||||
// PCacheStorageParent methods
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
virtual PCacheOpParent*
|
||||
AllocPCacheOpParent(const CacheOpArgs& aOpArgs) override;
|
||||
|
||||
virtual bool
|
||||
DeallocPCacheOpParent(PCacheOpParent* aActor) override;
|
||||
|
||||
virtual bool
|
||||
RecvPCacheOpConstructor(PCacheOpParent* actor,
|
||||
const CacheOpArgs& aOpArgs) override;
|
||||
|
||||
virtual bool
|
||||
RecvTeardown() override;
|
||||
virtual void ActorDestroy(ActorDestroyReason aReason) override;
|
||||
virtual bool RecvTeardown() override;
|
||||
virtual bool RecvMatch(const RequestId& aRequestId,
|
||||
const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams) override;
|
||||
virtual bool RecvHas(const RequestId& aRequestId,
|
||||
const nsString& aKey) override;
|
||||
virtual bool RecvOpen(const RequestId& aRequestId,
|
||||
const nsString& aKey) override;
|
||||
virtual bool RecvDelete(const RequestId& aRequestId,
|
||||
const nsString& aKey) override;
|
||||
virtual bool RecvKeys(const RequestId& aRequestId) override;
|
||||
|
||||
// PrincipalVerifier::Listener methods
|
||||
virtual void OnPrincipalVerified(nsresult aRv,
|
||||
ManagerId* aManagerId) override;
|
||||
|
||||
// Manager::Listener methods
|
||||
virtual void OnStorageMatch(RequestId aRequestId, nsresult aRv,
|
||||
const SavedResponse* aResponse,
|
||||
StreamList* aStreamList) override;
|
||||
virtual void OnStorageHas(RequestId aRequestId, nsresult aRv,
|
||||
bool aCacheFound) override;
|
||||
virtual void OnStorageOpen(RequestId aRequestId, nsresult aRv,
|
||||
CacheId aCacheId) override;
|
||||
virtual void OnStorageDelete(RequestId aRequestId, nsresult aRv,
|
||||
bool aCacheDeleted) override;
|
||||
virtual void OnStorageKeys(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<nsString>& aKeys) override;
|
||||
|
||||
CacheStreamControlParent*
|
||||
SerializeReadStream(CacheStreamControlParent *aStreamControl, const nsID& aId,
|
||||
StreamList* aStreamList,
|
||||
PCacheReadStream* aReadStreamOut);
|
||||
|
||||
void RetryPendingRequests();
|
||||
|
||||
nsresult RequestManager(RequestId aRequestId, cache::Manager** aManagerOut);
|
||||
void ReleaseManager(RequestId aRequestId);
|
||||
|
||||
const Namespace mNamespace;
|
||||
nsRefPtr<PrincipalVerifier> mVerifier;
|
||||
nsresult mVerifiedStatus;
|
||||
nsRefPtr<ManagerId> mManagerId;
|
||||
nsRefPtr<cache::Manager> mManager;
|
||||
|
||||
enum Op
|
||||
{
|
||||
OP_MATCH,
|
||||
OP_HAS,
|
||||
OP_OPEN,
|
||||
OP_DELETE,
|
||||
OP_KEYS
|
||||
};
|
||||
|
||||
struct Entry
|
||||
{
|
||||
Op mOp;
|
||||
RequestId mRequestId;
|
||||
nsString mKey;
|
||||
PCacheRequest mRequest;
|
||||
PCacheQueryParams mParams;
|
||||
};
|
||||
|
||||
nsTArray<Entry> mPendingRequests;
|
||||
nsTArray<RequestId> mActiveRequests;
|
||||
};
|
||||
|
||||
} // namesapce cache
|
||||
|
1
dom/cache/DBAction.cpp
vendored
1
dom/cache/DBAction.cpp
vendored
@ -14,7 +14,6 @@
|
||||
#include "nsIFile.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "DBSchema.h"
|
||||
#include "FileUtils.h"
|
||||
|
||||
|
1
dom/cache/DBAction.h
vendored
1
dom/cache/DBAction.h
vendored
@ -8,6 +8,7 @@
|
||||
#define mozilla_dom_cache_DBAction_h
|
||||
|
||||
#include "mozilla/dom/cache/Action.h"
|
||||
#include "mozilla/dom/cache/CacheInitData.h"
|
||||
#include "nsRefPtr.h"
|
||||
#include "nsString.h"
|
||||
|
||||
|
22
dom/cache/FetchPut.cpp
vendored
22
dom/cache/FetchPut.cpp
vendored
@ -90,7 +90,8 @@ private:
|
||||
|
||||
// static
|
||||
nsresult
|
||||
FetchPut::Create(Listener* aListener, Manager* aManager, CacheId aCacheId,
|
||||
FetchPut::Create(Listener* aListener, Manager* aManager,
|
||||
RequestId aRequestId, CacheId aCacheId,
|
||||
const nsTArray<PCacheRequest>& aRequests,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreams,
|
||||
FetchPut** aFetchPutOut)
|
||||
@ -106,7 +107,7 @@ FetchPut::Create(Listener* aListener, Manager* aManager, CacheId aCacheId,
|
||||
}
|
||||
#endif
|
||||
|
||||
nsRefPtr<FetchPut> ref = new FetchPut(aListener, aManager, aCacheId,
|
||||
nsRefPtr<FetchPut> ref = new FetchPut(aListener, aManager, aRequestId, aCacheId,
|
||||
aRequests, aRequestStreams);
|
||||
|
||||
nsresult rv = ref->DispatchToMainThread();
|
||||
@ -124,11 +125,13 @@ FetchPut::ClearListener()
|
||||
mListener = nullptr;
|
||||
}
|
||||
|
||||
FetchPut::FetchPut(Listener* aListener, Manager* aManager, CacheId aCacheId,
|
||||
FetchPut::FetchPut(Listener* aListener, Manager* aManager,
|
||||
RequestId aRequestId, CacheId aCacheId,
|
||||
const nsTArray<PCacheRequest>& aRequests,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreams)
|
||||
: mListener(aListener)
|
||||
, mManager(aManager)
|
||||
, mRequestId(aRequestId)
|
||||
, mCacheId(aCacheId)
|
||||
, mInitiatingThread(NS_GetCurrentThread())
|
||||
, mStateList(aRequests.Length())
|
||||
@ -319,8 +322,8 @@ FetchPut::DoPutOnWorkerThread()
|
||||
}
|
||||
mStateList.Clear();
|
||||
|
||||
mManager->ExecutePutAll(this, mCacheId, putList, requestStreamList,
|
||||
responseStreamList);
|
||||
mManager->CachePutAll(this, mRequestId, mCacheId, putList, requestStreamList,
|
||||
responseStreamList);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -415,14 +418,9 @@ FetchPut::MatchInPutList(const PCacheRequest& aRequest,
|
||||
}
|
||||
|
||||
void
|
||||
FetchPut::OnOpComplete(nsresult aRv, const CacheOpResult& aResult,
|
||||
CacheId aOpenedCacheId,
|
||||
const nsTArray<SavedResponse>& aSavedResponseList,
|
||||
const nsTArray<SavedRequest>& aSavedRequestList,
|
||||
StreamList* aStreamList)
|
||||
FetchPut::OnCachePutAll(RequestId aRequestId, nsresult aRv)
|
||||
{
|
||||
MOZ_ASSERT(mInitiatingThread == NS_GetCurrentThread());
|
||||
MOZ_ASSERT(aResult.type() == CacheOpResult::TCachePutAllResult);
|
||||
MaybeSetError(aRv);
|
||||
MaybeNotifyListener();
|
||||
}
|
||||
@ -443,7 +441,7 @@ FetchPut::MaybeNotifyListener()
|
||||
if (!mListener) {
|
||||
return;
|
||||
}
|
||||
mListener->OnFetchPut(this, mResult);
|
||||
mListener->OnFetchPut(this, mRequestId, mResult);
|
||||
}
|
||||
|
||||
nsIGlobalObject*
|
||||
|
17
dom/cache/FetchPut.h
vendored
17
dom/cache/FetchPut.h
vendored
@ -39,11 +39,12 @@ public:
|
||||
{
|
||||
public:
|
||||
virtual void
|
||||
OnFetchPut(FetchPut* aFetchPut, nsresult aRv) = 0;
|
||||
OnFetchPut(FetchPut* aFetchPut, RequestId aRequestId, nsresult aRv) = 0;
|
||||
};
|
||||
|
||||
static nsresult
|
||||
Create(Listener* aListener, Manager* aManager, CacheId aCacheId,
|
||||
Create(Listener* aListener, Manager* aManager,
|
||||
RequestId aRequestId, CacheId aCacheId,
|
||||
const nsTArray<PCacheRequest>& aRequests,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreams,
|
||||
FetchPut** aFetchPutOut);
|
||||
@ -65,7 +66,8 @@ private:
|
||||
nsRefPtr<Response> mResponse;
|
||||
};
|
||||
|
||||
FetchPut(Listener* aListener, Manager* aManager, CacheId aCacheId,
|
||||
FetchPut(Listener* aListener, Manager* aManager,
|
||||
RequestId aRequestId, CacheId aCacheId,
|
||||
const nsTArray<PCacheRequest>& aRequests,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreams);
|
||||
~FetchPut();
|
||||
@ -81,13 +83,7 @@ private:
|
||||
void DoPutOnWorkerThread();
|
||||
static bool MatchInPutList(const PCacheRequest& aRequest,
|
||||
const nsTArray<CacheRequestResponse>& aPutList);
|
||||
|
||||
virtual void
|
||||
OnOpComplete(nsresult aRv, const CacheOpResult& aResult,
|
||||
CacheId aOpenedCacheId,
|
||||
const nsTArray<SavedResponse>& aSavedResponseList,
|
||||
const nsTArray<SavedRequest>& aSavedRequestList,
|
||||
StreamList* aStreamList) override;
|
||||
virtual void OnCachePutAll(RequestId aRequestId, nsresult aRv) override;
|
||||
|
||||
void MaybeSetError(nsresult aRv);
|
||||
void MaybeNotifyListener();
|
||||
@ -103,6 +99,7 @@ private:
|
||||
|
||||
Listener* mListener;
|
||||
nsRefPtr<Manager> mManager;
|
||||
const RequestId mRequestId;
|
||||
const CacheId mCacheId;
|
||||
nsCOMPtr<nsIThread> mInitiatingThread;
|
||||
nsTArray<State> mStateList;
|
||||
|
435
dom/cache/Manager.cpp
vendored
435
dom/cache/Manager.cpp
vendored
@ -409,10 +409,11 @@ StaticRefPtr<nsIThread> Manager::Factory::sBackgroundThread;
|
||||
class Manager::BaseAction : public SyncDBAction
|
||||
{
|
||||
protected:
|
||||
BaseAction(Manager* aManager, ListenerId aListenerId)
|
||||
BaseAction(Manager* aManager, ListenerId aListenerId, RequestId aRequestId)
|
||||
: SyncDBAction(DBAction::Existing)
|
||||
, mManager(aManager)
|
||||
, mListenerId(aListenerId)
|
||||
, mRequestId (aRequestId)
|
||||
{
|
||||
}
|
||||
|
||||
@ -434,6 +435,7 @@ protected:
|
||||
|
||||
nsRefPtr<Manager> mManager;
|
||||
const ListenerId mListenerId;
|
||||
const RequestId mRequestId;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -486,11 +488,14 @@ class Manager::CacheMatchAction final : public Manager::BaseAction
|
||||
{
|
||||
public:
|
||||
CacheMatchAction(Manager* aManager, ListenerId aListenerId,
|
||||
CacheId aCacheId, const CacheMatchArgs& aArgs,
|
||||
RequestId aRequestId, CacheId aCacheId,
|
||||
const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams,
|
||||
StreamList* aStreamList)
|
||||
: BaseAction(aManager, aListenerId)
|
||||
: BaseAction(aManager, aListenerId, aRequestId)
|
||||
, mCacheId(aCacheId)
|
||||
, mArgs(aArgs)
|
||||
, mRequest(aRequest)
|
||||
, mParams(aParams)
|
||||
, mStreamList(aStreamList)
|
||||
, mFoundResponse(false)
|
||||
{ }
|
||||
@ -499,9 +504,8 @@ public:
|
||||
RunSyncWithDBOnTarget(const QuotaInfo& aQuotaInfo, nsIFile* aDBDir,
|
||||
mozIStorageConnection* aConn) override
|
||||
{
|
||||
nsresult rv = DBSchema::CacheMatch(aConn, mCacheId, mArgs.request(),
|
||||
mArgs.params(), &mFoundResponse,
|
||||
&mResponse);
|
||||
nsresult rv = DBSchema::CacheMatch(aConn, mCacheId, mRequest, mParams,
|
||||
&mFoundResponse, &mResponse);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
if (!mFoundResponse || !mResponse.mHasBodyId) {
|
||||
@ -523,11 +527,10 @@ public:
|
||||
Complete(Listener* aListener, nsresult aRv) override
|
||||
{
|
||||
if (!mFoundResponse) {
|
||||
aListener->OnOpComplete(aRv, CacheMatchResult(void_t()));
|
||||
aListener->OnCacheMatch(mRequestId, aRv, nullptr, nullptr);
|
||||
} else {
|
||||
mStreamList->Activate(mCacheId);
|
||||
aListener->OnOpComplete(aRv, CacheMatchResult(void_t()), mResponse,
|
||||
mStreamList);
|
||||
aListener->OnCacheMatch(mRequestId, aRv, &mResponse, mStreamList);
|
||||
}
|
||||
mStreamList = nullptr;
|
||||
}
|
||||
@ -539,7 +542,8 @@ public:
|
||||
|
||||
private:
|
||||
const CacheId mCacheId;
|
||||
const CacheMatchArgs mArgs;
|
||||
const PCacheRequest mRequest;
|
||||
const PCacheQueryParams mParams;
|
||||
nsRefPtr<StreamList> mStreamList;
|
||||
bool mFoundResponse;
|
||||
SavedResponse mResponse;
|
||||
@ -551,11 +555,14 @@ class Manager::CacheMatchAllAction final : public Manager::BaseAction
|
||||
{
|
||||
public:
|
||||
CacheMatchAllAction(Manager* aManager, ListenerId aListenerId,
|
||||
CacheId aCacheId, const CacheMatchAllArgs& aArgs,
|
||||
RequestId aRequestId, CacheId aCacheId,
|
||||
const PCacheRequestOrVoid& aRequestOrVoid,
|
||||
const PCacheQueryParams& aParams,
|
||||
StreamList* aStreamList)
|
||||
: BaseAction(aManager, aListenerId)
|
||||
: BaseAction(aManager, aListenerId, aRequestId)
|
||||
, mCacheId(aCacheId)
|
||||
, mArgs(aArgs)
|
||||
, mRequestOrVoid(aRequestOrVoid)
|
||||
, mParams(aParams)
|
||||
, mStreamList(aStreamList)
|
||||
{ }
|
||||
|
||||
@ -563,8 +570,8 @@ public:
|
||||
RunSyncWithDBOnTarget(const QuotaInfo& aQuotaInfo, nsIFile* aDBDir,
|
||||
mozIStorageConnection* aConn) override
|
||||
{
|
||||
nsresult rv = DBSchema::CacheMatchAll(aConn, mCacheId, mArgs.requestOrVoid(),
|
||||
mArgs.params(), mSavedResponses);
|
||||
nsresult rv = DBSchema::CacheMatchAll(aConn, mCacheId, mRequestOrVoid,
|
||||
mParams, mSavedResponses);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
for (uint32_t i = 0; i < mSavedResponses.Length(); ++i) {
|
||||
@ -589,8 +596,7 @@ public:
|
||||
Complete(Listener* aListener, nsresult aRv) override
|
||||
{
|
||||
mStreamList->Activate(mCacheId);
|
||||
aListener->OnOpComplete(aRv, CacheMatchAllResult(), mSavedResponses,
|
||||
mStreamList);
|
||||
aListener->OnCacheMatchAll(mRequestId, aRv, mSavedResponses, mStreamList);
|
||||
mStreamList = nullptr;
|
||||
}
|
||||
|
||||
@ -601,7 +607,8 @@ public:
|
||||
|
||||
private:
|
||||
const CacheId mCacheId;
|
||||
const CacheMatchAllArgs mArgs;
|
||||
const PCacheRequestOrVoid mRequestOrVoid;
|
||||
const PCacheQueryParams mParams;
|
||||
nsRefPtr<StreamList> mStreamList;
|
||||
nsTArray<SavedResponse> mSavedResponses;
|
||||
};
|
||||
@ -615,13 +622,14 @@ class Manager::CachePutAllAction final : public DBAction
|
||||
{
|
||||
public:
|
||||
CachePutAllAction(Manager* aManager, ListenerId aListenerId,
|
||||
CacheId aCacheId,
|
||||
RequestId aRequestId, CacheId aCacheId,
|
||||
const nsTArray<CacheRequestResponse>& aPutList,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreamList,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aResponseStreamList)
|
||||
: DBAction(DBAction::Existing)
|
||||
, mManager(aManager)
|
||||
, mListenerId(aListenerId)
|
||||
, mRequestId(aRequestId)
|
||||
, mCacheId(aCacheId)
|
||||
, mList(aPutList.Length())
|
||||
, mExpectedAsyncCopyCompletions(1)
|
||||
@ -806,7 +814,7 @@ private:
|
||||
Listener* listener = mManager->GetListener(mListenerId);
|
||||
mManager = nullptr;
|
||||
if (listener) {
|
||||
listener->OnOpComplete(aRv, CachePutAllResult());
|
||||
listener->OnCachePutAll(mRequestId, aRv);
|
||||
}
|
||||
}
|
||||
|
||||
@ -959,6 +967,7 @@ private:
|
||||
// initiating thread only
|
||||
nsRefPtr<Manager> mManager;
|
||||
const ListenerId mListenerId;
|
||||
const RequestId mRequestId;
|
||||
|
||||
// Set on initiating thread, read on target thread. State machine guarantees
|
||||
// these are not modified while being read by the target thread.
|
||||
@ -989,10 +998,13 @@ class Manager::CacheDeleteAction final : public Manager::BaseAction
|
||||
{
|
||||
public:
|
||||
CacheDeleteAction(Manager* aManager, ListenerId aListenerId,
|
||||
CacheId aCacheId, const CacheDeleteArgs& aArgs)
|
||||
: BaseAction(aManager, aListenerId)
|
||||
RequestId aRequestId, CacheId aCacheId,
|
||||
const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams)
|
||||
: BaseAction(aManager, aListenerId, aRequestId)
|
||||
, mCacheId(aCacheId)
|
||||
, mArgs(aArgs)
|
||||
, mRequest(aRequest)
|
||||
, mParams(aParams)
|
||||
, mSuccess(false)
|
||||
{ }
|
||||
|
||||
@ -1003,9 +1015,8 @@ public:
|
||||
mozStorageTransaction trans(aConn, false,
|
||||
mozIStorageConnection::TRANSACTION_IMMEDIATE);
|
||||
|
||||
nsresult rv = DBSchema::CacheDelete(aConn, mCacheId, mArgs.request(),
|
||||
mArgs.params(), mDeletedBodyIdList,
|
||||
&mSuccess);
|
||||
nsresult rv = DBSchema::CacheDelete(aConn, mCacheId, mRequest, mParams,
|
||||
mDeletedBodyIdList, &mSuccess);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = trans.Commit();
|
||||
@ -1021,7 +1032,7 @@ public:
|
||||
Complete(Listener* aListener, nsresult aRv) override
|
||||
{
|
||||
mManager->NoteOrphanedBodyIdList(mDeletedBodyIdList);
|
||||
aListener->OnOpComplete(aRv, CacheDeleteResult(mSuccess));
|
||||
aListener->OnCacheDelete(mRequestId, aRv, mSuccess);
|
||||
}
|
||||
|
||||
virtual bool MatchesCacheId(CacheId aCacheId) const override
|
||||
@ -1031,7 +1042,8 @@ public:
|
||||
|
||||
private:
|
||||
const CacheId mCacheId;
|
||||
const CacheDeleteArgs mArgs;
|
||||
const PCacheRequest mRequest;
|
||||
const PCacheQueryParams mParams;
|
||||
bool mSuccess;
|
||||
nsTArray<nsID> mDeletedBodyIdList;
|
||||
};
|
||||
@ -1042,11 +1054,14 @@ class Manager::CacheKeysAction final : public Manager::BaseAction
|
||||
{
|
||||
public:
|
||||
CacheKeysAction(Manager* aManager, ListenerId aListenerId,
|
||||
CacheId aCacheId, const CacheKeysArgs& aArgs,
|
||||
RequestId aRequestId, CacheId aCacheId,
|
||||
const PCacheRequestOrVoid& aRequestOrVoid,
|
||||
const PCacheQueryParams& aParams,
|
||||
StreamList* aStreamList)
|
||||
: BaseAction(aManager, aListenerId)
|
||||
: BaseAction(aManager, aListenerId, aRequestId)
|
||||
, mCacheId(aCacheId)
|
||||
, mArgs(aArgs)
|
||||
, mRequestOrVoid(aRequestOrVoid)
|
||||
, mParams(aParams)
|
||||
, mStreamList(aStreamList)
|
||||
{ }
|
||||
|
||||
@ -1054,8 +1069,8 @@ public:
|
||||
RunSyncWithDBOnTarget(const QuotaInfo& aQuotaInfo, nsIFile* aDBDir,
|
||||
mozIStorageConnection* aConn) override
|
||||
{
|
||||
nsresult rv = DBSchema::CacheKeys(aConn, mCacheId, mArgs.requestOrVoid(),
|
||||
mArgs.params(), mSavedRequests);
|
||||
nsresult rv = DBSchema::CacheKeys(aConn, mCacheId, mRequestOrVoid, mParams,
|
||||
mSavedRequests);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
for (uint32_t i = 0; i < mSavedRequests.Length(); ++i) {
|
||||
@ -1080,8 +1095,7 @@ public:
|
||||
Complete(Listener* aListener, nsresult aRv) override
|
||||
{
|
||||
mStreamList->Activate(mCacheId);
|
||||
aListener->OnOpComplete(aRv, CacheKeysResult(), mSavedRequests,
|
||||
mStreamList);
|
||||
aListener->OnCacheKeys(mRequestId, aRv, mSavedRequests, mStreamList);
|
||||
mStreamList = nullptr;
|
||||
}
|
||||
|
||||
@ -1092,7 +1106,8 @@ public:
|
||||
|
||||
private:
|
||||
const CacheId mCacheId;
|
||||
const CacheKeysArgs mArgs;
|
||||
const PCacheRequestOrVoid mRequestOrVoid;
|
||||
const PCacheQueryParams mParams;
|
||||
nsRefPtr<StreamList> mStreamList;
|
||||
nsTArray<SavedRequest> mSavedRequests;
|
||||
};
|
||||
@ -1103,12 +1118,14 @@ class Manager::StorageMatchAction final : public Manager::BaseAction
|
||||
{
|
||||
public:
|
||||
StorageMatchAction(Manager* aManager, ListenerId aListenerId,
|
||||
Namespace aNamespace,
|
||||
const StorageMatchArgs& aArgs,
|
||||
RequestId aRequestId, Namespace aNamespace,
|
||||
const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams,
|
||||
StreamList* aStreamList)
|
||||
: BaseAction(aManager, aListenerId)
|
||||
: BaseAction(aManager, aListenerId, aRequestId)
|
||||
, mNamespace(aNamespace)
|
||||
, mArgs(aArgs)
|
||||
, mRequest(aRequest)
|
||||
, mParams(aParams)
|
||||
, mStreamList(aStreamList)
|
||||
, mFoundResponse(false)
|
||||
{ }
|
||||
@ -1117,9 +1134,8 @@ public:
|
||||
RunSyncWithDBOnTarget(const QuotaInfo& aQuotaInfo, nsIFile* aDBDir,
|
||||
mozIStorageConnection* aConn) override
|
||||
{
|
||||
nsresult rv = DBSchema::StorageMatch(aConn, mNamespace, mArgs.request(),
|
||||
mArgs.params(), &mFoundResponse,
|
||||
&mSavedResponse);
|
||||
nsresult rv = DBSchema::StorageMatch(aConn, mNamespace, mRequest, mParams,
|
||||
&mFoundResponse, &mSavedResponse);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
if (!mFoundResponse || !mSavedResponse.mHasBodyId) {
|
||||
@ -1141,18 +1157,18 @@ public:
|
||||
Complete(Listener* aListener, nsresult aRv) override
|
||||
{
|
||||
if (!mFoundResponse) {
|
||||
aListener->OnOpComplete(aRv, StorageMatchResult(void_t()));
|
||||
aListener->OnStorageMatch(mRequestId, aRv, nullptr, nullptr);
|
||||
} else {
|
||||
mStreamList->Activate(mSavedResponse.mCacheId);
|
||||
aListener->OnOpComplete(aRv, StorageMatchResult(void_t()), mSavedResponse,
|
||||
mStreamList);
|
||||
aListener->OnStorageMatch(mRequestId, aRv, &mSavedResponse, mStreamList);
|
||||
}
|
||||
mStreamList = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
const Namespace mNamespace;
|
||||
const StorageMatchArgs mArgs;
|
||||
const PCacheRequest mRequest;
|
||||
const PCacheQueryParams mParams;
|
||||
nsRefPtr<StreamList> mStreamList;
|
||||
bool mFoundResponse;
|
||||
SavedResponse mSavedResponse;
|
||||
@ -1164,10 +1180,11 @@ class Manager::StorageHasAction final : public Manager::BaseAction
|
||||
{
|
||||
public:
|
||||
StorageHasAction(Manager* aManager, ListenerId aListenerId,
|
||||
Namespace aNamespace, const StorageHasArgs& aArgs)
|
||||
: BaseAction(aManager, aListenerId)
|
||||
RequestId aRequestId, Namespace aNamespace,
|
||||
const nsAString& aKey)
|
||||
: BaseAction(aManager, aListenerId, aRequestId)
|
||||
, mNamespace(aNamespace)
|
||||
, mArgs(aArgs)
|
||||
, mKey(aKey)
|
||||
, mCacheFound(false)
|
||||
{ }
|
||||
|
||||
@ -1176,19 +1193,19 @@ public:
|
||||
mozIStorageConnection* aConn) override
|
||||
{
|
||||
CacheId cacheId;
|
||||
return DBSchema::StorageGetCacheId(aConn, mNamespace, mArgs.key(),
|
||||
return DBSchema::StorageGetCacheId(aConn, mNamespace, mKey,
|
||||
&mCacheFound, &cacheId);
|
||||
}
|
||||
|
||||
virtual void
|
||||
Complete(Listener* aListener, nsresult aRv) override
|
||||
{
|
||||
aListener->OnOpComplete(aRv, StorageHasResult(mCacheFound));
|
||||
aListener->OnStorageHas(mRequestId, aRv, mCacheFound);
|
||||
}
|
||||
|
||||
private:
|
||||
const Namespace mNamespace;
|
||||
const StorageHasArgs mArgs;
|
||||
const nsString mKey;
|
||||
bool mCacheFound;
|
||||
};
|
||||
|
||||
@ -1198,10 +1215,11 @@ class Manager::StorageOpenAction final : public Manager::BaseAction
|
||||
{
|
||||
public:
|
||||
StorageOpenAction(Manager* aManager, ListenerId aListenerId,
|
||||
Namespace aNamespace, const StorageOpenArgs& aArgs)
|
||||
: BaseAction(aManager, aListenerId)
|
||||
RequestId aRequestId, Namespace aNamespace,
|
||||
const nsAString& aKey)
|
||||
: BaseAction(aManager, aListenerId, aRequestId)
|
||||
, mNamespace(aNamespace)
|
||||
, mArgs(aArgs)
|
||||
, mKey(aKey)
|
||||
, mCacheId(INVALID_CACHE_ID)
|
||||
{ }
|
||||
|
||||
@ -1215,7 +1233,7 @@ public:
|
||||
|
||||
// Look for existing cache
|
||||
bool cacheFound;
|
||||
nsresult rv = DBSchema::StorageGetCacheId(aConn, mNamespace, mArgs.key(),
|
||||
nsresult rv = DBSchema::StorageGetCacheId(aConn, mNamespace, mKey,
|
||||
&cacheFound, &mCacheId);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
if (cacheFound) {
|
||||
@ -1225,7 +1243,7 @@ public:
|
||||
rv = DBSchema::CreateCache(aConn, &mCacheId);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = DBSchema::StoragePutCache(aConn, mNamespace, mArgs.key(), mCacheId);
|
||||
rv = DBSchema::StoragePutCache(aConn, mNamespace, mKey, mCacheId);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = trans.Commit();
|
||||
@ -1237,12 +1255,12 @@ public:
|
||||
virtual void
|
||||
Complete(Listener* aListener, nsresult aRv) override
|
||||
{
|
||||
aListener->OnOpComplete(aRv, StorageOpenResult(), mCacheId);
|
||||
aListener->OnStorageOpen(mRequestId, aRv, mCacheId);
|
||||
}
|
||||
|
||||
private:
|
||||
const Namespace mNamespace;
|
||||
const StorageOpenArgs mArgs;
|
||||
const nsString mKey;
|
||||
CacheId mCacheId;
|
||||
};
|
||||
|
||||
@ -1252,10 +1270,11 @@ class Manager::StorageDeleteAction final : public Manager::BaseAction
|
||||
{
|
||||
public:
|
||||
StorageDeleteAction(Manager* aManager, ListenerId aListenerId,
|
||||
Namespace aNamespace, const StorageDeleteArgs& aArgs)
|
||||
: BaseAction(aManager, aListenerId)
|
||||
RequestId aRequestId, Namespace aNamespace,
|
||||
const nsAString& aKey)
|
||||
: BaseAction(aManager, aListenerId, aRequestId)
|
||||
, mNamespace(aNamespace)
|
||||
, mArgs(aArgs)
|
||||
, mKey(aKey)
|
||||
, mCacheDeleted(false)
|
||||
, mCacheId(INVALID_CACHE_ID)
|
||||
{ }
|
||||
@ -1268,8 +1287,8 @@ public:
|
||||
mozIStorageConnection::TRANSACTION_IMMEDIATE);
|
||||
|
||||
bool exists;
|
||||
nsresult rv = DBSchema::StorageGetCacheId(aConn, mNamespace, mArgs.key(),
|
||||
&exists, &mCacheId);
|
||||
nsresult rv = DBSchema::StorageGetCacheId(aConn, mNamespace, mKey, &exists,
|
||||
&mCacheId);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
if (!exists) {
|
||||
@ -1277,7 +1296,7 @@ public:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
rv = DBSchema::StorageForgetCache(aConn, mNamespace, mArgs.key());
|
||||
rv = DBSchema::StorageForgetCache(aConn, mNamespace, mKey);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = trans.Commit();
|
||||
@ -1304,12 +1323,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
aListener->OnOpComplete(aRv, StorageDeleteResult(mCacheDeleted));
|
||||
aListener->OnStorageDelete(mRequestId, aRv, mCacheDeleted);
|
||||
}
|
||||
|
||||
private:
|
||||
const Namespace mNamespace;
|
||||
const StorageDeleteArgs mArgs;
|
||||
const nsString mKey;
|
||||
bool mCacheDeleted;
|
||||
CacheId mCacheId;
|
||||
};
|
||||
@ -1320,8 +1339,8 @@ class Manager::StorageKeysAction final : public Manager::BaseAction
|
||||
{
|
||||
public:
|
||||
StorageKeysAction(Manager* aManager, ListenerId aListenerId,
|
||||
Namespace aNamespace)
|
||||
: BaseAction(aManager, aListenerId)
|
||||
RequestId aRequestId, Namespace aNamespace)
|
||||
: BaseAction(aManager, aListenerId, aRequestId)
|
||||
, mNamespace(aNamespace)
|
||||
{ }
|
||||
|
||||
@ -1338,7 +1357,7 @@ public:
|
||||
if (NS_FAILED(aRv)) {
|
||||
mKeys.Clear();
|
||||
}
|
||||
aListener->OnOpComplete(aRv, StorageKeysResult(mKeys));
|
||||
aListener->OnStorageKeys(mRequestId, aRv, mKeys);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -1351,50 +1370,6 @@ private:
|
||||
//static
|
||||
Manager::ListenerId Manager::sNextListenerId = 0;
|
||||
|
||||
void
|
||||
Manager::Listener::OnOpComplete(nsresult aRv, const CacheOpResult& aResult)
|
||||
{
|
||||
OnOpComplete(aRv, aResult, INVALID_CACHE_ID, nsTArray<SavedResponse>(),
|
||||
nsTArray<SavedRequest>(), nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
Manager::Listener::OnOpComplete(nsresult aRv, const CacheOpResult& aResult,
|
||||
CacheId aOpenedCacheId)
|
||||
{
|
||||
OnOpComplete(aRv, aResult, aOpenedCacheId, nsTArray<SavedResponse>(),
|
||||
nsTArray<SavedRequest>(), nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
Manager::Listener::OnOpComplete(nsresult aRv, const CacheOpResult& aResult,
|
||||
const SavedResponse& aSavedResponse,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
nsAutoTArray<SavedResponse, 1> responseList;
|
||||
responseList.AppendElement(aSavedResponse);
|
||||
OnOpComplete(aRv, aResult, INVALID_CACHE_ID, responseList,
|
||||
nsTArray<SavedRequest>(), aStreamList);
|
||||
}
|
||||
|
||||
void
|
||||
Manager::Listener::OnOpComplete(nsresult aRv, const CacheOpResult& aResult,
|
||||
const nsTArray<SavedResponse>& aSavedResponseList,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
OnOpComplete(aRv, aResult, INVALID_CACHE_ID, aSavedResponseList,
|
||||
nsTArray<SavedRequest>(), aStreamList);
|
||||
}
|
||||
|
||||
void
|
||||
Manager::Listener::OnOpComplete(nsresult aRv, const CacheOpResult& aResult,
|
||||
const nsTArray<SavedRequest>& aSavedRequestList,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
OnOpComplete(aRv, aResult, INVALID_CACHE_ID, nsTArray<SavedResponse>(),
|
||||
aSavedRequestList, aStreamList);
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
Manager::GetOrCreate(ManagerId* aManagerId, Manager** aManagerOut)
|
||||
@ -1585,115 +1560,195 @@ Manager::RemoveStreamList(StreamList* aStreamList)
|
||||
}
|
||||
|
||||
void
|
||||
Manager::ExecuteCacheOp(Listener* aListener, CacheId aCacheId,
|
||||
const CacheOpArgs& aOpArgs)
|
||||
Manager::CacheMatch(Listener* aListener, RequestId aRequestId, CacheId aCacheId,
|
||||
const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(Manager);
|
||||
MOZ_ASSERT(aListener);
|
||||
MOZ_ASSERT(aOpArgs.type() != CacheOpArgs::TCacheAddAllArgs);
|
||||
MOZ_ASSERT(aOpArgs.type() != CacheOpArgs::TCachePutAllArgs);
|
||||
|
||||
if (mShuttingDown || !mValid) {
|
||||
aListener->OnOpComplete(NS_ERROR_FAILURE, void_t());
|
||||
aListener->OnCacheMatch(aRequestId, NS_ERROR_FAILURE, nullptr, nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<Context> context = CurrentContext();
|
||||
nsRefPtr<StreamList> streamList = new StreamList(this, context);
|
||||
ListenerId listenerId = SaveListener(aListener);
|
||||
|
||||
nsRefPtr<Action> action;
|
||||
switch(aOpArgs.type()) {
|
||||
case CacheOpArgs::TCacheMatchArgs:
|
||||
action = new CacheMatchAction(this, listenerId, aCacheId,
|
||||
aOpArgs.get_CacheMatchArgs(), streamList);
|
||||
break;
|
||||
case CacheOpArgs::TCacheMatchAllArgs:
|
||||
action = new CacheMatchAllAction(this, listenerId, aCacheId,
|
||||
aOpArgs.get_CacheMatchAllArgs(),
|
||||
streamList);
|
||||
break;
|
||||
case CacheOpArgs::TCacheDeleteArgs:
|
||||
action = new CacheDeleteAction(this, listenerId, aCacheId,
|
||||
aOpArgs.get_CacheDeleteArgs());
|
||||
break;
|
||||
case CacheOpArgs::TCacheKeysArgs:
|
||||
action = new CacheKeysAction(this, listenerId, aCacheId,
|
||||
aOpArgs.get_CacheKeysArgs(), streamList);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unknown Cache operation!");
|
||||
}
|
||||
|
||||
nsRefPtr<Action> action = new CacheMatchAction(this, listenerId, aRequestId,
|
||||
aCacheId, aRequest, aParams,
|
||||
streamList);
|
||||
context->Dispatch(mIOThread, action);
|
||||
}
|
||||
|
||||
void
|
||||
Manager::ExecuteStorageOp(Listener* aListener, Namespace aNamespace,
|
||||
const CacheOpArgs& aOpArgs)
|
||||
Manager::CacheMatchAll(Listener* aListener, RequestId aRequestId,
|
||||
CacheId aCacheId, const PCacheRequestOrVoid& aRequest,
|
||||
const PCacheQueryParams& aParams)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(Manager);
|
||||
MOZ_ASSERT(aListener);
|
||||
|
||||
if (mShuttingDown || !mValid) {
|
||||
aListener->OnOpComplete(NS_ERROR_FAILURE, void_t());
|
||||
aListener->OnCacheMatchAll(aRequestId, NS_ERROR_FAILURE,
|
||||
nsTArray<SavedResponse>(), nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<Context> context = CurrentContext();
|
||||
nsRefPtr<StreamList> streamList = new StreamList(this, context);
|
||||
ListenerId listenerId = SaveListener(aListener);
|
||||
|
||||
nsRefPtr<Action> action;
|
||||
switch(aOpArgs.type()) {
|
||||
case CacheOpArgs::TStorageMatchArgs:
|
||||
action = new StorageMatchAction(this, listenerId, aNamespace,
|
||||
aOpArgs.get_StorageMatchArgs(),
|
||||
streamList);
|
||||
break;
|
||||
case CacheOpArgs::TStorageHasArgs:
|
||||
action = new StorageHasAction(this, listenerId, aNamespace,
|
||||
aOpArgs.get_StorageHasArgs());
|
||||
break;
|
||||
case CacheOpArgs::TStorageOpenArgs:
|
||||
action = new StorageOpenAction(this, listenerId, aNamespace,
|
||||
aOpArgs.get_StorageOpenArgs());
|
||||
break;
|
||||
case CacheOpArgs::TStorageDeleteArgs:
|
||||
action = new StorageDeleteAction(this, listenerId, aNamespace,
|
||||
aOpArgs.get_StorageDeleteArgs());
|
||||
break;
|
||||
case CacheOpArgs::TStorageKeysArgs:
|
||||
action = new StorageKeysAction(this, listenerId, aNamespace);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unknown CacheStorage operation!");
|
||||
}
|
||||
|
||||
nsRefPtr<Action> action = new CacheMatchAllAction(this, listenerId, aRequestId,
|
||||
aCacheId, aRequest, aParams,
|
||||
streamList);
|
||||
context->Dispatch(mIOThread, action);
|
||||
}
|
||||
|
||||
void
|
||||
Manager::ExecutePutAll(Listener* aListener, CacheId aCacheId,
|
||||
const nsTArray<CacheRequestResponse>& aPutList,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreamList,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aResponseStreamList)
|
||||
Manager::CachePutAll(Listener* aListener, RequestId aRequestId, CacheId aCacheId,
|
||||
const nsTArray<CacheRequestResponse>& aPutList,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreamList,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aResponseStreamList)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(Manager);
|
||||
MOZ_ASSERT(aListener);
|
||||
|
||||
if (mShuttingDown || !mValid) {
|
||||
aListener->OnOpComplete(NS_ERROR_FAILURE, CachePutAllResult());
|
||||
aListener->OnCachePutAll(aRequestId, NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<Context> context = CurrentContext();
|
||||
ListenerId listenerId = SaveListener(aListener);
|
||||
|
||||
nsRefPtr<Action> action = new CachePutAllAction(this, listenerId, aCacheId,
|
||||
aPutList, aRequestStreamList,
|
||||
nsRefPtr<Action> action = new CachePutAllAction(this, listenerId, aRequestId,
|
||||
aCacheId, aPutList,
|
||||
aRequestStreamList,
|
||||
aResponseStreamList);
|
||||
nsRefPtr<Context> context = CurrentContext();
|
||||
context->Dispatch(mIOThread, action);
|
||||
}
|
||||
|
||||
void
|
||||
Manager::CacheDelete(Listener* aListener, RequestId aRequestId,
|
||||
CacheId aCacheId, const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(Manager);
|
||||
MOZ_ASSERT(aListener);
|
||||
if (mShuttingDown || !mValid) {
|
||||
aListener->OnCacheDelete(aRequestId, NS_ERROR_FAILURE, false);
|
||||
return;
|
||||
}
|
||||
ListenerId listenerId = SaveListener(aListener);
|
||||
nsRefPtr<Action> action = new CacheDeleteAction(this, listenerId, aRequestId,
|
||||
aCacheId, aRequest, aParams);
|
||||
nsRefPtr<Context> context = CurrentContext();
|
||||
context->Dispatch(mIOThread, action);
|
||||
}
|
||||
|
||||
void
|
||||
Manager::CacheKeys(Listener* aListener, RequestId aRequestId,
|
||||
CacheId aCacheId, const PCacheRequestOrVoid& aRequestOrVoid,
|
||||
const PCacheQueryParams& aParams)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(Manager);
|
||||
MOZ_ASSERT(aListener);
|
||||
if (mShuttingDown || !mValid) {
|
||||
aListener->OnCacheKeys(aRequestId, NS_ERROR_FAILURE,
|
||||
nsTArray<SavedRequest>(), nullptr);
|
||||
return;
|
||||
}
|
||||
nsRefPtr<Context> context = CurrentContext();
|
||||
nsRefPtr<StreamList> streamList = new StreamList(this, context);
|
||||
ListenerId listenerId = SaveListener(aListener);
|
||||
nsRefPtr<Action> action = new CacheKeysAction(this, listenerId, aRequestId,
|
||||
aCacheId, aRequestOrVoid,
|
||||
aParams, streamList);
|
||||
context->Dispatch(mIOThread, action);
|
||||
}
|
||||
|
||||
void
|
||||
Manager::StorageMatch(Listener* aListener, RequestId aRequestId,
|
||||
Namespace aNamespace, const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(Manager);
|
||||
MOZ_ASSERT(aListener);
|
||||
if (mShuttingDown || !mValid) {
|
||||
aListener->OnStorageMatch(aRequestId, NS_ERROR_FAILURE,
|
||||
nullptr, nullptr);
|
||||
return;
|
||||
}
|
||||
nsRefPtr<Context> context = CurrentContext();
|
||||
nsRefPtr<StreamList> streamList = new StreamList(this, context);
|
||||
ListenerId listenerId = SaveListener(aListener);
|
||||
nsRefPtr<Action> action = new StorageMatchAction(this, listenerId, aRequestId,
|
||||
aNamespace, aRequest,
|
||||
aParams, streamList);
|
||||
context->Dispatch(mIOThread, action);
|
||||
}
|
||||
|
||||
void
|
||||
Manager::StorageHas(Listener* aListener, RequestId aRequestId,
|
||||
Namespace aNamespace, const nsAString& aKey)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(Manager);
|
||||
MOZ_ASSERT(aListener);
|
||||
if (mShuttingDown || !mValid) {
|
||||
aListener->OnStorageHas(aRequestId, NS_ERROR_FAILURE,
|
||||
false);
|
||||
return;
|
||||
}
|
||||
ListenerId listenerId = SaveListener(aListener);
|
||||
nsRefPtr<Action> action = new StorageHasAction(this, listenerId, aRequestId,
|
||||
aNamespace, aKey);
|
||||
nsRefPtr<Context> context = CurrentContext();
|
||||
context->Dispatch(mIOThread, action);
|
||||
}
|
||||
|
||||
void
|
||||
Manager::StorageOpen(Listener* aListener, RequestId aRequestId,
|
||||
Namespace aNamespace, const nsAString& aKey)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(Manager);
|
||||
MOZ_ASSERT(aListener);
|
||||
if (mShuttingDown || !mValid) {
|
||||
aListener->OnStorageOpen(aRequestId, NS_ERROR_FAILURE, 0);
|
||||
return;
|
||||
}
|
||||
ListenerId listenerId = SaveListener(aListener);
|
||||
nsRefPtr<Action> action = new StorageOpenAction(this, listenerId, aRequestId,
|
||||
aNamespace, aKey);
|
||||
nsRefPtr<Context> context = CurrentContext();
|
||||
context->Dispatch(mIOThread, action);
|
||||
}
|
||||
|
||||
void
|
||||
Manager::StorageDelete(Listener* aListener, RequestId aRequestId,
|
||||
Namespace aNamespace, const nsAString& aKey)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(Manager);
|
||||
MOZ_ASSERT(aListener);
|
||||
if (mShuttingDown || !mValid) {
|
||||
aListener->OnStorageDelete(aRequestId, NS_ERROR_FAILURE,
|
||||
false);
|
||||
return;
|
||||
}
|
||||
ListenerId listenerId = SaveListener(aListener);
|
||||
nsRefPtr<Action> action = new StorageDeleteAction(this, listenerId, aRequestId,
|
||||
aNamespace, aKey);
|
||||
nsRefPtr<Context> context = CurrentContext();
|
||||
context->Dispatch(mIOThread, action);
|
||||
}
|
||||
|
||||
void
|
||||
Manager::StorageKeys(Listener* aListener, RequestId aRequestId,
|
||||
Namespace aNamespace)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(Manager);
|
||||
MOZ_ASSERT(aListener);
|
||||
if (mShuttingDown || !mValid) {
|
||||
aListener->OnStorageKeys(aRequestId, NS_ERROR_FAILURE,
|
||||
nsTArray<nsString>());
|
||||
return;
|
||||
}
|
||||
ListenerId listenerId = SaveListener(aListener);
|
||||
nsRefPtr<Action> action = new StorageKeysAction(this, listenerId, aRequestId,
|
||||
aNamespace);
|
||||
nsRefPtr<Context> context = CurrentContext();
|
||||
context->Dispatch(mIOThread, action);
|
||||
}
|
||||
|
||||
|
91
dom/cache/Manager.h
vendored
91
dom/cache/Manager.h
vendored
@ -7,6 +7,7 @@
|
||||
#ifndef mozilla_dom_cache_Manager_h
|
||||
#define mozilla_dom_cache_Manager_h
|
||||
|
||||
#include "mozilla/dom/cache/CacheInitData.h"
|
||||
#include "mozilla/dom/cache/PCacheStreamControlParent.h"
|
||||
#include "mozilla/dom/cache/Types.h"
|
||||
#include "nsCOMPtr.h"
|
||||
@ -21,8 +22,6 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
class CacheOpArgs;
|
||||
class CacheOpResult;
|
||||
class CacheRequestResponse;
|
||||
class Context;
|
||||
class ManagerId;
|
||||
@ -87,36 +86,30 @@ public:
|
||||
class Listener
|
||||
{
|
||||
public:
|
||||
// convenience routines
|
||||
void
|
||||
OnOpComplete(nsresult aRv, const CacheOpResult& aResult);
|
||||
virtual void OnCacheMatch(RequestId aRequestId, nsresult aRv,
|
||||
const SavedResponse* aResponse,
|
||||
StreamList* aStreamList) { }
|
||||
virtual void OnCacheMatchAll(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<SavedResponse>& aSavedResponses,
|
||||
StreamList* aStreamList) { }
|
||||
virtual void OnCachePutAll(RequestId aRequestId, nsresult aRv) { }
|
||||
virtual void OnCacheDelete(RequestId aRequestId, nsresult aRv,
|
||||
bool aSuccess) { }
|
||||
virtual void OnCacheKeys(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<SavedRequest>& aSavedRequests,
|
||||
StreamList* aStreamList) { }
|
||||
|
||||
void
|
||||
OnOpComplete(nsresult aRv, const CacheOpResult& aResult,
|
||||
CacheId aOpenedCacheId);
|
||||
|
||||
void
|
||||
OnOpComplete(nsresult aRv, const CacheOpResult& aResult,
|
||||
const SavedResponse& aSavedResponse,
|
||||
StreamList* aStreamList);
|
||||
|
||||
void
|
||||
OnOpComplete(nsresult aRv, const CacheOpResult& aResult,
|
||||
const nsTArray<SavedResponse>& aSavedResponseList,
|
||||
StreamList* aStreamList);
|
||||
|
||||
void
|
||||
OnOpComplete(nsresult aRv, const CacheOpResult& aResult,
|
||||
const nsTArray<SavedRequest>& aSavedRequestList,
|
||||
StreamList* aStreamList);
|
||||
|
||||
// interface to be implemented
|
||||
virtual void
|
||||
OnOpComplete(nsresult aRv, const CacheOpResult& aResult,
|
||||
CacheId aOpenedCacheId,
|
||||
const nsTArray<SavedResponse>& aSavedResponseList,
|
||||
const nsTArray<SavedRequest>& aSavedRequestList,
|
||||
StreamList* aStreamList) { }
|
||||
virtual void OnStorageMatch(RequestId aRequestId, nsresult aRv,
|
||||
const SavedResponse* aResponse,
|
||||
StreamList* aStreamList) { }
|
||||
virtual void OnStorageHas(RequestId aRequestId, nsresult aRv,
|
||||
bool aCacheFound) { }
|
||||
virtual void OnStorageOpen(RequestId aRequestId, nsresult aRv,
|
||||
CacheId aCacheId) { }
|
||||
virtual void OnStorageDelete(RequestId aRequestId, nsresult aRv,
|
||||
bool aCacheDeleted) { }
|
||||
virtual void OnStorageKeys(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<nsString>& aKeys) { }
|
||||
|
||||
protected:
|
||||
~Listener() { }
|
||||
@ -157,15 +150,35 @@ public:
|
||||
void AddStreamList(StreamList* aStreamList);
|
||||
void RemoveStreamList(StreamList* aStreamList);
|
||||
|
||||
void ExecuteCacheOp(Listener* aListener, CacheId aCacheId,
|
||||
const CacheOpArgs& aOpArgs);
|
||||
void ExecutePutAll(Listener* aListener, CacheId aCacheId,
|
||||
const nsTArray<CacheRequestResponse>& aPutList,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreamList,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aResponseStreamList);
|
||||
// TODO: consider moving CacheId up in the argument lists below (bug 1110485)
|
||||
void CacheMatch(Listener* aListener, RequestId aRequestId, CacheId aCacheId,
|
||||
const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams);
|
||||
void CacheMatchAll(Listener* aListener, RequestId aRequestId,
|
||||
CacheId aCacheId, const PCacheRequestOrVoid& aRequestOrVoid,
|
||||
const PCacheQueryParams& aParams);
|
||||
void CachePutAll(Listener* aListener, RequestId aRequestId, CacheId aCacheId,
|
||||
const nsTArray<CacheRequestResponse>& aPutList,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreamList,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aResponseStreamList);
|
||||
void CacheDelete(Listener* aListener, RequestId aRequestId,
|
||||
CacheId aCacheId, const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams);
|
||||
void CacheKeys(Listener* aListener, RequestId aRequestId,
|
||||
CacheId aCacheId, const PCacheRequestOrVoid& aRequestOrVoid,
|
||||
const PCacheQueryParams& aParams);
|
||||
|
||||
void ExecuteStorageOp(Listener* aListener, Namespace aNamespace,
|
||||
const CacheOpArgs& aOpArgs);
|
||||
void StorageMatch(Listener* aListener, RequestId aRequestId,
|
||||
Namespace aNamespace, const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams);
|
||||
void StorageHas(Listener* aListener, RequestId aRequestId,
|
||||
Namespace aNamespace, const nsAString& aKey);
|
||||
void StorageOpen(Listener* aListener, RequestId aRequestId,
|
||||
Namespace aNamespace, const nsAString& aKey);
|
||||
void StorageDelete(Listener* aListener, RequestId aRequestId,
|
||||
Namespace aNamespace, const nsAString& aKey);
|
||||
void StorageKeys(Listener* aListener, RequestId aRequestId,
|
||||
Namespace aNamespace);
|
||||
|
||||
private:
|
||||
class Factory;
|
||||
|
20
dom/cache/PCache.ipdl
vendored
20
dom/cache/PCache.ipdl
vendored
@ -3,7 +3,6 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PBackground;
|
||||
include protocol PCacheOp;
|
||||
include protocol PCachePushStream;
|
||||
include PCacheTypes;
|
||||
include protocol PFileDescriptorSet;
|
||||
@ -11,6 +10,9 @@ include protocol PFileDescriptorSet;
|
||||
include protocol PBlob; // FIXME: bug 792908
|
||||
include protocol PCacheStreamControl;
|
||||
|
||||
using mozilla::dom::cache::RequestId from "mozilla/dom/cache/Types.h";
|
||||
include "mozilla/dom/cache/IPCUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
@ -18,15 +20,27 @@ namespace cache {
|
||||
protocol PCache
|
||||
{
|
||||
manager PBackground;
|
||||
manages PCacheOp;
|
||||
manages PCachePushStream;
|
||||
|
||||
parent:
|
||||
PCacheOp(CacheOpArgs aOpArgs);
|
||||
PCachePushStream();
|
||||
Teardown();
|
||||
Match(RequestId requestId, PCacheRequest request, PCacheQueryParams params);
|
||||
MatchAll(RequestId requestId, PCacheRequestOrVoid request, PCacheQueryParams params);
|
||||
AddAll(RequestId requestId, PCacheRequest[] requests);
|
||||
Put(RequestId requestId, CacheRequestResponse aPut);
|
||||
Delete(RequestId requestId, PCacheRequest request, PCacheQueryParams params);
|
||||
Keys(RequestId requestId, PCacheRequestOrVoid request, PCacheQueryParams params);
|
||||
|
||||
child:
|
||||
MatchResponse(RequestId requestId, nsresult aRv, PCacheResponseOrVoid aResponse);
|
||||
MatchAllResponse(RequestId requestId, nsresult aRv, PCacheResponse[] responses);
|
||||
AddAllResponse(RequestId requestId, nsresult aRv);
|
||||
PutResponse(RequestId requestId, nsresult aRv);
|
||||
DeleteResponse(RequestId requestId, nsresult aRv, bool success);
|
||||
KeysResponse(RequestId requestId, nsresult aRv, PCacheRequest[] requests);
|
||||
|
||||
both:
|
||||
__delete__();
|
||||
};
|
||||
|
||||
|
29
dom/cache/PCacheOp.ipdl
vendored
29
dom/cache/PCacheOp.ipdl
vendored
@ -1,29 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PCache;
|
||||
include protocol PCacheStorage;
|
||||
|
||||
// these are needed indirectly through CacheOpResult
|
||||
include protocol PCachePushStream;
|
||||
include protocol PCacheStreamControl;
|
||||
include protocol PFileDescriptorSet;
|
||||
|
||||
include PCacheTypes;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
protocol PCacheOp
|
||||
{
|
||||
manager PCache or PCacheStorage;
|
||||
|
||||
child:
|
||||
__delete__(nsresult aStatus, CacheOpResult aResult);
|
||||
};
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
17
dom/cache/PCacheStorage.ipdl
vendored
17
dom/cache/PCacheStorage.ipdl
vendored
@ -4,13 +4,14 @@
|
||||
|
||||
include protocol PBackground;
|
||||
include protocol PCache;
|
||||
include protocol PCacheOp;
|
||||
include PCacheTypes;
|
||||
include protocol PFileDescriptorSet;
|
||||
|
||||
include protocol PBlob; // FIXME: bug 792908
|
||||
include protocol PCacheStreamControl;
|
||||
|
||||
using mozilla::dom::cache::RequestId from "mozilla/dom/cache/IPCUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
@ -18,13 +19,23 @@ namespace cache {
|
||||
protocol PCacheStorage
|
||||
{
|
||||
manager PBackground;
|
||||
manages PCacheOp;
|
||||
|
||||
parent:
|
||||
PCacheOp(CacheOpArgs aOpArgs);
|
||||
Teardown();
|
||||
Match(RequestId aRequestId, PCacheRequest aRequest,
|
||||
PCacheQueryParams aParams);
|
||||
Has(RequestId aRequestId, nsString aKey);
|
||||
Open(RequestId aRequestId, nsString aKey);
|
||||
Delete(RequestId aRequestId, nsString aKey);
|
||||
Keys(RequestId aRequestId);
|
||||
|
||||
child:
|
||||
MatchResponse(RequestId aRequestId, nsresult aRv,
|
||||
PCacheResponseOrVoid aResponseOrVoid);
|
||||
HasResponse(RequestId aRequestId, nsresult aRv, bool aSuccess);
|
||||
OpenResponse(RequestId aRequestId, nsresult aRv, nullable PCache aActor);
|
||||
DeleteResponse(RequestId aRequestId, nsresult aRv, bool aSuccess);
|
||||
KeysResponse(RequestId aRequestId, nsresult aRv, nsString[] aKeys);
|
||||
__delete__();
|
||||
};
|
||||
|
||||
|
144
dom/cache/PCacheTypes.ipdlh
vendored
144
dom/cache/PCacheTypes.ipdlh
vendored
@ -2,7 +2,6 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PCache;
|
||||
include protocol PCachePushStream;
|
||||
include protocol PCacheStreamControl;
|
||||
include PHeaders;
|
||||
@ -91,149 +90,6 @@ struct CacheRequestResponse
|
||||
PCacheResponse response;
|
||||
};
|
||||
|
||||
struct CacheMatchArgs
|
||||
{
|
||||
PCacheRequest request;
|
||||
PCacheQueryParams params;
|
||||
};
|
||||
|
||||
struct CacheMatchAllArgs
|
||||
{
|
||||
PCacheRequestOrVoid requestOrVoid;
|
||||
PCacheQueryParams params;
|
||||
};
|
||||
|
||||
struct CacheAddAllArgs
|
||||
{
|
||||
PCacheRequest[] requestList;
|
||||
};
|
||||
|
||||
struct CachePutAllArgs
|
||||
{
|
||||
CacheRequestResponse[] requestResponseList;
|
||||
};
|
||||
|
||||
struct CacheDeleteArgs
|
||||
{
|
||||
PCacheRequest request;
|
||||
PCacheQueryParams params;
|
||||
};
|
||||
|
||||
struct CacheKeysArgs
|
||||
{
|
||||
PCacheRequestOrVoid requestOrVoid;
|
||||
PCacheQueryParams params;
|
||||
};
|
||||
|
||||
struct StorageMatchArgs
|
||||
{
|
||||
PCacheRequest request;
|
||||
PCacheQueryParams params;
|
||||
};
|
||||
|
||||
struct StorageHasArgs
|
||||
{
|
||||
nsString key;
|
||||
};
|
||||
|
||||
struct StorageOpenArgs
|
||||
{
|
||||
nsString key;
|
||||
};
|
||||
|
||||
struct StorageDeleteArgs
|
||||
{
|
||||
nsString key;
|
||||
};
|
||||
|
||||
struct StorageKeysArgs
|
||||
{
|
||||
};
|
||||
|
||||
union CacheOpArgs
|
||||
{
|
||||
CacheMatchArgs;
|
||||
CacheMatchAllArgs;
|
||||
CacheAddAllArgs;
|
||||
CachePutAllArgs;
|
||||
CacheDeleteArgs;
|
||||
CacheKeysArgs;
|
||||
StorageMatchArgs;
|
||||
StorageHasArgs;
|
||||
StorageOpenArgs;
|
||||
StorageDeleteArgs;
|
||||
StorageKeysArgs;
|
||||
};
|
||||
|
||||
struct CacheMatchResult
|
||||
{
|
||||
PCacheResponseOrVoid responseOrVoid;
|
||||
};
|
||||
|
||||
struct CacheMatchAllResult
|
||||
{
|
||||
PCacheResponse[] responseList;
|
||||
};
|
||||
|
||||
struct CacheAddAllResult
|
||||
{
|
||||
};
|
||||
|
||||
struct CachePutAllResult
|
||||
{
|
||||
};
|
||||
|
||||
struct CacheDeleteResult
|
||||
{
|
||||
bool success;
|
||||
};
|
||||
|
||||
struct CacheKeysResult
|
||||
{
|
||||
PCacheRequest[] requestList;
|
||||
};
|
||||
|
||||
struct StorageMatchResult
|
||||
{
|
||||
PCacheResponseOrVoid responseOrVoid;
|
||||
};
|
||||
|
||||
struct StorageHasResult
|
||||
{
|
||||
bool success;
|
||||
};
|
||||
|
||||
struct StorageOpenResult
|
||||
{
|
||||
nullable PCache actor;
|
||||
};
|
||||
|
||||
struct StorageDeleteResult
|
||||
{
|
||||
bool success;
|
||||
};
|
||||
|
||||
struct StorageKeysResult
|
||||
{
|
||||
nsString[] keyList;
|
||||
};
|
||||
|
||||
union CacheOpResult
|
||||
{
|
||||
void_t;
|
||||
CacheMatchResult;
|
||||
CacheMatchAllResult;
|
||||
CacheAddAllResult;
|
||||
CachePutAllResult;
|
||||
CacheDeleteResult;
|
||||
CacheKeysResult;
|
||||
StorageMatchResult;
|
||||
StorageHasResult;
|
||||
StorageOpenResult;
|
||||
StorageDeleteResult;
|
||||
StorageKeysResult;
|
||||
};
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
38
dom/cache/PrincipalVerifier.cpp
vendored
38
dom/cache/PrincipalVerifier.cpp
vendored
@ -46,35 +46,25 @@ PrincipalVerifier::CreateAndDispatch(Listener* aListener,
|
||||
}
|
||||
|
||||
void
|
||||
PrincipalVerifier::AddListener(Listener* aListener)
|
||||
PrincipalVerifier::ClearListener()
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aListener);
|
||||
MOZ_ASSERT(!mListenerList.Contains(aListener));
|
||||
mListenerList.AppendElement(aListener);
|
||||
}
|
||||
|
||||
void
|
||||
PrincipalVerifier::RemoveListener(Listener* aListener)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aListener);
|
||||
MOZ_ALWAYS_TRUE(mListenerList.RemoveElement(aListener));
|
||||
MOZ_ASSERT(mListener);
|
||||
mListener = nullptr;
|
||||
}
|
||||
|
||||
PrincipalVerifier::PrincipalVerifier(Listener* aListener,
|
||||
PBackgroundParent* aActor,
|
||||
const PrincipalInfo& aPrincipalInfo)
|
||||
: mActor(BackgroundParent::GetContentParent(aActor))
|
||||
: mListener(aListener)
|
||||
, mActor(BackgroundParent::GetContentParent(aActor))
|
||||
, mPrincipalInfo(aPrincipalInfo)
|
||||
, mInitiatingThread(NS_GetCurrentThread())
|
||||
, mResult(NS_OK)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mListener);
|
||||
MOZ_ASSERT(mInitiatingThread);
|
||||
MOZ_ASSERT(aListener);
|
||||
|
||||
mListenerList.AppendElement(aListener);
|
||||
}
|
||||
|
||||
PrincipalVerifier::~PrincipalVerifier()
|
||||
@ -83,7 +73,7 @@ PrincipalVerifier::~PrincipalVerifier()
|
||||
// threads, its a race to see which thread de-refs us last. Therefore
|
||||
// we cannot guarantee which thread we destruct on.
|
||||
|
||||
MOZ_ASSERT(mListenerList.IsEmpty());
|
||||
MOZ_ASSERT(!mListener);
|
||||
|
||||
// We should always be able to explicitly release the actor on the main
|
||||
// thread.
|
||||
@ -182,13 +172,17 @@ void
|
||||
PrincipalVerifier::CompleteOnInitiatingThread()
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
ListenerList::ForwardIterator iter(mListenerList);
|
||||
while (iter.HasMore()) {
|
||||
iter.GetNext()->OnPrincipalVerified(mResult, mManagerId);
|
||||
|
||||
// This can happen if the listener is destroyed before we finish. For
|
||||
// example, if the child process OOMs and the actor is destroyed.
|
||||
if (!mListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The listener must clear its reference in OnPrincipalVerified()
|
||||
MOZ_ASSERT(mListenerList.IsEmpty());
|
||||
mListener->OnPrincipalVerified(mResult, mManagerId);
|
||||
|
||||
// The listener must clear their reference in OnPrincipalVerified()
|
||||
MOZ_ASSERT(!mListener);
|
||||
}
|
||||
|
||||
void
|
||||
|
14
dom/cache/PrincipalVerifier.h
vendored
14
dom/cache/PrincipalVerifier.h
vendored
@ -9,7 +9,6 @@
|
||||
|
||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsTObserverArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -27,7 +26,7 @@ class PrincipalVerifier final : public nsRunnable
|
||||
public:
|
||||
// An interface to be implemented by code wishing to use the
|
||||
// PrincipalVerifier. Note, the Listener implementation is responsible
|
||||
// for calling RemoveListener() on the PrincipalVerifier to clear the
|
||||
// for calling ClearListener() on the PrincipalVerifier to clear the
|
||||
// weak reference.
|
||||
class Listener
|
||||
{
|
||||
@ -39,11 +38,9 @@ public:
|
||||
CreateAndDispatch(Listener* aListener, mozilla::ipc::PBackgroundParent* aActor,
|
||||
const mozilla::ipc::PrincipalInfo& aPrincipalInfo);
|
||||
|
||||
void AddListener(Listener* aListener);
|
||||
|
||||
// The Listener must call RemoveListener() when OnPrincipalVerified() is
|
||||
// The Listener must call ClearListener() when OnPrincipalVerified() is
|
||||
// called or when the Listener is destroyed.
|
||||
void RemoveListener(Listener* aListener);
|
||||
void ClearListener();
|
||||
|
||||
private:
|
||||
PrincipalVerifier(Listener* aListener, mozilla::ipc::PBackgroundParent* aActor,
|
||||
@ -55,9 +52,8 @@ private:
|
||||
|
||||
void DispatchToInitiatingThread(nsresult aRv);
|
||||
|
||||
// Weak reference cleared by RemoveListener()
|
||||
typedef nsTObserverArray<Listener*> ListenerList;
|
||||
ListenerList mListenerList;
|
||||
// Weak reference cleared by ClearListener()
|
||||
Listener* mListener;
|
||||
|
||||
// set in originating thread at construction, but must be accessed and
|
||||
// released on main thread
|
||||
|
4
dom/cache/Types.h
vendored
4
dom/cache/Types.h
vendored
@ -22,7 +22,9 @@ enum Namespace
|
||||
CHROME_ONLY_NAMESPACE,
|
||||
NUMBER_OF_NAMESPACES
|
||||
};
|
||||
static const Namespace INVALID_NAMESPACE = NUMBER_OF_NAMESPACES;
|
||||
|
||||
typedef uintptr_t RequestId;
|
||||
static const RequestId INVALID_REQUEST_ID = 0;
|
||||
|
||||
typedef int64_t CacheId;
|
||||
static const CacheId INVALID_CACHE_ID = -1;
|
||||
|
6
dom/cache/moz.build
vendored
6
dom/cache/moz.build
vendored
@ -11,8 +11,6 @@ EXPORTS.mozilla.dom.cache += [
|
||||
'AutoUtils.h',
|
||||
'Cache.h',
|
||||
'CacheChild.h',
|
||||
'CacheOpChild.h',
|
||||
'CacheOpParent.h',
|
||||
'CacheParent.h',
|
||||
'CachePushStreamChild.h',
|
||||
'CachePushStreamParent.h',
|
||||
@ -48,8 +46,6 @@ UNIFIED_SOURCES += [
|
||||
'AutoUtils.cpp',
|
||||
'Cache.cpp',
|
||||
'CacheChild.cpp',
|
||||
'CacheOpChild.cpp',
|
||||
'CacheOpParent.cpp',
|
||||
'CacheParent.cpp',
|
||||
'CachePushStreamChild.cpp',
|
||||
'CachePushStreamParent.cpp',
|
||||
@ -77,8 +73,8 @@ UNIFIED_SOURCES += [
|
||||
]
|
||||
|
||||
IPDL_SOURCES += [
|
||||
'CacheInitData.ipdlh',
|
||||
'PCache.ipdl',
|
||||
'PCacheOp.ipdl',
|
||||
'PCachePushStream.ipdl',
|
||||
'PCacheStorage.ipdl',
|
||||
'PCacheStreamControl.ipdl',
|
||||
|
Loading…
Reference in New Issue
Block a user