JSOracleParent.cpp (2699B)
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 "mozilla/dom/JSOracleParent.h" 8 9 #include "mozilla/ClearOnShutdown.h" 10 #include "mozilla/RefPtr.h" 11 #include "mozilla/dom/PJSOracle.h" 12 #include "mozilla/ipc/Endpoint.h" 13 #include "mozilla/ipc/UtilityProcessManager.h" 14 15 using namespace mozilla; 16 using namespace mozilla::dom; 17 18 static StaticRefPtr<JSOracleParent> sOracleSingleton; 19 20 /* static */ 21 void JSOracleParent::WithJSOracle( 22 const std::function<void(JSOracleParent* aParent)>& aCallback) { 23 GetSingleton()->StartJSOracle()->Then( 24 GetMainThreadSerialEventTarget(), __func__, 25 [aCallback](const JSOraclePromise::ResolveOrRejectValue& aResult) { 26 aCallback(aResult.IsReject() || !aResult.ResolveValue() 27 ? nullptr 28 : GetSingleton()); 29 }); 30 } 31 32 void JSOracleParent::ActorDestroy(ActorDestroyReason aReason) { 33 // Given an actor can only be bound to one process, 34 // if the utility process crashes and we create a new one, 35 // we can't reuse the same JSOracleParent instance for it, 36 // so we always create a new JSOracleParent to replace 37 // the existing one. 38 if (aReason == ActorDestroyReason::AbnormalShutdown) { 39 sOracleSingleton = new JSOracleParent(); 40 } 41 } 42 43 /* static */ 44 JSOracleParent* JSOracleParent::GetSingleton() { 45 if (!sOracleSingleton) { 46 sOracleSingleton = new JSOracleParent(); 47 ClearOnShutdown(&sOracleSingleton); 48 } 49 50 return sOracleSingleton; 51 } 52 53 RefPtr<JSOracleParent::JSOraclePromise> JSOracleParent::StartJSOracle() { 54 using namespace mozilla::ipc; 55 RefPtr<JSOracleParent> parent = JSOracleParent::GetSingleton(); 56 return UtilityProcessManager::GetSingleton()->StartJSOracle(parent); 57 } 58 59 nsresult JSOracleParent::BindToUtilityProcess( 60 const RefPtr<mozilla::ipc::UtilityProcessParent>& aUtilityParent) { 61 Endpoint<PJSOracleParent> parentEnd; 62 Endpoint<PJSOracleChild> childEnd; 63 MOZ_ASSERT(aUtilityParent); 64 if (NS_FAILED(PJSOracle::CreateEndpoints( 65 mozilla::ipc::EndpointProcInfo::Current(), 66 aUtilityParent->OtherEndpointProcInfo(), &parentEnd, &childEnd))) { 67 return NS_ERROR_FAILURE; 68 } 69 70 if (!aUtilityParent->SendStartJSOracleService(std::move(childEnd))) { 71 return NS_ERROR_FAILURE; 72 } 73 74 Bind(std::move(parentEnd)); 75 76 return NS_OK; 77 } 78 79 void JSOracleParent::Bind(Endpoint<PJSOracleParent>&& aEndpoint) { 80 DebugOnly<bool> ok = aEndpoint.Bind(this); 81 MOZ_ASSERT(ok); 82 }