summaryrefslogtreecommitdiff
path: root/chromium/content/browser/histogram_synchronizer.h
diff options
context:
space:
mode:
authorZeno Albisser <zeno.albisser@digia.com>2013-08-15 21:46:11 +0200
committerZeno Albisser <zeno.albisser@digia.com>2013-08-15 21:46:11 +0200
commit679147eead574d186ebf3069647b4c23e8ccace6 (patch)
treefc247a0ac8ff119f7c8550879ebb6d3dd8d1ff69 /chromium/content/browser/histogram_synchronizer.h
downloadqtwebengine-chromium-679147eead574d186ebf3069647b4c23e8ccace6.tar.gz
Initial import.
Diffstat (limited to 'chromium/content/browser/histogram_synchronizer.h')
-rw-r--r--chromium/content/browser/histogram_synchronizer.h154
1 files changed, 154 insertions, 0 deletions
diff --git a/chromium/content/browser/histogram_synchronizer.h b/chromium/content/browser/histogram_synchronizer.h
new file mode 100644
index 00000000000..9ff69d5cfeb
--- /dev/null
+++ b/chromium/content/browser/histogram_synchronizer.h
@@ -0,0 +1,154 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_HISTOGRAM_SYNCHRONIZER_H_
+#define CONTENT_BROWSER_HISTOGRAM_SYNCHRONIZER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/memory/singleton.h"
+#include "base/synchronization/lock.h"
+#include "base/time/time.h"
+#include "content/browser/histogram_subscriber.h"
+
+namespace base {
+class MessageLoop;
+}
+
+namespace content {
+
+// This class maintains state that is used to upload histogram data from the
+// various child processes, into the browser process. Such transactions are
+// usually instigated by the browser. In general, a child process will respond
+// by gathering snapshots of all internal histograms, calculating what has
+// changed since its last upload, and transmitting a pickled collection of
+// deltas.
+//
+// There are actually two modes of update request. One is synchronous (and
+// blocks the UI thread, waiting to populate an about:histograms tab) and the
+// other is asynchronous, and used by the metrics services in preparation for a
+// log upload.
+//
+// To assure that all the processes have responded, a counter is maintained to
+// indicate the number of pending (not yet responsive) processes. To avoid
+// confusion about a response (i.e., is the process responding to a current
+// request for an update, or to an old request for an update) we tag each group
+// of requests with a sequence number. When an update arrives we can ignore it
+// (relative to the counter) if it does not relate to a current outstanding
+// sequence number.
+//
+// There is one final mode of use, where a renderer spontaneously decides to
+// transmit a collection of histogram data. This is designed for use when the
+// renderer is terminating. Unfortunately, renders may be terminated without
+// warning, and the best we can do is periodically acquire data from a tab, such
+// as when a page load has completed. In this mode, the renderer uses a
+// reserved sequence number, different from any sequence number that might be
+// specified by a browser request. Since this sequence number can't match an
+// outstanding sequence number, the pickled data is accepted into the browser,
+// but there is no impact on the counters.
+
+class HistogramSynchronizer : public HistogramSubscriber {
+ public:
+ enum ProcessHistogramRequester {
+ UNKNOWN,
+ ASYNC_HISTOGRAMS,
+ };
+
+ // Return pointer to the singleton instance for the current process, or NULL
+ // if none.
+ static HistogramSynchronizer* GetInstance();
+
+ // Contact all processes, and get them to upload to the browser any/all
+ // changes to histograms. This method is called from about:histograms.
+ static void FetchHistograms();
+
+ // Contact all child processes, and get them to upload to the browser any/all
+ // changes to histograms. When all changes have been acquired, or when the
+ // wait time expires (whichever is sooner), post the callback to the
+ // specified message loop. Note the callback is posted exactly once.
+ static void FetchHistogramsAsynchronously(base::MessageLoop* callback_thread,
+ const base::Closure& callback,
+ base::TimeDelta wait_time);
+
+ private:
+ friend struct DefaultSingletonTraits<HistogramSynchronizer>;
+
+ class RequestContext;
+
+ HistogramSynchronizer();
+ virtual ~HistogramSynchronizer();
+
+ // Establish a new sequence number, and use it to notify all processes
+ // (renderers, plugins, GPU, etc) of the need to supply, to the browser,
+ // any/all changes to their histograms. |wait_time| specifies the amount of
+ // time to wait before cancelling the requests for non-responsive processes.
+ void RegisterAndNotifyAllProcesses(ProcessHistogramRequester requester,
+ base::TimeDelta wait_time);
+
+ // -------------------------------------------------------
+ // HistogramSubscriber methods for browser child processes
+ // -------------------------------------------------------
+
+ // Update the number of pending processes for the given |sequence_number|.
+ // This is called on UI thread.
+ virtual void OnPendingProcesses(int sequence_number,
+ int pending_processes,
+ bool end) OVERRIDE;
+
+ // Send histogram_data back to caller and also record that we are waiting
+ // for one less histogram data from child process for the given sequence
+ // number. This method is accessible on UI thread.
+ virtual void OnHistogramDataCollected(
+ int sequence_number,
+ const std::vector<std::string>& pickled_histograms) OVERRIDE;
+
+ // Set the callback_thread_ and callback_ members. If these members already
+ // had values, then as a side effect, post the old callback_ to the old
+ // callaback_thread_. This side effect should not generally happen, but is in
+ // place to assure correctness (that any tasks that were set, are eventually
+ // called, and never merely discarded).
+ void SetCallbackTaskAndThread(base::MessageLoop* callback_thread,
+ const base::Closure& callback);
+
+ void ForceHistogramSynchronizationDoneCallback(int sequence_number);
+
+ // Internal helper function, to post task, and record callback stats.
+ void InternalPostTask(base::MessageLoop* thread,
+ const base::Closure& callback);
+
+ // Gets a new sequence number to be sent to processes from browser process.
+ int GetNextAvailableSequenceNumber(ProcessHistogramRequester requester);
+
+ // This lock_ protects access to all members.
+ base::Lock lock_;
+
+ // When a request is made to asynchronously update the histograms, we store
+ // the task and thread we use to post a completion notification in
+ // callback_ and callback_thread_.
+ base::Closure callback_;
+ base::MessageLoop* callback_thread_;
+
+ // We don't track the actual processes that are contacted for an update, only
+ // the count of the number of processes, and we can sometimes time-out and
+ // give up on a "slow to respond" process. We use a sequence_number to be
+ // sure a response from a process is associated with the current round of
+ // requests (and not merely a VERY belated prior response).
+ // All sequence numbers used are non-negative.
+ // last_used_sequence_number_ is the most recently used number (used to avoid
+ // reuse for a long time).
+ int last_used_sequence_number_;
+
+ // The sequence number used by the most recent asynchronous update request to
+ // contact all processes.
+ int async_sequence_number_;
+
+ DISALLOW_COPY_AND_ASSIGN(HistogramSynchronizer);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_HISTOGRAM_SYNCHRONIZER_H_