summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authormmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-04 17:48:58 +0000
committermmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-04 17:48:58 +0000
commitf820f6f10f3800512cccfb8755cc17af7c28c3cc (patch)
tree2e2e798a28232866e4da6d39c90363f66792c940 /chrome
parentc71f66e93418080fe0cedf93175ae38dbbe05792 (diff)
downloadchromium_src-f820f6f10f3800512cccfb8755cc17af7c28c3cc.zip
chromium_src-f820f6f10f3800512cccfb8755cc17af7c28c3cc.tar.gz
chromium_src-f820f6f10f3800512cccfb8755cc17af7c28c3cc.tar.bz2
Reduces the CPU usage when about:net-internals is open,
and a lot of events are being logged in a short period. Does this by collecting events on the IO thread, and then sending them all off to Javascript event 100 ms. Also makes net-internals event ordering match the order they're handled by the ChromeNetLog. I believe that currently all sources live on a single thread, so don't think that matters a whole lot right now, but you never know... BUG=57214 TEST=manual Review URL: http://codereview.chromium.org/5918002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@70417 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/dom_ui/net_internals_ui.cc51
-rw-r--r--chrome/browser/resources/net_internals/main.js33
2 files changed, 63 insertions, 21 deletions
diff --git a/chrome/browser/dom_ui/net_internals_ui.cc b/chrome/browser/dom_ui/net_internals_ui.cc
index 0cea72a..07109ba 100644
--- a/chrome/browser/dom_ui/net_internals_ui.cc
+++ b/chrome/browser/dom_ui/net_internals_ui.cc
@@ -54,6 +54,11 @@
namespace {
+// Delay between when an event occurs and when it is passed to the Javascript
+// page. All events that occur during this period are grouped together and
+// sent to the page at once, which reduces context switching and CPU usage.
+const int kNetLogEventDelayMilliseconds = 100;
+
// Returns the HostCache for |context|'s primary HostResolver, or NULL if
// there is none.
net::HostCache* GetHostResolverCache(URLRequestContext* context) {
@@ -245,8 +250,18 @@ class NetInternalsMessageHandler::IOThreadImpl
// Helper that executes |function_name| in the attached renderer.
// The function takes ownership of |arg|. Note that this can be called from
// any thread.
- void CallJavascriptFunction(const std::wstring& function_name,
- Value* arg);
+ void CallJavascriptFunction(const std::wstring& function_name, Value* arg);
+
+ // Adds |entry| to the queue of pending log entries to be sent to the page via
+ // Javascript. Must be called on the IO Thread. Also creates a delayed task
+ // that will call PostPendingEntries, if there isn't one already.
+ void AddEntryToQueue(Value* entry);
+
+ // Sends all pending entries to the page via Javascript, and clears the list
+ // of pending entries. Sending multiple entries at once results in a
+ // significant reduction of CPU usage when a lot of events are happening.
+ // Must be called on the IO Thread.
+ void PostPendingEntries();
// Pointer to the UI-thread message handler. Only access this from
// the UI thread.
@@ -271,6 +286,11 @@ class NetInternalsMessageHandler::IOThreadImpl
// True if we have attached an observer to the NetLog already.
bool is_observing_log_;
friend class base::RefCountedThreadSafe<IOThreadImpl>;
+
+ // Log entries that have yet to be passed along to Javascript page. Non-NULL
+ // when and only when there is a pending delayed task to call
+ // PostPendingEntries. Read and written to exclusively on the IO Thread.
+ scoped_ptr<ListValue> pending_entries_;
};
// Helper class for a DOMUI::MessageCallback which when excuted calls
@@ -951,10 +971,31 @@ void NetInternalsMessageHandler::IOThreadImpl::OnAddEntry(
const net::NetLog::Source& source,
net::NetLog::EventPhase phase,
net::NetLog::EventParameters* params) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(
+ this, &IOThreadImpl::AddEntryToQueue,
+ net::NetLog::EntryToDictionaryValue(type, time, source, phase,
+ params, false)));
+}
+
+void NetInternalsMessageHandler::IOThreadImpl::AddEntryToQueue(Value* entry) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ if (!pending_entries_.get()) {
+ pending_entries_.reset(new ListValue());
+ BrowserThread::PostDelayedTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(this, &IOThreadImpl::PostPendingEntries),
+ kNetLogEventDelayMilliseconds);
+ }
+ pending_entries_->Append(entry);
+}
+
+void NetInternalsMessageHandler::IOThreadImpl::PostPendingEntries() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
CallJavascriptFunction(
- L"g_browser.receivedLogEntry",
- net::NetLog::EntryToDictionaryValue(type, time, source, phase, params,
- false));
+ L"g_browser.receivedLogEntries",
+ pending_entries_.release());
}
void NetInternalsMessageHandler::IOThreadImpl::OnStartConnectionTestSuite() {
diff --git a/chrome/browser/resources/net_internals/main.js b/chrome/browser/resources/net_internals/main.js
index 70a1b51..d879c87 100644
--- a/chrome/browser/resources/net_internals/main.js
+++ b/chrome/browser/resources/net_internals/main.js
@@ -306,15 +306,19 @@ BrowserBridge.prototype.setLogLevel = function(logLevel) {
// Messages received from the browser
//------------------------------------------------------------------------------
-BrowserBridge.prototype.receivedLogEntry = function(logEntry) {
- // Assign unique ID, if needed.
- if (logEntry.source.id == 0) {
- logEntry.source.id = this.nextSourcelessEventId_;
- --this.nextSourcelessEventId_;
+BrowserBridge.prototype.receivedLogEntries = function(logEntries) {
+ for (var e = 0; e < logEntries.length; ++e) {
+ var logEntry = logEntries[e];
+
+ // Assign unique ID, if needed.
+ if (logEntry.source.id == 0) {
+ logEntry.source.id = this.nextSourcelessEventId_;
+ --this.nextSourcelessEventId_;
+ }
+ this.capturedEvents_.push(logEntry);
+ for (var i = 0; i < this.logObservers_.length; ++i)
+ this.logObservers_[i].onLogEntryAdded(logEntry);
}
- this.capturedEvents_.push(logEntry);
- for (var i = 0; i < this.logObservers_.length; ++i)
- this.logObservers_[i].onLogEntryAdded(logEntry);
};
BrowserBridge.prototype.receivedLogEventTypeConstants = function(constantsMap) {
@@ -395,16 +399,13 @@ BrowserBridge.prototype.receivedPassiveLogEntries = function(entries) {
this.deleteAllEvents();
this.numPassivelyCapturedEvents_ = entries.length;
- for (var i = 0; i < entries.length; ++i) {
- var entry = entries[i];
- entry.wasPassivelyCaptured = true;
- this.receivedLogEntry(entry);
- }
+ for (var i = 0; i < entries.length; ++i)
+ entries[i].wasPassivelyCaptured = true;
+ this.receivedLogEntries(entries);
// Add back early actively captured events, if any.
- for (var i = 0; i < earlyActivelyCapturedEvents.length; ++i) {
- this.receivedLogEntry(earlyActivelyCapturedEvents[i]);
- }
+ if (earlyActivelyCapturedEvents.length)
+ this.receivedLogEntries(earlyActivelyCapturedEvents);
};