OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef CHROME_BROWSER_METRICS_TRACKING_SYNCHRONIZER_H_ | |
6 #define CHROME_BROWSER_METRICS_TRACKING_SYNCHRONIZER_H_ | |
7 | |
8 #include <map> | |
9 #include <string> | |
10 #include <vector> | |
11 | |
12 #include "base/basictypes.h" | |
13 #include "base/lazy_instance.h" | |
14 #include "base/memory/ref_counted.h" | |
15 #include "base/memory/weak_ptr.h" | |
16 #include "content/public/browser/profiler_subscriber.h" | |
17 | |
18 // This class maintains state that is used to upload profiler data from the | |
19 // various processes, into the browser process. Such transactions are usually | |
20 // instigated by the browser. In general, a process will respond by gathering | |
21 // profiler data, and transmitting the pickled profiler data. We collect the | |
22 // data in asynchronous mode that doesn't block the UI thread. | |
23 // | |
24 // To assure that all the processes have responded, a counter is maintained | |
25 // to indicate the number of pending (not yet responsive) processes. We tag | |
26 // each group of requests with a sequence number. For each group of requests, we | |
27 // create RequestContext object which stores the sequence number, pending | |
28 // processes and the callback_object that needs to be notified when we receive | |
29 // an update from processes. When an update arrives we find the RequestContext | |
30 // associated with sequence number and send the unpickled profiler data to the | |
31 // |callback_object_|. | |
32 | |
33 namespace chrome_browser_metrics { | |
34 | |
35 class TrackingSynchronizerObserver; | |
36 | |
37 class TrackingSynchronizer | |
38 : public content::ProfilerSubscriber, | |
39 public base::RefCountedThreadSafe<TrackingSynchronizer> { | |
40 public: | |
41 // Construction also sets up the global singleton instance. This instance is | |
42 // used to communicate between the IO and UI thread, and is destroyed only as | |
43 // the main thread (browser_main) terminates, which means the IO thread has | |
44 // already completed, and will not need this instance any further. | |
45 TrackingSynchronizer(); | |
46 | |
47 // Contact all processes, and get them to upload to the browser any/all | |
48 // changes to profiler data. It calls |callback_object|'s SetData method with | |
49 // the data received from each sub-process. | |
50 // This method is accessible on UI thread. | |
51 static void FetchProfilerDataAsynchronously( | |
52 const base::WeakPtr<TrackingSynchronizerObserver>& callback_object); | |
53 | |
54 // ------------------------------------------------------ | |
55 // ProfilerSubscriber methods for browser child processes | |
56 // ------------------------------------------------------ | |
57 | |
58 // Update the number of pending processes for the given |sequence_number|. | |
59 // This is called on UI thread. | |
60 virtual void OnPendingProcesses(int sequence_number, | |
61 int pending_processes, | |
62 bool end) OVERRIDE; | |
63 | |
64 private: | |
65 friend class base::RefCountedThreadSafe<TrackingSynchronizer>; | |
66 | |
67 class RequestContext; | |
68 | |
69 virtual ~TrackingSynchronizer(); | |
70 | |
71 // Send profiler_data back to callback_object_ by calling | |
72 // DecrementPendingProcessesAndSendData which records that we are waiting | |
73 // for one less profiler data from renderer or browser child process for the | |
74 // given sequence number. This method is accessible on UI thread. | |
75 virtual void OnProfilerDataCollected( | |
76 int sequence_number, | |
77 const tracked_objects::ProcessDataSnapshot& profiler_data, | |
78 int process_type) OVERRIDE; | |
79 | |
80 // Establish a new sequence_number_, and use it to notify all the processes of | |
81 // the need to supply, to the browser, their tracking data. It also registers | |
82 // |callback_object| in |outstanding_requests_| map. Return the | |
83 // sequence_number_ that was used. This method is accessible on UI thread. | |
84 int RegisterAndNotifyAllProcesses( | |
85 const base::WeakPtr<TrackingSynchronizerObserver>& callback_object); | |
86 | |
87 // It finds the RequestContext for the given |sequence_number| and notifies | |
88 // the RequestContext's |callback_object_| about the |value|. This is called | |
89 // whenever we receive profiler data from processes. It also records that we | |
90 // are waiting for one less profiler data from a process for the given | |
91 // sequence number. If we have received a response from all renderers and | |
92 // browser processes, then it calls RequestContext's DeleteIfAllDone to delete | |
93 // the entry for sequence_number. This method is accessible on UI thread. | |
94 void DecrementPendingProcessesAndSendData( | |
95 int sequence_number, | |
96 const tracked_objects::ProcessDataSnapshot& profiler_data, | |
97 int process_type); | |
98 | |
99 // Get a new sequence number to be sent to processes from browser process. | |
100 // This method is accessible on UI thread. | |
101 int GetNextAvailableSequenceNumber(); | |
102 | |
103 // We don't track the actual processes that are contacted for an update, only | |
104 // the count of the number of processes, and we can sometimes time-out and | |
105 // give up on a "slow to respond" process. We use a sequence_number to be | |
106 // sure a response from a process is associated with the current round of | |
107 // requests. All sequence numbers used are non-negative. | |
108 // last_used_sequence_number_ is the most recently used number (used to avoid | |
109 // reuse for a long time). | |
110 int last_used_sequence_number_; | |
111 | |
112 DISALLOW_COPY_AND_ASSIGN(TrackingSynchronizer); | |
113 }; | |
114 | |
115 } // namespace chrome_browser_metrics | |
116 | |
117 #endif // CHROME_BROWSER_METRICS_TRACKING_SYNCHRONIZER_H_ | |
OLD | NEW |