diff options
author | mmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-04 17:48:58 +0000 |
---|---|---|
committer | mmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-04 17:48:58 +0000 |
commit | f820f6f10f3800512cccfb8755cc17af7c28c3cc (patch) | |
tree | 2e2e798a28232866e4da6d39c90363f66792c940 /chrome | |
parent | c71f66e93418080fe0cedf93175ae38dbbe05792 (diff) | |
download | chromium_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.cc | 51 | ||||
-rw-r--r-- | chrome/browser/resources/net_internals/main.js | 33 |
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); }; |