Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Side by Side Diff: chrome/browser/metrics/tracking_synchronizer.h

Issue 8413009: Changes to upload tracked_objects data from all renderer (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:executable
+ *
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 #pragma once
8
9 #include <string>
10 #include <vector>
11
12 #include "base/basictypes.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/synchronization/condition_variable.h"
15 #include "base/synchronization/lock.h"
16 #include "base/time.h"
17 #include "base/values.h"
18
19 // This class maintains state that is used to upload tracking data from the
20 // various processes, into the browser process. Such transactions are usually
21 // instigated by the browser. In general, a process will respond by gathering
22 // tracking data, and transmitting the pickled tracking data. We collect the
23 // data in asynchronous mode that doesn't block the UI thread.
24 //
25 // To assure that all the processes have responded, a counter is maintained
26 // to indicate the number of pending (not yet responsive) processes. We tag
27 // each group of requests with a sequence number. For each group of requests, we
28 // create RequestContext object which stores the sequence number, pending
29 // processes and the CallbackObject that needs to be notified when we receive an
30 // update from processes. When an update arrives we find the RequestContext
31 // associated with sequence number and send the unpicked tracking data to the
jar (doing other things) 2011/10/30 08:04:19 nit: unpicked --> unpickled
ramant (doing other things) 2011/11/01 00:52:15 Done.
32 // |callback_object|.
33
34 namespace chrome_browser_metrics {
35
36 // TODO(rtenneti): Need to flush out exact interface/integration with the UI
37 // (about CallbackObject).
38 class CallbackObject {
39 public:
40 CallbackObject() {}
41 virtual ~CallbackObject() {}
42
43 // Returns the data from renderer process in |value|. The ownership of
44 // |value| is transferred to the caller who is trying to collect data.
jar (doing other things) 2011/10/30 08:04:19 *if* you think this code will continue to exist in
ramant (doing other things) 2011/11/01 00:52:15 Done.
45 void SendData(base::Value* value) {value_ = value; }
46
47 base::Value* value_;
48
49 private:
50 DISALLOW_COPY_AND_ASSIGN(CallbackObject);
51 };
52
53 class TrackingSynchronizer : public
54 base::RefCountedThreadSafe<TrackingSynchronizer> {
55 public:
56 // The "RequestContext" structure describes an individual request received
57 // from the UI.
58 struct RequestContext {
59 RequestContext(CallbackObject* callback_object,
60 int sequence_number,
61 int processes_pending,
62 base::TimeTicks callback_start_time)
63 : callback_object_(callback_object),
64 sequence_number_(sequence_number),
65 processes_pending_(processes_pending),
66 request_start_time_(callback_start_time) {
67 }
68
69 // Requests are made to asynchronously send data to the |callback_object_|.
70 CallbackObject* callback_object_;
71
72 // The sequence number used by the most recent update request to contact all
73 // processes.
74 int sequence_number_;
75
76 // The number of processes that have not yet responded to requests.
77 int processes_pending_;
78
79 // The time when we were told to start the fetching of data from processes.
80 base::TimeTicks request_start_time_;
81 };
82
83 // A map from sequence_number_ to the actual RequestContexts.
84 typedef std::map<int, RequestContext*> RequestContextMap;
85
86 // Construction also sets up the global singleton instance. This instance is
87 // used to communicate between the IO and UI thread, and is destroyed only as
88 // the main thread (browser_main) terminates, which means the IO thread has
89 // already completed, and will not need this instance any further.
90 TrackingSynchronizer();
91
92 ~TrackingSynchronizer();
jar (doing other things) 2011/10/30 08:04:19 make destructor private, so that only reference co
ramant (doing other things) 2011/11/01 00:52:15 Done.
93
94 // Return pointer to the singleton instance, which is allocated and
95 // deallocated on the main UI thread (during system startup and teardown).
96 static TrackingSynchronizer* CurrentSynchronizer();
97
98 // TODO(rtenneti): delete this after testing is complete.
99 static void FetchTrackingDataSynchronously(std::string* output);
100
101 // Contact all processes, and get them to upload to the browser any/all
102 // changes to tracking data. It calls |callback_object|'s SetData method with
103 // the data received from each sub-process.
104 static void FetchTrackingDataAsynchronously(CallbackObject* callback_object);
105
106 // This method is called on the IO thread. Deserializes the tracking data and
107 // records that we have received tracking data from a process.
108 static void DeserializeTrackingList(int sequence_number,
109 const std::string& tracking_data);
110
111 private:
112 // Establish a new sequence_number_, and use it to notify all the processes of
113 // the need to supply, to the browser, their tracking data. It also registers
114 // |callback_object| in |outstanding_requests_| map.
115 // Return the sequence_number_ that was used.
116 int RegisterAndNotifyAllProcesses(CallbackObject* callback_object);
jar (doing other things) 2011/10/30 08:04:19 I'm going to guess that these callback objects are
ramant (doing other things) 2011/11/01 00:52:15 I am hoping the Callback that is defined in this f
117
118 // Register() stores the |callback_object| in |outstanding_requests_| map.
119 void Register(int sequence_number,
120 CallbackObject* callback_object,
121 int processes_pending);
122
123 // It finds the CallbackObject in |outstanding_requests_| map for the given
124 // |sequence_number| and notifies the CallbackObject about the |value|. This
125 // is called whenever we receive tracked data from processes. It also records
126 // that we are waiting for one less tracking data from a process for the given
127 // sequence number. If we have received a response from all renderers, then it
128 // deletes the entry for sequence_number from |outstanding_requests_| map.
129 void DecrementPendingProcessesAndSendData(int sequence_number,
130 base::Value* value);
131
132 // Records that we are waiting for one less tracking data from a process for
133 // the given sequence number.
134 void DecrementPendingProcesses(int sequence_number);
135
136 // When all changes have been acquired, or when the wait time expires
137 // (whichever is sooner), this method is called. This method deletes the entry
138 // for the given sequence_number from |outstanding_requests_| map.
139 void ForceTrackingSynchronizationDoneCallback(int sequence_number);
140
141 // Gets a new sequence number to be sent to processes from browser process.
142 int GetNextAvailableSequenceNumber();
143
144 // This lock_ protects access to all members.
145 base::Lock lock_;
jar (doing other things) 2011/10/30 08:04:19 Rather than a lock, we *might* restrict this class
ramant (doing other things) 2011/11/01 00:52:15 Done.
146
147 // Map of all outstanding RequestContexts, from sequence_number_ to
148 // RequestContext.
149 RequestContextMap outstanding_requests_;
150
151 // We don't track the actual processes that are contacted for an update, only
152 // the count of the number of processes, and we can sometimes time-out and
153 // give up on a "slow to respond" process. We use a sequence_number to be
154 // sure a response from a process is associated with the current round of
155 // requests. All sequence numbers used are non-negative.
156 // last_used_sequence_number_ is the most recently used number (used to avoid
157 // reuse for a long time).
158 int last_used_sequence_number_;
159
160 // This singleton instance should be started during the single threaded
161 // portion of main(). It initializes globals to provide support for all future
162 // calls. This object is created on the UI thread, and it is destroyed after
163 // all the other threads have gone away. As a result, it is ok to call it
164 // from the UI thread, or for about:tracking.
165 static TrackingSynchronizer* tracking_synchronizer_;
166
167 // Save's the last Value received from sub-processs. TODO(rtenneti): Delete
168 // this after testing is done.
169 base::Value* last_value_from_renderer_;
170
171 DISALLOW_COPY_AND_ASSIGN(TrackingSynchronizer);
172 };
173
174 } // namespace chrome_browser_metrics
175
176 #endif // CHROME_BROWSER_METRICS_TRACKING_SYNCHRONIZER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698