LCOV - code coverage report
Current view: top level - tools/profiler/gecko - ProfilerParent.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 32 115 27.8 %
Date: 2017-07-14 16:53:18 Functions: 5 26 19.2 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "ProfilerParent.h"
       8             : 
       9             : #include "mozilla/ClearOnShutdown.h"
      10             : #include "mozilla/RefPtr.h"
      11             : #include "mozilla/Unused.h"
      12             : 
      13             : #include "nsProfiler.h"
      14             : #include "nsTArray.h"
      15             : #include "nsThreadUtils.h"
      16             : 
      17             : namespace mozilla {
      18             : 
      19             : using namespace ipc;
      20             : 
      21             : class ProfilerParentTracker final {
      22             : public:
      23             :   static void StartTracking(ProfilerParent* aParent);
      24             :   static void StopTracking(ProfilerParent* aParent);
      25             : 
      26             :   template<typename FuncType>
      27             :   static void Enumerate(FuncType aIterFunc);
      28             : 
      29             :   ProfilerParentTracker();
      30             :   ~ProfilerParentTracker();
      31             : 
      32             : private:
      33             :   nsTArray<ProfilerParent*> mProfilerParents;
      34             :   static UniquePtr<ProfilerParentTracker> sInstance;
      35             : };
      36             : 
      37           3 : UniquePtr<ProfilerParentTracker> ProfilerParentTracker::sInstance;
      38             : 
      39             : /* static */ void
      40           2 : ProfilerParentTracker::StartTracking(ProfilerParent* aProfilerParent)
      41             : {
      42           2 :   if (!sInstance) {
      43           1 :     sInstance = MakeUnique<ProfilerParentTracker>();
      44           1 :     ClearOnShutdown(&sInstance);
      45             :   }
      46           2 :   sInstance->mProfilerParents.AppendElement(aProfilerParent);
      47           2 : }
      48             : 
      49             : /* static */ void
      50           0 : ProfilerParentTracker::StopTracking(ProfilerParent* aParent)
      51             : {
      52           0 :   if (sInstance) {
      53           0 :     sInstance->mProfilerParents.RemoveElement(aParent);
      54             :   }
      55           0 : }
      56             : 
      57             : template<typename FuncType>
      58             : /* static */ void
      59           0 : ProfilerParentTracker::Enumerate(FuncType aIterFunc)
      60             : {
      61           0 :   if (sInstance) {
      62           0 :     for (ProfilerParent* profilerParent : sInstance->mProfilerParents) {
      63           0 :       if (!profilerParent->mDestroyed) {
      64           0 :         aIterFunc(profilerParent);
      65             :       }
      66             :     }
      67             :   }
      68           0 : }
      69             : 
      70           1 : ProfilerParentTracker::ProfilerParentTracker()
      71             : {
      72           1 :   MOZ_COUNT_CTOR(ProfilerParentTracker);
      73           1 : }
      74             : 
      75           0 : ProfilerParentTracker::~ProfilerParentTracker()
      76             : {
      77           0 :   MOZ_COUNT_DTOR(ProfilerParentTracker);
      78             : 
      79           0 :   nsTArray<ProfilerParent*> parents;
      80           0 :   parents = mProfilerParents;
      81             :   // Close the channels of any profiler parents that haven't been destroyed.
      82           0 :   for (ProfilerParent* profilerParent : parents) {
      83           0 :     if (!profilerParent->mDestroyed) {
      84             :       // Keep the object alive until the call to Close() has completed.
      85             :       // Close() will trigger a call to DeallocPProfilerParent.
      86           0 :       RefPtr<ProfilerParent> actor = profilerParent;
      87           0 :       actor->Close();
      88             :     }
      89             :   }
      90           0 : }
      91             : 
      92             : /* static */ Endpoint<PProfilerChild>
      93           2 : ProfilerParent::CreateForProcess(base::ProcessId aOtherPid)
      94             : {
      95           2 :   MOZ_RELEASE_ASSERT(NS_IsMainThread());
      96           4 :   Endpoint<PProfilerParent> parent;
      97           2 :   Endpoint<PProfilerChild> child;
      98           2 :   nsresult rv = PProfiler::CreateEndpoints(base::GetCurrentProcId(),
      99             :                                            aOtherPid,
     100           2 :                                            &parent, &child);
     101             : 
     102           2 :   if (NS_FAILED(rv)) {
     103           0 :     MOZ_CRASH("Failed to create top level actor for PProfiler!");
     104             :   }
     105             : 
     106           4 :   RefPtr<ProfilerParent> actor = new ProfilerParent();
     107           2 :   if (!parent.Bind(actor)) {
     108           0 :     MOZ_CRASH("Failed to bind parent actor for PProfiler!");
     109             :   }
     110             : 
     111             :   // mSelfRef will be cleared in DeallocPProfilerParent.
     112           2 :   actor->mSelfRef = actor;
     113           2 :   actor->Init();
     114             : 
     115           4 :   return child;
     116             : }
     117             : 
     118           2 : ProfilerParent::ProfilerParent()
     119           2 :   : mDestroyed(false)
     120             : {
     121           2 :   MOZ_COUNT_CTOR(ProfilerParent);
     122             : 
     123           2 :   MOZ_RELEASE_ASSERT(NS_IsMainThread());
     124           2 : }
     125             : 
     126             : void
     127           2 : ProfilerParent::Init()
     128             : {
     129           2 :   MOZ_RELEASE_ASSERT(NS_IsMainThread());
     130             : 
     131           2 :   ProfilerParentTracker::StartTracking(this);
     132             : 
     133           2 :   if (profiler_is_active()) {
     134             :     // If the profiler is already running in this process, start it in the
     135             :     // child process immediately.
     136           0 :     int entries = 0;
     137           0 :     double interval = 0;
     138           0 :     mozilla::Vector<const char*> filters;
     139             :     uint32_t features;
     140           0 :     profiler_get_start_params(&entries, &interval, &features, &filters);
     141             : 
     142           0 :     ProfilerInitParams ipcParams;
     143           0 :     ipcParams.enabled() = true;
     144           0 :     ipcParams.entries() = entries;
     145           0 :     ipcParams.interval() = interval;
     146           0 :     ipcParams.features() = features;
     147             : 
     148           0 :     for (uint32_t i = 0; i < filters.length(); ++i) {
     149           0 :       ipcParams.filters().AppendElement(filters[i]);
     150             :     }
     151             : 
     152           0 :     Unused << SendStart(ipcParams);
     153             :   }
     154           2 : }
     155             : 
     156           0 : ProfilerParent::~ProfilerParent()
     157             : {
     158           0 :   MOZ_COUNT_DTOR(ProfilerParent);
     159             : 
     160           0 :   MOZ_RELEASE_ASSERT(NS_IsMainThread());
     161           0 :   ProfilerParentTracker::StopTracking(this);
     162           0 : }
     163             : 
     164             : /* static */ nsTArray<RefPtr<ProfilerParent::SingleProcessProfilePromise>>
     165           0 : ProfilerParent::GatherProfiles()
     166             : {
     167           0 :   if (!NS_IsMainThread()) {
     168           0 :     return nsTArray<RefPtr<ProfilerParent::SingleProcessProfilePromise>>();
     169             :   }
     170             : 
     171           0 :   nsTArray<RefPtr<SingleProcessProfilePromise>> results;
     172           0 :   ProfilerParentTracker::Enumerate([&](ProfilerParent* profilerParent) {
     173           0 :     results.AppendElement(profilerParent->SendGatherProfile());
     174           0 :   });
     175           0 :   return results;
     176             : }
     177             : 
     178             : /* static */ void
     179           0 : ProfilerParent::ProfilerStarted(nsIProfilerStartParams* aParams)
     180             : {
     181           0 :   if (!NS_IsMainThread()) {
     182           0 :     return;
     183             :   }
     184             : 
     185           0 :   ProfilerInitParams ipcParams;
     186           0 :   ipcParams.enabled() = true;
     187           0 :   aParams->GetEntries(&ipcParams.entries());
     188           0 :   aParams->GetInterval(&ipcParams.interval());
     189           0 :   aParams->GetFeatures(&ipcParams.features());
     190           0 :   ipcParams.filters() = aParams->GetFilters();
     191             : 
     192           0 :   ProfilerParentTracker::Enumerate([&](ProfilerParent* profilerParent) {
     193           0 :     Unused << profilerParent->SendStart(ipcParams);
     194           0 :   });
     195             : }
     196             : 
     197             : /* static */ void
     198           0 : ProfilerParent::ProfilerStopped()
     199             : {
     200           0 :   if (!NS_IsMainThread()) {
     201           0 :     return;
     202             :   }
     203             : 
     204           0 :   ProfilerParentTracker::Enumerate([](ProfilerParent* profilerParent) {
     205           0 :     Unused << profilerParent->SendStop();
     206           0 :   });
     207             : }
     208             : 
     209             : /* static */ void
     210           0 : ProfilerParent::ProfilerPaused()
     211             : {
     212           0 :   if (!NS_IsMainThread()) {
     213           0 :     return;
     214             :   }
     215             : 
     216           0 :   ProfilerParentTracker::Enumerate([](ProfilerParent* profilerParent) {
     217           0 :     Unused << profilerParent->SendPause();
     218           0 :   });
     219             : }
     220             : 
     221             : /* static */ void
     222           0 : ProfilerParent::ProfilerResumed()
     223             : {
     224           0 :   if (!NS_IsMainThread()) {
     225           0 :     return;
     226             :   }
     227             : 
     228           0 :   ProfilerParentTracker::Enumerate([](ProfilerParent* profilerParent) {
     229           0 :     Unused << profilerParent->SendResume();
     230           0 :   });
     231             : }
     232             : 
     233             : void
     234           0 : ProfilerParent::ActorDestroy(ActorDestroyReason aActorDestroyReason)
     235             : {
     236           0 :   MOZ_RELEASE_ASSERT(NS_IsMainThread());
     237           0 :   mDestroyed = true;
     238           0 : }
     239             : 
     240             : void
     241           0 : ProfilerParent::DeallocPProfilerParent()
     242             : {
     243           0 :   mSelfRef = nullptr;
     244           0 : }
     245             : 
     246             : } // namespace mozilla

Generated by: LCOV version 1.13