Backed out changeset 1d9301697aa0 (bug 1887752) for causing failures on browser_all_f...
[gecko.git] / dom / cache / CacheOpChild.cpp
blobb0c5c78bfc88bb8b7a5e0561fb965e380f57c9e9
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/cache/CacheOpChild.h"
9 #include "mozilla/dom/Promise.h"
10 #include "mozilla/dom/Request.h"
11 #include "mozilla/dom/Response.h"
12 #include "mozilla/dom/cache/Cache.h"
13 #include "mozilla/dom/cache/CacheChild.h"
14 #include "mozilla/dom/cache/CacheStreamControlChild.h"
15 #include "mozilla/dom/cache/CacheWorkerRef.h"
17 namespace mozilla::dom {
18 // XXX Move this to ToJSValue.h
19 template <typename T>
20 [[nodiscard]] bool ToJSValue(JSContext* aCx, const SafeRefPtr<T>& aArgument,
21 JS::MutableHandle<JS::Value> aValue) {
22 return ToJSValue(aCx, *aArgument.unsafeGetRawPtr(), aValue);
25 namespace cache {
27 using mozilla::ipc::PBackgroundChild;
29 namespace {
31 void AddWorkerRefToStreamChild(const CacheReadStream& aReadStream,
32 const SafeRefPtr<CacheWorkerRef>& aWorkerRef) {
33 MOZ_ASSERT_IF(!NS_IsMainThread(), aWorkerRef);
34 CacheStreamControlChild* cacheControl =
35 static_cast<CacheStreamControlChild*>(aReadStream.control().AsChild());
36 if (cacheControl) {
37 cacheControl->SetWorkerRef(aWorkerRef.clonePtr());
41 void AddWorkerRefToStreamChild(const CacheResponse& aResponse,
42 const SafeRefPtr<CacheWorkerRef>& aWorkerRef) {
43 MOZ_ASSERT_IF(!NS_IsMainThread(), aWorkerRef);
45 if (aResponse.body().isNothing()) {
46 return;
49 AddWorkerRefToStreamChild(aResponse.body().ref(), aWorkerRef);
52 void AddWorkerRefToStreamChild(const CacheRequest& aRequest,
53 const SafeRefPtr<CacheWorkerRef>& aWorkerRef) {
54 MOZ_ASSERT_IF(!NS_IsMainThread(), aWorkerRef);
56 if (aRequest.body().isNothing()) {
57 return;
60 AddWorkerRefToStreamChild(aRequest.body().ref(), aWorkerRef);
63 } // namespace
65 CacheOpChild::CacheOpChild(SafeRefPtr<CacheWorkerRef> aWorkerRef,
66 nsIGlobalObject* aGlobal, nsISupports* aParent,
67 Promise* aPromise, ActorChild* aParentActor)
68 : mGlobal(aGlobal),
69 mParent(aParent),
70 mPromise(aPromise),
71 mParentActor(aParentActor) {
72 MOZ_DIAGNOSTIC_ASSERT(mGlobal);
73 MOZ_DIAGNOSTIC_ASSERT(mParent);
74 MOZ_DIAGNOSTIC_ASSERT(mPromise);
76 MOZ_ASSERT_IF(!NS_IsMainThread(), aWorkerRef);
78 SetWorkerRef(CacheWorkerRef::PreferBehavior(
79 std::move(aWorkerRef), CacheWorkerRef::eStrongWorkerRef));
82 CacheOpChild::~CacheOpChild() {
83 NS_ASSERT_OWNINGTHREAD(CacheOpChild);
84 MOZ_DIAGNOSTIC_ASSERT(!mPromise);
87 void CacheOpChild::ActorDestroy(ActorDestroyReason aReason) {
88 NS_ASSERT_OWNINGTHREAD(CacheOpChild);
90 // If the actor was terminated for some unknown reason, then indicate the
91 // operation is dead.
92 if (mPromise) {
93 mPromise->MaybeReject(NS_ERROR_FAILURE);
94 mPromise = nullptr;
96 mParentActor->NoteDeletedActor();
97 RemoveWorkerRef();
100 mozilla::ipc::IPCResult CacheOpChild::Recv__delete__(
101 ErrorResult&& aRv, const CacheOpResult& aResult) {
102 NS_ASSERT_OWNINGTHREAD(CacheOpChild);
104 if (NS_WARN_IF(aRv.Failed())) {
105 MOZ_DIAGNOSTIC_ASSERT(aResult.type() == CacheOpResult::Tvoid_t);
106 mPromise->MaybeReject(std::move(aRv));
107 mPromise = nullptr;
108 return IPC_OK();
111 switch (aResult.type()) {
112 case CacheOpResult::TCacheMatchResult: {
113 HandleResponse(aResult.get_CacheMatchResult().maybeResponse());
114 break;
116 case CacheOpResult::TCacheMatchAllResult: {
117 HandleResponseList(aResult.get_CacheMatchAllResult().responseList());
118 break;
120 case CacheOpResult::TCachePutAllResult: {
121 mPromise->MaybeResolveWithUndefined();
122 break;
124 case CacheOpResult::TCacheDeleteResult: {
125 mPromise->MaybeResolve(aResult.get_CacheDeleteResult().success());
126 break;
128 case CacheOpResult::TCacheKeysResult: {
129 HandleRequestList(aResult.get_CacheKeysResult().requestList());
130 break;
132 case CacheOpResult::TStorageMatchResult: {
133 HandleResponse(aResult.get_StorageMatchResult().maybeResponse());
134 break;
136 case CacheOpResult::TStorageHasResult: {
137 mPromise->MaybeResolve(aResult.get_StorageHasResult().success());
138 break;
140 case CacheOpResult::TStorageOpenResult: {
141 auto result = aResult.get_StorageOpenResult();
142 auto actor = static_cast<CacheChild*>(result.actor().AsChild());
144 // If we have a success status then we should have an actor. Gracefully
145 // reject instead of crashing, though, if we get a nullptr here.
146 MOZ_DIAGNOSTIC_ASSERT(actor);
147 if (!actor) {
148 mPromise->MaybeRejectWithTypeError(
149 "CacheStorage.open() failed to access the storage system.");
150 break;
153 actor->SetWorkerRef(CacheWorkerRef::PreferBehavior(
154 GetWorkerRefPtr().clonePtr(), CacheWorkerRef::eIPCWorkerRef));
155 RefPtr<Cache> cache = new Cache(mGlobal, actor, result.ns());
156 mPromise->MaybeResolve(cache);
157 break;
159 case CacheOpResult::TStorageDeleteResult: {
160 mPromise->MaybeResolve(aResult.get_StorageDeleteResult().success());
161 break;
163 case CacheOpResult::TStorageKeysResult: {
164 mPromise->MaybeResolve(aResult.get_StorageKeysResult().keyList());
165 break;
167 default:
168 MOZ_CRASH("Unknown Cache op result type!");
171 mPromise = nullptr;
173 return IPC_OK();
176 void CacheOpChild::StartDestroy() {
177 NS_ASSERT_OWNINGTHREAD(CacheOpChild);
179 // Do not cancel on-going operations when WorkerRef calls this. Instead,
180 // keep the Worker alive until we are done.
183 nsIGlobalObject* CacheOpChild::GetGlobalObject() const { return mGlobal; }
185 #ifdef DEBUG
186 void CacheOpChild::AssertOwningThread() const {
187 NS_ASSERT_OWNINGTHREAD(CacheOpChild);
189 #endif
191 PBackgroundChild* CacheOpChild::GetIPCManager() {
192 MOZ_CRASH("CacheOpChild does not implement TypeUtils::GetIPCManager()");
195 void CacheOpChild::HandleResponse(const Maybe<CacheResponse>& aMaybeResponse) {
196 if (aMaybeResponse.isNothing()) {
197 mPromise->MaybeResolveWithUndefined();
198 return;
201 const CacheResponse& cacheResponse = aMaybeResponse.ref();
203 AddWorkerRefToStreamChild(cacheResponse, GetWorkerRefPtr());
204 RefPtr<Response> response = ToResponse(cacheResponse);
206 mPromise->MaybeResolve(response);
209 void CacheOpChild::HandleResponseList(
210 const nsTArray<CacheResponse>& aResponseList) {
211 AutoTArray<RefPtr<Response>, 256> responses;
212 responses.SetCapacity(aResponseList.Length());
214 for (uint32_t i = 0; i < aResponseList.Length(); ++i) {
215 AddWorkerRefToStreamChild(aResponseList[i], GetWorkerRefPtr());
216 responses.AppendElement(ToResponse(aResponseList[i]));
219 mPromise->MaybeResolve(responses);
222 void CacheOpChild::HandleRequestList(
223 const nsTArray<CacheRequest>& aRequestList) {
224 AutoTArray<SafeRefPtr<Request>, 256> requests;
225 requests.SetCapacity(aRequestList.Length());
227 for (uint32_t i = 0; i < aRequestList.Length(); ++i) {
228 AddWorkerRefToStreamChild(aRequestList[i], GetWorkerRefPtr());
229 requests.AppendElement(ToRequest(aRequestList[i]));
232 mPromise->MaybeResolve(requests);
235 } // namespace cache
236 } // namespace mozilla::dom