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

Side by Side Diff: extensions/browser/process_manager.cc

Issue 60613004: Add KeepaliveImpulse to extension process manager. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Back to 1sec times for tests. Created 7 years 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/browser/process_manager.h" 5 #include "extensions/browser/process_manager.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 126
127 ProcessManager* process_manager_; 127 ProcessManager* process_manager_;
128 128
129 DISALLOW_COPY_AND_ASSIGN(RenderViewHostDestructionObserver); 129 DISALLOW_COPY_AND_ASSIGN(RenderViewHostDestructionObserver);
130 }; 130 };
131 131
132 struct ProcessManager::BackgroundPageData { 132 struct ProcessManager::BackgroundPageData {
133 // The count of things keeping the lazy background page alive. 133 // The count of things keeping the lazy background page alive.
134 int lazy_keepalive_count; 134 int lazy_keepalive_count;
135 135
136 // Tracks if an impulse event has occured since the last polling check.
137 bool keepalive_impulse;
138 bool previous_keepalive_impulse;
139
136 // This is used with the ShouldSuspend message, to ensure that the extension 140 // This is used with the ShouldSuspend message, to ensure that the extension
137 // remained idle between sending the message and receiving the ack. 141 // remained idle between sending the message and receiving the ack.
138 int close_sequence_id; 142 int close_sequence_id;
139 143
140 // True if the page responded to the ShouldSuspend message and is currently 144 // True if the page responded to the ShouldSuspend message and is currently
141 // dispatching the suspend event. During this time any events that arrive will 145 // dispatching the suspend event. During this time any events that arrive will
142 // cancel the suspend process and an onSuspendCanceled event will be 146 // cancel the suspend process and an onSuspendCanceled event will be
143 // dispatched to the page. 147 // dispatched to the page.
144 bool is_closing; 148 bool is_closing;
145 149
146 // Keeps track of when this page was last suspended. Used for perf metrics. 150 // Keeps track of when this page was last suspended. Used for perf metrics.
147 linked_ptr<base::ElapsedTimer> since_suspended; 151 linked_ptr<base::ElapsedTimer> since_suspended;
148 152
149 BackgroundPageData() 153 BackgroundPageData()
150 : lazy_keepalive_count(0), close_sequence_id(0), is_closing(false) {} 154 : lazy_keepalive_count(0),
155 keepalive_impulse(false),
156 previous_keepalive_impulse(false),
157 close_sequence_id(0),
158 is_closing(false) {}
151 }; 159 };
152 160
153 // 161 //
154 // ProcessManager 162 // ProcessManager
155 // 163 //
156 164
157 // static 165 // static
158 ProcessManager* ProcessManager::Create(BrowserContext* context) { 166 ProcessManager* ProcessManager::Create(BrowserContext* context) {
159 if (context->IsOffTheRecord()) { 167 if (context->IsOffTheRecord()) {
160 BrowserContext* original_context = 168 BrowserContext* original_context =
(...skipping 29 matching lines...) Expand all
190 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED, 198 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
191 content::Source<BrowserContext>(original_context)); 199 content::Source<BrowserContext>(original_context));
192 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, 200 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
193 content::Source<BrowserContext>(context)); 201 content::Source<BrowserContext>(context));
194 if (context->IsOffTheRecord()) { 202 if (context->IsOffTheRecord()) {
195 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, 203 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
196 content::Source<BrowserContext>(original_context)); 204 content::Source<BrowserContext>(original_context));
197 } 205 }
198 206
199 event_page_idle_time_ = base::TimeDelta::FromSeconds(10); 207 event_page_idle_time_ = base::TimeDelta::FromSeconds(10);
200 unsigned idle_time_sec = 0; 208 unsigned idle_time_msec = 0;
201 if (base::StringToUint(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 209 if (base::StringToUint(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
202 extensions::switches::kEventPageIdleTime), &idle_time_sec)) { 210 extensions::switches::kEventPageIdleTime), &idle_time_msec)) {
203 event_page_idle_time_ = base::TimeDelta::FromSeconds(idle_time_sec); 211 CHECK(idle_time_msec > 0); // OnKeepaliveImpulseCheck requires non zero.
tapted 2013/11/28 03:03:37 optional nit: maybe CHECK_NE(0u, idle_time_msec)?
scheib 2013/12/02 21:22:38 I think this check output is pretty clear as is wi
212 event_page_idle_time_ = base::TimeDelta::FromMilliseconds(idle_time_msec);
204 } 213 }
205 event_page_suspending_time_ = base::TimeDelta::FromSeconds(5); 214 event_page_suspending_time_ = base::TimeDelta::FromSeconds(5);
206 unsigned suspending_time_sec = 0; 215 unsigned suspending_time_msec = 0;
207 if (base::StringToUint(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 216 if (base::StringToUint(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
208 extensions::switches::kEventPageSuspendingTime), 217 extensions::switches::kEventPageSuspendingTime),
209 &suspending_time_sec)) { 218 &suspending_time_msec)) {
210 event_page_suspending_time_ = 219 event_page_suspending_time_ =
211 base::TimeDelta::FromSeconds(suspending_time_sec); 220 base::TimeDelta::FromMilliseconds(suspending_time_msec);
212 } 221 }
213 222
214 content::DevToolsManager::GetInstance()->AddAgentStateCallback( 223 content::DevToolsManager::GetInstance()->AddAgentStateCallback(
215 devtools_callback_); 224 devtools_callback_);
225
226 OnKeepaliveImpulseCheck();
216 } 227 }
217 228
218 ProcessManager::~ProcessManager() { 229 ProcessManager::~ProcessManager() {
219 CloseBackgroundHosts(); 230 CloseBackgroundHosts();
220 DCHECK(background_hosts_.empty()); 231 DCHECK(background_hosts_.empty());
221 content::DevToolsManager::GetInstance()->RemoveAgentStateCallback( 232 content::DevToolsManager::GetInstance()->RemoveAgentStateCallback(
222 devtools_callback_); 233 devtools_callback_);
223 } 234 }
224 235
225 const ProcessManager::ViewSet ProcessManager::GetAllViews() const { 236 const ProcessManager::ViewSet ProcessManager::GetAllViews() const {
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 int& count = background_page_data_[extension->id()].lazy_keepalive_count; 364 int& count = background_page_data_[extension->id()].lazy_keepalive_count;
354 if (++count == 1) 365 if (++count == 1)
355 OnLazyBackgroundPageActive(extension->id()); 366 OnLazyBackgroundPageActive(extension->id());
356 367
357 return count; 368 return count;
358 } 369 }
359 370
360 int ProcessManager::DecrementLazyKeepaliveCount(const Extension* extension) { 371 int ProcessManager::DecrementLazyKeepaliveCount(const Extension* extension) {
361 if (!BackgroundInfo::HasLazyBackgroundPage(extension)) 372 if (!BackgroundInfo::HasLazyBackgroundPage(extension))
362 return 0; 373 return 0;
374 return DecrementLazyKeepaliveCount(extension->id());
375 }
363 376
364 int& count = background_page_data_[extension->id()].lazy_keepalive_count; 377 int ProcessManager::DecrementLazyKeepaliveCount(std::string extension_id) {
378 int& count = background_page_data_[extension_id].lazy_keepalive_count;
365 DCHECK_GT(count, 0); 379 DCHECK_GT(count, 0);
366 380
367 // If we reach a zero keepalive count when the lazy background page is about 381 // If we reach a zero keepalive count when the lazy background page is about
368 // to be closed, incrementing close_sequence_id will cancel the close 382 // to be closed, incrementing close_sequence_id will cancel the close
369 // sequence and cause the background page to linger. So check is_closing 383 // sequence and cause the background page to linger. So check is_closing
370 // before initiating another close sequence. 384 // before initiating another close sequence.
371 if (--count == 0 && !background_page_data_[extension->id()].is_closing) { 385 if (--count == 0 && !background_page_data_[extension_id].is_closing) {
372 base::MessageLoop::current()->PostDelayedTask( 386 base::MessageLoop::current()->PostDelayedTask(
373 FROM_HERE, 387 FROM_HERE,
374 base::Bind(&ProcessManager::OnLazyBackgroundPageIdle, 388 base::Bind(&ProcessManager::OnLazyBackgroundPageIdle,
375 weak_ptr_factory_.GetWeakPtr(), extension->id(), 389 weak_ptr_factory_.GetWeakPtr(), extension_id,
376 ++background_page_data_[extension->id()].close_sequence_id), 390 ++background_page_data_[extension_id].close_sequence_id),
377 event_page_idle_time_); 391 event_page_idle_time_);
378 } 392 }
379 393
380 return count; 394 return count;
381 } 395 }
382 396
383 void ProcessManager::IncrementLazyKeepaliveCountForView( 397 void ProcessManager::IncrementLazyKeepaliveCountForView(
384 RenderViewHost* render_view_host) { 398 RenderViewHost* render_view_host) {
385 WebContents* web_contents = 399 WebContents* web_contents =
386 WebContents::FromRenderViewHost(render_view_host); 400 WebContents::FromRenderViewHost(render_view_host);
387 ViewType view_type = GetViewType(web_contents); 401 ViewType view_type = GetViewType(web_contents);
388 if (view_type != VIEW_TYPE_INVALID && 402 if (view_type != VIEW_TYPE_INVALID &&
389 view_type != VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { 403 view_type != VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) {
390 const Extension* extension = GetExtensionForRenderViewHost( 404 const Extension* extension = GetExtensionForRenderViewHost(
391 render_view_host); 405 render_view_host);
392 if (extension) 406 if (extension)
393 IncrementLazyKeepaliveCount(extension); 407 IncrementLazyKeepaliveCount(extension);
394 } 408 }
395 } 409 }
396 410
411 // This implementation layers on top of the keepalive count. An impulse sets
412 // a per extension flag. On a regular interval that flag is checked. Changes
413 // from the flag not being set to set cause an IncrementLazyKeepaliveCount.
414 void ProcessManager::KeepaliveImpulse(const Extension* extension) {
415 if (!BackgroundInfo::HasLazyBackgroundPage(extension))
416 return;
417
418 BackgroundPageData& bd = background_page_data_[extension->id()];
419
420 if (!bd.keepalive_impulse) {
421 bd.keepalive_impulse = true;
422 if (!bd.previous_keepalive_impulse) {
423 IncrementLazyKeepaliveCount(extension);
424 }
425 }
426 }
427
428 // DecrementLazyKeepaliveCount is called when no calls to KeepaliveImpulse
429 // have been made for at least event_page_idle_time_. In the best case an
430 // impulse was made just before being cleared, and the decrement will occur
431 // event_page_idle_time_ later, causing a 2 * event_page_idle_time_ total time
432 // for extension to be shut down based on impulses. Worst case is an impulse
433 // just after a clear, adding one check cycle and resulting in 3x total time.
434 void ProcessManager::OnKeepaliveImpulseCheck() {
435 for (BackgroundPageDataMap::iterator i = background_page_data_.begin();
436 i != background_page_data_.end();
437 ++i) {
438 bool this_impulse = i->second.keepalive_impulse;
tapted 2013/11/28 03:03:37 (optional) This might be easier to read without th
scheib 2013/12/02 21:22:38 Done; your first suggestion. The latter didn't reu
439 bool previous_impulse = i->second.previous_keepalive_impulse;
440 i->second.keepalive_impulse = false;
441 i->second.previous_keepalive_impulse = this_impulse;
442
443 if (previous_impulse && !this_impulse)
444 DecrementLazyKeepaliveCount(i->first);
tapted 2013/11/28 03:03:37 I thought it weird that the return value wasn't ch
scheib 2013/12/02 21:22:38 Done.
445 }
446
447 if (base::MessageLoop::current()) {
tapted 2013/11/28 03:03:37 Maybe a comment here to explain this check (e.g. S
scheib 2013/12/02 21:22:38 Done.
448 base::MessageLoop::current()->PostDelayedTask(
449 FROM_HERE,
450 base::Bind(&ProcessManager::OnKeepaliveImpulseCheck,
451 weak_ptr_factory_.GetWeakPtr()),
452 event_page_idle_time_);
453 }
454 }
455
397 void ProcessManager::OnLazyBackgroundPageIdle(const std::string& extension_id, 456 void ProcessManager::OnLazyBackgroundPageIdle(const std::string& extension_id,
398 int sequence_id) { 457 int sequence_id) {
399 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); 458 ExtensionHost* host = GetBackgroundHostForExtension(extension_id);
400 if (host && !background_page_data_[extension_id].is_closing && 459 if (host && !background_page_data_[extension_id].is_closing &&
401 sequence_id == background_page_data_[extension_id].close_sequence_id) { 460 sequence_id == background_page_data_[extension_id].close_sequence_id) {
402 // Tell the renderer we are about to close. This is a simple ping that the 461 // Tell the renderer we are about to close. This is a simple ping that the
403 // renderer will respond to. The purpose is to control sequencing: if the 462 // renderer will respond to. The purpose is to control sequencing: if the
404 // extension remains idle until the renderer responds with an ACK, then we 463 // extension remains idle until the renderer responds with an ACK, then we
405 // know that the extension process is ready to shut down. If our 464 // know that the extension process is ready to shut down. If our
406 // close_sequence_id has already changed, then we would ignore the 465 // close_sequence_id has already changed, then we would ignore the
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 } 865 }
807 866
808 bool IncognitoProcessManager::IsIncognitoEnabled(const Extension* extension) { 867 bool IncognitoProcessManager::IsIncognitoEnabled(const Extension* extension) {
809 // Keep in sync with duplicate in extension_info_map.cc. 868 // Keep in sync with duplicate in extension_info_map.cc.
810 ExtensionService* service = ExtensionSystem::GetForBrowserContext( 869 ExtensionService* service = ExtensionSystem::GetForBrowserContext(
811 GetBrowserContext())->extension_service(); 870 GetBrowserContext())->extension_service();
812 return extension_util::IsIncognitoEnabled(extension->id(), service); 871 return extension_util::IsIncognitoEnabled(extension->id(), service);
813 } 872 }
814 873
815 } // namespace extensions 874 } // namespace extensions
OLDNEW
« extensions/browser/process_manager.h ('K') | « extensions/browser/process_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698