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.
5 #ifndef CHROME_BROWSER_METRICS_TRACKING_SYNCHRONIZER_H_
6 #define CHROME_BROWSER_METRICS_TRACKING_SYNCHRONIZER_H_
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"
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.
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_|.
33 namespace chrome_browser_metrics
{
35 class TrackingSynchronizerObserver
;
37 class TrackingSynchronizer
38 : public content::ProfilerSubscriber
,
39 public base::RefCountedThreadSafe
<TrackingSynchronizer
> {
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();
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
);
54 // ------------------------------------------------------
55 // ProfilerSubscriber methods for browser child processes
56 // ------------------------------------------------------
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
,
65 friend class base::RefCountedThreadSafe
<TrackingSynchronizer
>;
69 virtual ~TrackingSynchronizer();
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(
77 const tracked_objects::ProcessDataSnapshot
& profiler_data
,
78 int process_type
) OVERRIDE
;
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
);
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(
96 const tracked_objects::ProcessDataSnapshot
& profiler_data
,
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();
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_
;
112 DISALLOW_COPY_AND_ASSIGN(TrackingSynchronizer
);
115 } // namespace chrome_browser_metrics
117 #endif // CHROME_BROWSER_METRICS_TRACKING_SYNCHRONIZER_H_