JSProcessActorParent.cpp (3364B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ 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 "mozilla/dom/JSProcessActorParent.h" 8 9 #include "mozilla/dom/InProcessChild.h" 10 #include "mozilla/dom/InProcessParent.h" 11 #include "mozilla/dom/JSIPCValue.h" 12 #include "mozilla/dom/JSIPCValueUtils.h" 13 #include "mozilla/dom/JSProcessActorBinding.h" 14 15 namespace mozilla::dom { 16 17 NS_IMPL_CYCLE_COLLECTION_INHERITED(JSProcessActorParent, JSActor, mManager) 18 19 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(JSProcessActorParent) 20 NS_INTERFACE_MAP_END_INHERITING(JSActor) 21 22 NS_IMPL_ADDREF_INHERITED(JSProcessActorParent, JSActor) 23 NS_IMPL_RELEASE_INHERITED(JSProcessActorParent, JSActor) 24 25 JSObject* JSProcessActorParent::WrapObject(JSContext* aCx, 26 JS::Handle<JSObject*> aGivenProto) { 27 return JSProcessActorParent_Binding::Wrap(aCx, this, aGivenProto); 28 } 29 30 void JSProcessActorParent::Init(const nsACString& aName, 31 nsIDOMProcessParent* aManager) { 32 MOZ_ASSERT(!mManager, "Cannot Init() a JSProcessActorParent twice!"); 33 mManager = aManager; 34 JSActor::Init(aName, /* aSendTyped= */ false); 35 } 36 37 JSProcessActorParent::~JSProcessActorParent() { MOZ_ASSERT(!mManager); } 38 39 void JSProcessActorParent::SendRawMessage( 40 const JSActorMessageMeta& aMeta, JSIPCValue&& aData, 41 UniquePtr<ipc::StructuredCloneData> aStack, ErrorResult& aRv) { 42 if (NS_WARN_IF(!CanSend() || !mManager || !mManager->GetCanSend())) { 43 aRv.ThrowInvalidStateError( 44 nsPrintfCString("Actor '%s' cannot send message '%s' during shutdown.", 45 PromiseFlatCString(aMeta.actorName()).get(), 46 NS_ConvertUTF16toUTF8(aMeta.messageName()).get())); 47 return; 48 } 49 50 // If the parent side is in the same process, we have a PInProcess manager, 51 // and can dispatch the message directly to the event loop. 52 ContentParent* contentParent = mManager->AsContentParent(); 53 if (!contentParent) { 54 SendRawMessageInProcess(aMeta, std::move(aData), std::move(aStack), []() { 55 return do_AddRef(InProcessChild::Singleton()); 56 }); 57 return; 58 } 59 60 // Cross-process case - send data over ContentParent to other side. 61 JSIPCValueUtils::SCDHolder holder; 62 if (NS_WARN_IF(!JSIPCValueUtils::PrepareForSending(holder, aData))) { 63 aRv.ThrowDataCloneError( 64 nsPrintfCString("Actor '%s' cannot send message '%s': cannot clone.", 65 PromiseFlatCString(aMeta.actorName()).get(), 66 NS_ConvertUTF16toUTF8(aMeta.messageName()).get())); 67 return; 68 } 69 70 UniquePtr<ClonedMessageData> stackData; 71 if (aStack) { 72 stackData = MakeUnique<ClonedMessageData>(); 73 if (!aStack->BuildClonedMessageData(*stackData)) { 74 stackData.reset(); 75 } 76 } 77 78 if (NS_WARN_IF(!contentParent->SendRawMessage(aMeta, aData, stackData))) { 79 aRv.ThrowOperationError( 80 nsPrintfCString("JSProcessActorParent send error in actor '%s'", 81 PromiseFlatCString(aMeta.actorName()).get())); 82 return; 83 } 84 } 85 86 void JSProcessActorParent::ClearManager() { mManager = nullptr; } 87 88 } // namespace mozilla::dom