Bug 1668867 - ProfilerParent::Profiler{Start,Stop,etc.}ed await the corresponding PProfiler function and then resolve their GenericPromise - r=canaltinova

Differential Revision: https://phabricator.services.mozilla.com/D139333
This commit is contained in:
Gerald Squelart 2022-03-01 06:56:01 +00:00
Родитель 4d50543faa
Коммит f2d47478d0
2 изменённых файлов: 95 добавлений и 48 удалений

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

@ -742,10 +742,72 @@ void ProfilerParent::RequestChunkManagerUpdate() {
});
}
/* static */
void ProfilerParent::ProfilerStarted(nsIProfilerStartParams* aParams) {
// Ref-counted class that resolves a promise on destruction.
// Usage:
// RefPtr<GenericPromise> f() {
// return PromiseResolverOnDestruction::RunTask(
// [](RefPtr<PromiseResolverOnDestruction> aPromiseResolver){
// // Give *copies* of aPromiseResolver to asynchronous sub-tasks, the
// // last remaining RefPtr destruction will resolve the promise.
// });
// }
class PromiseResolverOnDestruction {
public:
NS_INLINE_DECL_REFCOUNTING(PromiseResolverOnDestruction)
template <typename TaskFunction>
static RefPtr<GenericPromise> RunTask(TaskFunction&& aTaskFunction) {
RefPtr<PromiseResolverOnDestruction> promiseResolver =
new PromiseResolverOnDestruction();
RefPtr<GenericPromise> promise =
promiseResolver->mPromiseHolder.Ensure(__func__);
std::forward<TaskFunction>(aTaskFunction)(std::move(promiseResolver));
return promise;
}
private:
PromiseResolverOnDestruction() = default;
~PromiseResolverOnDestruction() {
mPromiseHolder.ResolveIfExists(/* unused */ true, __func__);
}
MozPromiseHolder<GenericPromise> mPromiseHolder;
};
// Given a ProfilerParentSendFunction: (ProfilerParent*) -> some MozPromise,
// run the function on all live ProfilerParents and return a GenericPromise, and
// when their promise gets resolve, resolve our Generic promise.
template <typename ProfilerParentSendFunction>
static RefPtr<GenericPromise> SendAndConvertPromise(
ProfilerParentSendFunction&& aProfilerParentSendFunction) {
if (!NS_IsMainThread()) {
return;
return GenericPromise::CreateAndResolve(/* unused */ true, __func__);
}
return PromiseResolverOnDestruction::RunTask(
[&](RefPtr<PromiseResolverOnDestruction> aPromiseResolver) {
ProfilerParentTracker::Enumerate([&](ProfilerParent* profilerParent) {
std::forward<ProfilerParentSendFunction>(aProfilerParentSendFunction)(
profilerParent)
->Then(GetMainThreadSerialEventTarget(), __func__,
[aPromiseResolver](
typename std::remove_reference_t<
decltype(*std::forward<ProfilerParentSendFunction>(
aProfilerParentSendFunction)(
profilerParent))>::ResolveOrRejectValue&&) {
// Whatever the resolution/rejection is, do nothing.
// The lambda aPromiseResolver ref-count will decrease.
});
});
});
}
/* static */
RefPtr<GenericPromise> ProfilerParent::ProfilerStarted(
nsIProfilerStartParams* aParams) {
if (!NS_IsMainThread()) {
return GenericPromise::CreateAndResolve(/* unused */ true, __func__);
}
ProfilerInitParams ipcParams;
@ -768,16 +830,17 @@ void ProfilerParent::ProfilerStarted(nsIProfilerStartParams* aParams) {
}
aParams->GetActiveTabID(&ipcParams.activeTabID());
ProfilerParentTracker::ProfilerStarted(ipcParams.entries());
ProfilerParentTracker::Enumerate([&](ProfilerParent* profilerParent) {
return SendAndConvertPromise([&](ProfilerParent* profilerParent) {
if (profiler::detail::FiltersExcludePid(
filtersCStrings,
ProfilerProcessId::FromNumber(profilerParent->mChildPid))) {
// This pid is excluded, don't start the profiler at all.
return;
return PProfilerParent::StartPromise::CreateAndResolve(/* unused */ true,
__func__);
}
Unused << profilerParent->SendStart(ipcParams);
auto promise = profilerParent->SendStart(ipcParams);
profilerParent->RequestChunkManagerUpdate();
return promise;
});
}
@ -791,57 +854,37 @@ void ProfilerParent::ProfilerWillStopIfStarted() {
}
/* static */
void ProfilerParent::ProfilerStopped() {
if (!NS_IsMainThread()) {
return;
}
ProfilerParentTracker::Enumerate([](ProfilerParent* profilerParent) {
Unused << profilerParent->SendStop();
RefPtr<GenericPromise> ProfilerParent::ProfilerStopped() {
return SendAndConvertPromise([](ProfilerParent* profilerParent) {
return profilerParent->SendStop();
});
}
/* static */
void ProfilerParent::ProfilerPaused() {
if (!NS_IsMainThread()) {
return;
}
ProfilerParentTracker::Enumerate([](ProfilerParent* profilerParent) {
Unused << profilerParent->SendPause();
RefPtr<GenericPromise> ProfilerParent::ProfilerPaused() {
return SendAndConvertPromise([](ProfilerParent* profilerParent) {
return profilerParent->SendPause();
});
}
/* static */
void ProfilerParent::ProfilerResumed() {
if (!NS_IsMainThread()) {
return;
}
ProfilerParentTracker::Enumerate([](ProfilerParent* profilerParent) {
Unused << profilerParent->SendResume();
RefPtr<GenericPromise> ProfilerParent::ProfilerResumed() {
return SendAndConvertPromise([](ProfilerParent* profilerParent) {
return profilerParent->SendResume();
});
}
/* static */
void ProfilerParent::ProfilerPausedSampling() {
if (!NS_IsMainThread()) {
return;
}
ProfilerParentTracker::Enumerate([](ProfilerParent* profilerParent) {
Unused << profilerParent->SendPauseSampling();
RefPtr<GenericPromise> ProfilerParent::ProfilerPausedSampling() {
return SendAndConvertPromise([](ProfilerParent* profilerParent) {
return profilerParent->SendPauseSampling();
});
}
/* static */
void ProfilerParent::ProfilerResumedSampling() {
if (!NS_IsMainThread()) {
return;
}
ProfilerParentTracker::Enumerate([](ProfilerParent* profilerParent) {
Unused << profilerParent->SendResumeSampling();
RefPtr<GenericPromise> ProfilerParent::ProfilerResumedSampling() {
return SendAndConvertPromise([](ProfilerParent* profilerParent) {
return profilerParent->SendResumeSampling();
});
}

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

@ -71,13 +71,17 @@ class ProfilerParent final : public PProfilerParent {
static RefPtr<SingleProcessProgressPromise> RequestGatherProfileProgress(
base::ProcessId aChildPid);
static void ProfilerStarted(nsIProfilerStartParams* aParams);
// This will start the profiler in all child processes. The returned promise
// will be resolved when all child have completed their operation
// (successfully or not.)
static RefPtr<GenericPromise> ProfilerStarted(
nsIProfilerStartParams* aParams);
static void ProfilerWillStopIfStarted();
static void ProfilerStopped();
static void ProfilerPaused();
static void ProfilerResumed();
static void ProfilerPausedSampling();
static void ProfilerResumedSampling();
static RefPtr<GenericPromise> ProfilerStopped();
static RefPtr<GenericPromise> ProfilerPaused();
static RefPtr<GenericPromise> ProfilerResumed();
static RefPtr<GenericPromise> ProfilerPausedSampling();
static RefPtr<GenericPromise> ProfilerResumedSampling();
static void ClearAllPages();
// Create a "Final" update that the Child can return to its Parent.