diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /dom/cache/CacheOpParent.cpp | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/cache/CacheOpParent.cpp')
-rw-r--r-- | dom/cache/CacheOpParent.cpp | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/dom/cache/CacheOpParent.cpp b/dom/cache/CacheOpParent.cpp new file mode 100644 index 000000000..992ee82a7 --- /dev/null +++ b/dom/cache/CacheOpParent.cpp @@ -0,0 +1,230 @@ +/* -*- 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/ReadStream.h" +#include "mozilla/dom/cache/SavedTypes.h" +#include "mozilla/ipc/FileDescriptorSetParent.h" +#include "mozilla/ipc/InputStreamUtils.h" +#include "mozilla/ipc/SendStream.h" + +namespace mozilla { +namespace dom { +namespace cache { + +using mozilla::ipc::FileDescriptorSetParent; +using mozilla::ipc::PBackgroundParent; +using mozilla::ipc::SendStreamParent; + +CacheOpParent::CacheOpParent(PBackgroundParent* aIpcManager, CacheId aCacheId, + const CacheOpArgs& aOpArgs) + : mIpcManager(aIpcManager) + , mCacheId(aCacheId) + , mNamespace(INVALID_NAMESPACE) + , mOpArgs(aOpArgs) +{ + MOZ_DIAGNOSTIC_ASSERT(mIpcManager); +} + +CacheOpParent::CacheOpParent(PBackgroundParent* aIpcManager, + Namespace aNamespace, const CacheOpArgs& aOpArgs) + : mIpcManager(aIpcManager) + , mCacheId(INVALID_CACHE_ID) + , mNamespace(aNamespace) + , mOpArgs(aOpArgs) +{ + MOZ_DIAGNOSTIC_ASSERT(mIpcManager); +} + +CacheOpParent::~CacheOpParent() +{ + NS_ASSERT_OWNINGTHREAD(CacheOpParent); +} + +void +CacheOpParent::Execute(ManagerId* aManagerId) +{ + NS_ASSERT_OWNINGTHREAD(CacheOpParent); + MOZ_DIAGNOSTIC_ASSERT(!mManager); + MOZ_DIAGNOSTIC_ASSERT(!mVerifier); + + RefPtr<cache::Manager> manager; + nsresult rv = cache::Manager::GetOrCreate(aManagerId, getter_AddRefs(manager)); + if (NS_WARN_IF(NS_FAILED(rv))) { + ErrorResult result(rv); + Unused << Send__delete__(this, result, void_t()); + result.SuppressException(); + return; + } + + Execute(manager); +} + +void +CacheOpParent::Execute(cache::Manager* aManager) +{ + NS_ASSERT_OWNINGTHREAD(CacheOpParent); + MOZ_DIAGNOSTIC_ASSERT(!mManager); + MOZ_DIAGNOSTIC_ASSERT(!mVerifier); + + mManager = aManager; + + // Handle put op + if (mOpArgs.type() == CacheOpArgs::TCachePutAllArgs) { + MOZ_DIAGNOSTIC_ASSERT(mCacheId != INVALID_CACHE_ID); + + const CachePutAllArgs& args = mOpArgs.get_CachePutAllArgs(); + const nsTArray<CacheRequestResponse>& list = args.requestResponseList(); + + AutoTArray<nsCOMPtr<nsIInputStream>, 256> requestStreamList; + AutoTArray<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_DIAGNOSTIC_ASSERT(mNamespace == INVALID_NAMESPACE); + mManager->ExecuteCacheOp(this, mCacheId, mOpArgs); + return; + } + + // Handle all storage ops + MOZ_DIAGNOSTIC_ASSERT(mNamespace != INVALID_NAMESPACE); + mManager->ExecuteStorageOp(this, mNamespace, mOpArgs); +} + +void +CacheOpParent::WaitForVerification(PrincipalVerifier* aVerifier) +{ + NS_ASSERT_OWNINGTHREAD(CacheOpParent); + MOZ_DIAGNOSTIC_ASSERT(!mManager); + MOZ_DIAGNOSTIC_ASSERT(!mVerifier); + + mVerifier = aVerifier; + mVerifier->AddListener(this); +} + +void +CacheOpParent::ActorDestroy(ActorDestroyReason aReason) +{ + NS_ASSERT_OWNINGTHREAD(CacheOpParent); + + if (mVerifier) { + mVerifier->RemoveListener(this); + mVerifier = nullptr; + } + + 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))) { + ErrorResult result(aRv); + Unused << Send__delete__(this, result, void_t()); + result.SuppressException(); + return; + } + + Execute(aManagerId); +} + +void +CacheOpParent::OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult, + CacheId aOpenedCacheId, + const nsTArray<SavedResponse>& aSavedResponseList, + const nsTArray<SavedRequest>& aSavedRequestList, + StreamList* aStreamList) +{ + NS_ASSERT_OWNINGTHREAD(CacheOpParent); + MOZ_DIAGNOSTIC_ASSERT(mIpcManager); + MOZ_DIAGNOSTIC_ASSERT(mManager); + + // Never send an op-specific result if we have an error. Instead, send + // void_t() to ensure that we don't leak actors on the child side. + if (NS_WARN_IF(aRv.Failed())) { + Unused << Send__delete__(this, aRv, void_t()); + aRv.SuppressException(); // We serialiazed it, as best we could. + return; + } + + uint32_t entryCount = std::max(1lu, static_cast<unsigned long>( + std::max(aSavedResponseList.Length(), + aSavedRequestList.Length()))); + + // 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, entryCount); + + 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()); +} + +already_AddRefed<nsIInputStream> +CacheOpParent::DeserializeCacheStream(const CacheReadStreamOrVoid& aStreamOrVoid) +{ + if (aStreamOrVoid.type() == CacheReadStreamOrVoid::Tvoid_t) { + return nullptr; + } + + nsCOMPtr<nsIInputStream> stream; + const CacheReadStream& readStream = aStreamOrVoid.get_CacheReadStream(); + + // Option 1: 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 2: A stream was serialized using normal methods or passed + // as a PSendStream actor. Use the standard method for + // extracting the resulting stream. + return DeserializeIPCStream(readStream.stream()); +} + +} // namespace cache +} // namespace dom +} // namespace mozilla |