Bug 1672072 - P10. Promisify launch of RDD process and remove sync dispatch. r=mattwoodrow,bryce,mjf,padenot

Differential Revision: https://phabricator.services.mozilla.com/D96366
This commit is contained in:
Jean-Yves Avenard 2020-11-13 04:21:16 +00:00
Родитель 44ad5e249a
Коммит 96a9f35dcd
3 изменённых файлов: 90 добавлений и 80 удалений

Просмотреть файл

@ -99,44 +99,49 @@ void RDDProcessManager::OnPreferenceChange(const char16_t* aData) {
}
}
bool RDDProcessManager::EnsureRDDProcessAndCreateBridge(
base::ProcessId aOtherProcess,
mozilla::ipc::Endpoint<PRemoteDecoderManagerChild>*
aOutRemoteDecoderManager) {
bool success = false;
auto RDDProcessManager::EnsureRDDProcessAndCreateBridge(
base::ProcessId aOtherProcess) -> RefPtr<EnsureRDDPromise> {
return InvokeAsync(GetMainThreadSerialEventTarget(), __func__,
[aOtherProcess, this]() -> RefPtr<EnsureRDDPromise> {
if (!Get()) {
// Shutdown?
return EnsureRDDPromise::CreateAndReject(
NS_ERROR_NOT_AVAILABLE, __func__);
}
if (mProcess) {
ipc::Endpoint<PRemoteDecoderManagerChild> endpoint;
if (!CreateContentBridge(aOtherProcess, &endpoint)) {
return EnsureRDDPromise::CreateAndReject(
NS_ERROR_NOT_AVAILABLE, __func__);
}
return EnsureRDDPromise::CreateAndResolve(
std::move(endpoint), __func__);
}
RefPtr<Runnable> task =
NS_NewRunnableFunction("RDDProcessManager::RDDProcessManager", [&]() {
if (mProcess) {
success =
CreateContentBridge(aOtherProcess, aOutRemoteDecoderManager);
return;
}
mNumProcessAttempts++;
mNumProcessAttempts++;
std::vector<std::string> extraArgs;
nsCString parentBuildID(mozilla::PlatformBuildID());
extraArgs.push_back("-parentBuildID");
extraArgs.push_back(parentBuildID.get());
std::vector<std::string> extraArgs;
nsCString parentBuildID(mozilla::PlatformBuildID());
extraArgs.push_back("-parentBuildID");
extraArgs.push_back(parentBuildID.get());
// The subprocess is launched asynchronously, so we wait for a callback
// to acquire the IPDL actor.
mProcess = new RDDProcessHost(this);
if (!mProcess->Launch(extraArgs)) {
DestroyProcess();
return;
}
if (!EnsureRDDReady()) {
return;
}
success = CreateVideoBridge() &&
CreateContentBridge(aOtherProcess, aOutRemoteDecoderManager);
});
SyncRunnable::DispatchToThread(GetMainThreadSerialEventTarget(), task);
return success;
// The subprocess is launched asynchronously, so we wait
// for a callback to acquire the IPDL actor.
mProcess = new RDDProcessHost(this);
if (!mProcess->Launch(extraArgs)) {
DestroyProcess();
return EnsureRDDPromise::CreateAndReject(
NS_ERROR_NOT_AVAILABLE, __func__);
}
ipc::Endpoint<PRemoteDecoderManagerChild> endpoint;
if (!EnsureRDDReady() || !CreateVideoBridge() ||
!CreateContentBridge(aOtherProcess, &endpoint)) {
return EnsureRDDPromise::CreateAndReject(
NS_ERROR_NOT_AVAILABLE, __func__);
}
return EnsureRDDPromise::CreateAndResolve(
std::move(endpoint), __func__);
});
}
bool RDDProcessManager::IsRDDProcessLaunching() {
@ -237,27 +242,23 @@ void RDDProcessManager::DestroyProcess() {
bool RDDProcessManager::CreateContentBridge(
base::ProcessId aOtherProcess,
ipc::Endpoint<PRemoteDecoderManagerChild>* aOutRemoteDecoderManager) {
bool success = false;
RefPtr<Runnable> task =
NS_NewRunnableFunction("RDDProcessManager::RDDProcessManager", [&]() {
ipc::Endpoint<PRemoteDecoderManagerParent> parentPipe;
ipc::Endpoint<PRemoteDecoderManagerChild> childPipe;
MOZ_ASSERT(NS_IsMainThread());
nsresult rv = PRemoteDecoderManager::CreateEndpoints(
mRDDChild->OtherPid(), aOtherProcess, &parentPipe, &childPipe);
if (NS_FAILED(rv)) {
MOZ_LOG(sPDMLog, LogLevel::Debug,
("Could not create content remote decoder: %d", int(rv)));
return;
}
ipc::Endpoint<PRemoteDecoderManagerParent> parentPipe;
ipc::Endpoint<PRemoteDecoderManagerChild> childPipe;
mRDDChild->SendNewContentRemoteDecoderManager(std::move(parentPipe));
nsresult rv = PRemoteDecoderManager::CreateEndpoints(
mRDDChild->OtherPid(), aOtherProcess, &parentPipe, &childPipe);
if (NS_FAILED(rv)) {
MOZ_LOG(sPDMLog, LogLevel::Debug,
("Could not create content remote decoder: %d", int(rv)));
return false;
}
*aOutRemoteDecoderManager = std::move(childPipe);
success = true;
});
SyncRunnable::DispatchToThread(GetMainThreadSerialEventTarget(), task);
return success;
mRDDChild->SendNewContentRemoteDecoderManager(std::move(parentPipe));
*aOutRemoteDecoderManager = std::move(childPipe);
return true;
}
bool RDDProcessManager::CreateVideoBridge() {

Просмотреть файл

@ -5,13 +5,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef _include_dom_media_ipc_RDDProcessManager_h_
#define _include_dom_media_ipc_RDDProcessManager_h_
#include "mozilla/MozPromise.h"
#include "mozilla/PRemoteDecoderManagerChild.h"
#include "mozilla/RDDProcessHost.h"
#include "mozilla/ipc/TaskFactory.h"
namespace mozilla {
class MemoryReportingProcess;
class PRemoteDecoderManagerChild;
class RDDChild;
// The RDDProcessManager is a singleton responsible for creating RDD-bound
@ -27,18 +28,12 @@ class RDDProcessManager final : public RDDProcessHost::Listener {
~RDDProcessManager();
using EnsureRDDPromise =
MozPromise<ipc::Endpoint<PRemoteDecoderManagerChild>, nsresult, true>;
// If not using a RDD process, launch a new RDD process asynchronously and
// create a RemoteDecoderManager bridge
bool EnsureRDDProcessAndCreateBridge(
base::ProcessId aOtherProcess,
mozilla::ipc::Endpoint<PRemoteDecoderManagerChild>*
aOutRemoteDecoderManager);
bool IsRDDProcessLaunching();
// Ensure that RDD-bound methods can be used. If no RDD process is being
// used, or one is launched and ready, this function returns immediately.
// Otherwise it blocks until the RDD process has finished launching.
bool EnsureRDDReady();
RefPtr<EnsureRDDPromise> EnsureRDDProcessAndCreateBridge(
base::ProcessId aOtherProcess);
void OnProcessLaunchComplete(RDDProcessHost* aHost) override;
void OnProcessUnexpectedShutdown(RDDProcessHost* aHost) override;
@ -67,6 +62,11 @@ class RDDProcessManager final : public RDDProcessHost::Listener {
RDDProcessHost* Process() { return mProcess; }
private:
bool IsRDDProcessLaunching();
// Ensure that RDD-bound methods can be used. If no RDD process is being
// used, or one is launched and ready, this function returns immediately.
// Otherwise it blocks until the RDD process has finished launching.
bool EnsureRDDReady();
bool CreateVideoBridge();
// Called from our xpcom-shutdown observer.
@ -94,13 +94,12 @@ class RDDProcessManager final : public RDDProcessHost::Listener {
};
friend class Observer;
private:
bool CreateContentBridge(base::ProcessId aOtherProcess,
mozilla::ipc::Endpoint<PRemoteDecoderManagerChild>*
aOutRemoteDecoderManager);
bool CreateContentBridge(
base::ProcessId aOtherProcess,
ipc::Endpoint<PRemoteDecoderManagerChild>* aOutRemoteDecoderManager);
const RefPtr<Observer> mObserver;
mozilla::ipc::TaskFactory<RDDProcessManager> mTaskFactory;
ipc::TaskFactory<RDDProcessManager> mTaskFactory;
uint32_t mNumProcessAttempts = 0;
// Fields that are associated with the current RDD process.
@ -110,7 +109,7 @@ class RDDProcessManager final : public RDDProcessHost::Listener {
// Collects any pref changes that occur during process launch (after
// the initial map is passed in command-line arguments) to be sent
// when the process can receive IPC messages.
nsTArray<mozilla::dom::Pref> mQueuedPrefs;
nsTArray<dom::Pref> mQueuedPrefs;
};
} // namespace mozilla

Просмотреть файл

@ -761,7 +761,7 @@ bool BackgroundParentImpl::DeallocPCamerasParent(
}
auto BackgroundParentImpl::AllocPUDPSocketParent(
const Maybe<PrincipalInfo>& /* unused */, const nsCString & /* unused */)
const Maybe<PrincipalInfo>& /* unused */, const nsCString& /* unused */)
-> PUDPSocketParent* {
RefPtr<UDPSocketParent> p = new UDPSocketParent(this);
@ -1316,15 +1316,25 @@ mozilla::ipc::IPCResult
BackgroundParentImpl::RecvEnsureRDDProcessAndCreateBridge(
EnsureRDDProcessAndCreateBridgeResolver&& aResolver) {
RDDProcessManager* rdd = RDDProcessManager::Get();
Endpoint<PRemoteDecoderManagerChild> endpoint;
nsresult rv =
rdd && rdd->EnsureRDDProcessAndCreateBridge(OtherPid(), &endpoint)
? NS_OK
: NS_ERROR_NOT_AVAILABLE;
aResolver(
Tuple<const nsresult&, Endpoint<mozilla::PRemoteDecoderManagerChild>&&>(
rv, std::move(endpoint)));
using Type =
Tuple<const nsresult&, Endpoint<mozilla::PRemoteDecoderManagerChild>&&>;
if (!rdd) {
aResolver(
Type(NS_ERROR_NOT_AVAILABLE, Endpoint<PRemoteDecoderManagerChild>()));
} else {
rdd->EnsureRDDProcessAndCreateBridge(OtherPid())
->Then(GetCurrentSerialEventTarget(), __func__,
[resolver = std::move(aResolver)](
mozilla::RDDProcessManager::EnsureRDDPromise::
ResolveOrRejectValue&& aValue) mutable {
if (aValue.IsReject()) {
resolver(Type(aValue.RejectValue(),
Endpoint<PRemoteDecoderManagerChild>()));
return;
}
resolver(Type(NS_OK, std::move(aValue.ResolveValue())));
});
}
return IPC_OK();
}