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 #ifndef ProfilerParent_h
8 #define ProfilerParent_h
9 
10 #include "mozilla/PProfilerParent.h"
11 #include "mozilla/RefPtr.h"
12 
13 class nsIProfilerStartParams;
14 
15 namespace mozilla {
16 
17 class ProfileBufferGlobalController;
18 class ProfilerParentTracker;
19 
20 // This is the main process side of the PProfiler protocol.
21 // ProfilerParent instances only exist on the main thread of the main process.
22 // The other side (ProfilerChild) lives on a background thread in the other
23 // process.
24 // The creation of PProfiler actors is initiated from the main process, after
25 // the other process has been launched.
26 // ProfilerParent instances are destroyed once the message channel closes,
27 // which can be triggered by either process, depending on which one shuts down
28 // first.
29 // All ProfilerParent instances are registered with a manager class called
30 // ProfilerParentTracker, which has the list of living ProfilerParent instances
31 // and handles shutdown.
32 class ProfilerParent final : public PProfilerParent {
33  public:
34   NS_INLINE_DECL_REFCOUNTING(ProfilerParent)
35 
36   static mozilla::ipc::Endpoint<PProfilerChild> CreateForProcess(
37       base::ProcessId aOtherPid);
38 
39   typedef MozPromise<Shmem, ResponseRejectReason, true>
40       SingleProcessProfilePromise;
41 
42   // The following static methods can be called on any thread, but they are
43   // no-ops on anything other than the main thread.
44   // If called on the main thread, the call will be broadcast to all
45   // registered processes (all processes for which we have a ProfilerParent
46   // object).
47   // At the moment, the main process always calls these methods on the main
48   // thread, and that's the only process in which we need to forward these
49   // calls to other processes. The other processes will call these methods on
50   // the ProfilerChild background thread, but those processes don't need to
51   // forward these calls any further.
52 
53   // Returns the number of profiles to expect. The gathered profiles will be
54   // provided asynchronously with a call to
55   // ProfileGatherer::ReceiveGatheredProfile.
56   static nsTArray<RefPtr<SingleProcessProfilePromise>> GatherProfiles();
57 
58   static void ProfilerStarted(nsIProfilerStartParams* aParams);
59   static void ProfilerWillStopIfStarted();
60   static void ProfilerStopped();
61   static void ProfilerPaused();
62   static void ProfilerResumed();
63   static void ClearAllPages();
64 
65   // Create a "Final" update that the Child can return to its Parent.
66   static ProfileBufferChunkManagerUpdate MakeFinalUpdate();
67 
68  private:
69   friend class ProfileBufferGlobalController;
70   friend class ProfilerParentTracker;
71 
72   explicit ProfilerParent(base::ProcessId aChildPid);
73   virtual ~ProfilerParent();
74 
75   void Init();
76   void ActorDestroy(ActorDestroyReason aActorDestroyReason) override;
77   void ActorDealloc() override;
78 
79   void RequestChunkManagerUpdate();
80 
81   RefPtr<ProfilerParent> mSelfRef;
82   base::ProcessId mChildPid;
83   nsTArray<MozPromiseHolder<SingleProcessProfilePromise>>
84       mPendingRequestedProfiles;
85   bool mDestroyed;
86 };
87 
88 }  // namespace mozilla
89 
90 #endif  // ProfilerParent_h
91