Bug 1382910 - Update the profiler state in the child process once PProfiler is connected. r?njn
This handles the case where the profiler state changes in the parent process
between the initial launch of the child process and the time at which the
PProfiler connection is established.
MozReview-Commit-ID: 5SQme5M7P30
--- a/tools/profiler/gecko/PProfiler.ipdl
+++ b/tools/profiler/gecko/PProfiler.ipdl
@@ -13,16 +13,17 @@ namespace mozilla {
// those processes.
// It is a top-level protocol so that its child endpoint can be on a
// background thread, so that profiles can be gathered even if the main thread
// is unresponsive.
async protocol PProfiler
{
child:
async Start(ProfilerInitParams params);
+ async EnsureStarted(ProfilerInitParams params);
async Stop();
async Pause();
async Resume();
async GatherProfile() returns (nsCString profile);
};
} // namespace mozilla
--- a/tools/profiler/gecko/ProfilerChild.cpp
+++ b/tools/profiler/gecko/ProfilerChild.cpp
@@ -34,16 +34,31 @@ ProfilerChild::RecvStart(const ProfilerI
params.features(),
filterArray.Elements(),
filterArray.Length());
return IPC_OK();
}
mozilla::ipc::IPCResult
+ProfilerChild::RecvEnsureStarted(const ProfilerInitParams& params)
+{
+ nsTArray<const char*> filterArray;
+ for (size_t i = 0; i < params.filters().Length(); ++i) {
+ filterArray.AppendElement(params.filters()[i].get());
+ }
+
+ profiler_ensure_started(params.entries(), params.interval(),
+ params.features(),
+ filterArray.Elements(), filterArray.Length());
+
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
ProfilerChild::RecvStop()
{
profiler_stop();
return IPC_OK();
}
mozilla::ipc::IPCResult
ProfilerChild::RecvPause()
--- a/tools/profiler/gecko/ProfilerParent.cpp
+++ b/tools/profiler/gecko/ProfilerParent.cpp
@@ -124,16 +124,44 @@ ProfilerParent::ProfilerParent()
}
void
ProfilerParent::Init()
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
ProfilerParentTracker::StartTracking(this);
+
+ // We propagated the profiler state from the parent process to the child
+ // process through MOZ_PROFILER_STARTUP* environment variables.
+ // However, the profiler state might have changed in this process since then,
+ // and now that an active communication channel has been established with the
+ // child process, it's a good time to sync up the two profilers again.
+
+ int entries = 0;
+ double interval = 0;
+ mozilla::Vector<const char*> filters;
+ uint32_t features;
+ profiler_get_start_params(&entries, &interval, &features, &filters);
+
+ if (entries != 0) {
+ ProfilerInitParams ipcParams;
+ ipcParams.enabled() = true;
+ ipcParams.entries() = entries;
+ ipcParams.interval() = interval;
+ ipcParams.features() = features;
+
+ for (uint32_t i = 0; i < filters.length(); ++i) {
+ ipcParams.filters().AppendElement(filters[i]);
+ }
+
+ Unused << SendEnsureStarted(ipcParams);
+ } else {
+ Unused << SendStop();
+ }
}
ProfilerParent::~ProfilerParent()
{
MOZ_COUNT_DTOR(ProfilerParent);
MOZ_RELEASE_ASSERT(NS_IsMainThread());
ProfilerParentTracker::StopTracking(this);
--- a/tools/profiler/public/ProfilerChild.h
+++ b/tools/profiler/public/ProfilerChild.h
@@ -31,16 +31,17 @@ class ProfilerChild final : public PProf
nsCString GrabShutdownProfile();
void Destroy();
private:
virtual ~ProfilerChild();
mozilla::ipc::IPCResult RecvStart(const ProfilerInitParams& params) override;
+ mozilla::ipc::IPCResult RecvEnsureStarted(const ProfilerInitParams& params) override;
mozilla::ipc::IPCResult RecvStop() override;
mozilla::ipc::IPCResult RecvPause() override;
mozilla::ipc::IPCResult RecvResume() override;
mozilla::ipc::IPCResult RecvGatherProfile(GatherProfileResolver&& aResolve) override;
void ActorDestroy(ActorDestroyReason aActorDestroyReason) override;
nsCOMPtr<nsIThread> mThread;