ClientHandleOpParent.cpp (3851B)
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/. */ 6 7 #include "ClientHandleOpParent.h" 8 9 #include "ClientHandleParent.h" 10 #include "ClientSourceParent.h" 11 #include "mozilla/dom/PClientManagerParent.h" 12 #include "mozilla/dom/ipc/StructuredCloneData.h" 13 14 namespace mozilla::dom { 15 16 ClientSourceParent* ClientHandleOpParent::GetSource() const { 17 auto handle = static_cast<ClientHandleParent*>(Manager()); 18 return handle->GetSource(); 19 } 20 21 void ClientHandleOpParent::ActorDestroy(ActorDestroyReason aReason) { 22 mPromiseRequestHolder.DisconnectIfExists(); 23 mSourcePromiseRequestHolder.DisconnectIfExists(); 24 } 25 26 void ClientHandleOpParent::Init(ClientOpConstructorArgs&& aArgs) { 27 RefPtr<ClientHandleParent> handle = 28 static_cast<ClientHandleParent*>(Manager()); 29 handle->EnsureSource() 30 ->Then( 31 GetCurrentSerialEventTarget(), __func__, 32 [this, handle, args = std::move(aArgs)](bool) mutable { 33 mSourcePromiseRequestHolder.Complete(); 34 35 auto source = handle->GetSource(); 36 if (!source) { 37 CopyableErrorResult rv; 38 rv.ThrowAbortError("Client has been destroyed"); 39 (void)PClientHandleOpParent::Send__delete__(this, rv); 40 return; 41 } 42 RefPtr<ClientOpPromise> p; 43 44 // ClientPostMessageArgs can contain PBlob actors. This means we 45 // can't just forward the args from one PBackground manager to 46 // another. Instead, unpack the structured clone data and repack 47 // it into a new set of arguments. 48 if (args.type() == 49 ClientOpConstructorArgs::TClientPostMessageArgs) { 50 const ClientPostMessageArgs& orig = 51 args.get_ClientPostMessageArgs(); 52 53 ClientPostMessageArgs rebuild; 54 rebuild.serviceWorker() = orig.serviceWorker(); 55 56 ipc::StructuredCloneData data; 57 data.BorrowFromClonedMessageData(orig.clonedData()); 58 if (!data.BuildClonedMessageData(rebuild.clonedData())) { 59 CopyableErrorResult rv; 60 rv.ThrowAbortError("Aborting client operation"); 61 (void)PClientHandleOpParent::Send__delete__(this, rv); 62 return; 63 } 64 65 p = source->StartOp(std::move(rebuild)); 66 } 67 68 // Other argument types can just be forwarded straight through. 69 else { 70 p = source->StartOp(std::move(args)); 71 } 72 73 // Capturing 'this' is safe here because we disconnect the promise 74 // in ActorDestroy() which ensures neither lambda is called if the 75 // actor is destroyed before the source operation completes. 76 p->Then( 77 GetCurrentSerialEventTarget(), __func__, 78 [this](const ClientOpResult& aResult) { 79 mPromiseRequestHolder.Complete(); 80 (void)PClientHandleOpParent::Send__delete__(this, aResult); 81 }, 82 [this](const CopyableErrorResult& aRv) { 83 mPromiseRequestHolder.Complete(); 84 (void)PClientHandleOpParent::Send__delete__(this, aRv); 85 }) 86 ->Track(mPromiseRequestHolder); 87 }, 88 [=](const CopyableErrorResult& failure) { 89 mSourcePromiseRequestHolder.Complete(); 90 (void)PClientHandleOpParent::Send__delete__(this, failure); 91 return; 92 }) 93 ->Track(mSourcePromiseRequestHolder); 94 } 95 96 } // namespace mozilla::dom