Bug 1382910 - Update the profiler state in the child process once PProfiler is connected. r?njn draft
authorMarkus Stange <mstange@themasta.com>
Mon, 24 Jul 2017 16:33:50 -0400
changeset 614736 55808cc575ee9376a7e59ed60ee3585685e5cbe5
parent 614735 bfb28d33e32b5690dc7012203248c57f9a1c54bd
child 638939 40668197c2feb5e7b9d8d5acbe4e7cb6435b8774
push id70096
push userbmo:mstange@themasta.com
push dateMon, 24 Jul 2017 22:17:43 +0000
reviewersnjn
bugs1382910
milestone56.0a1
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
tools/profiler/gecko/PProfiler.ipdl
tools/profiler/gecko/ProfilerChild.cpp
tools/profiler/gecko/ProfilerParent.cpp
tools/profiler/public/ProfilerChild.h
--- 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;