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

Side by Side Diff: content/browser/renderer_host/render_process_host_impl.cc

Issue 1214393004: Proposed new approach for SetBackgrounded. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: dchecks. Created 5 years, 5 months 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
« no previous file with comments | « content/browser/renderer_host/render_process_host_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 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 // Represents the browser side of the browser <--> renderer communication 5 // Represents the browser side of the browser <--> renderer communication
6 // channel. There will be one RenderProcessHost per renderer process. 6 // channel. There will be one RenderProcessHost per renderer process.
7 7
8 #include "content/browser/renderer_host/render_process_host_impl.h" 8 #include "content/browser/renderer_host/render_process_host_impl.h"
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 StoragePartitionImpl* storage_partition_impl, 473 StoragePartitionImpl* storage_partition_impl,
474 bool is_for_guests_only) 474 bool is_for_guests_only)
475 : fast_shutdown_started_(false), 475 : fast_shutdown_started_(false),
476 deleting_soon_(false), 476 deleting_soon_(false),
477 #ifndef NDEBUG 477 #ifndef NDEBUG
478 is_self_deleted_(false), 478 is_self_deleted_(false),
479 #endif 479 #endif
480 pending_views_(0), 480 pending_views_(0),
481 mojo_application_host_(new MojoApplicationHost), 481 mojo_application_host_(new MojoApplicationHost),
482 visible_widgets_(0), 482 visible_widgets_(0),
483 backgrounded_(true), 483 is_process_backgrounded_(false),
484 is_initialized_(false), 484 is_initialized_(false),
485 id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()), 485 id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()),
486 browser_context_(browser_context), 486 browser_context_(browser_context),
487 storage_partition_impl_(storage_partition_impl), 487 storage_partition_impl_(storage_partition_impl),
488 sudden_termination_allowed_(true), 488 sudden_termination_allowed_(true),
489 ignore_input_events_(false), 489 ignore_input_events_(false),
490 is_for_guests_only_(is_for_guests_only), 490 is_for_guests_only_(is_for_guests_only),
491 gpu_observer_registered_(false), 491 gpu_observer_registered_(false),
492 delayed_cleanup_needed_(false), 492 delayed_cleanup_needed_(false),
493 within_process_died_observer_(false), 493 within_process_died_observer_(false),
(...skipping 17 matching lines...) Expand all
511 if (!GetBrowserContext()->IsOffTheRecord() && 511 if (!GetBrowserContext()->IsOffTheRecord() &&
512 !base::CommandLine::ForCurrentProcess()->HasSwitch( 512 !base::CommandLine::ForCurrentProcess()->HasSwitch(
513 switches::kDisableGpuShaderDiskCache)) { 513 switches::kDisableGpuShaderDiskCache)) {
514 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 514 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
515 base::Bind(&CacheShaderInfo, GetID(), 515 base::Bind(&CacheShaderInfo, GetID(),
516 storage_partition_impl_->GetPath())); 516 storage_partition_impl_->GetPath()));
517 } 517 }
518 subscribe_uniform_enabled_ = 518 subscribe_uniform_enabled_ =
519 base::CommandLine::ForCurrentProcess()->HasSwitch( 519 base::CommandLine::ForCurrentProcess()->HasSwitch(
520 switches::kEnableSubscribeUniformExtension); 520 switches::kEnableSubscribeUniformExtension);
521
522 // Note: When we create the RenderProcessHostImpl, it's technically
523 // backgrounded, because it has no visible listeners. But the process
524 // doesn't actually exist yet, so we'll Background it later, after
525 // creation.
526 } 521 }
527 522
528 // static 523 // static
529 void RenderProcessHostImpl::ShutDownInProcessRenderer() { 524 void RenderProcessHostImpl::ShutDownInProcessRenderer() {
530 DCHECK(g_run_renderer_in_process_); 525 DCHECK(g_run_renderer_in_process_);
531 526
532 switch (g_all_hosts.Pointer()->size()) { 527 switch (g_all_hosts.Pointer()->size()) {
533 case 0: 528 case 0:
534 return; 529 return;
535 case 1: { 530 case 1: {
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 // crash. 1059 // crash.
1065 CHECK(false); 1060 CHECK(false);
1066 } 1061 }
1067 // We kill the renderer but don't include a NOTREACHED, because we want the 1062 // We kill the renderer but don't include a NOTREACHED, because we want the
1068 // browser to try to survive when it gets illegal messages from the renderer. 1063 // browser to try to survive when it gets illegal messages from the renderer.
1069 Shutdown(RESULT_CODE_KILLED_BAD_MESSAGE, false); 1064 Shutdown(RESULT_CODE_KILLED_BAD_MESSAGE, false);
1070 } 1065 }
1071 1066
1072 void RenderProcessHostImpl::WidgetRestored() { 1067 void RenderProcessHostImpl::WidgetRestored() {
1073 // Verify we were properly backgrounded. 1068 // Verify we were properly backgrounded.
1074 DCHECK_EQ(backgrounded_, (visible_widgets_ == 0));
1075 visible_widgets_++; 1069 visible_widgets_++;
1076 SetBackgrounded(false); 1070 UpdateProcessPriority();
1071 DCHECK(!is_process_backgrounded_);
1077 } 1072 }
1078 1073
1079 void RenderProcessHostImpl::WidgetHidden() { 1074 void RenderProcessHostImpl::WidgetHidden() {
1080 // On startup, the browser will call Hide 1075 // On startup, the browser will call Hide. We ignore these calls.
1081 if (backgrounded_) 1076 if (visible_widgets_ == 0)
1082 return; 1077 return;
1083 1078
1084 DCHECK_EQ(backgrounded_, (visible_widgets_ == 0)); 1079 DCHECK_GE(visible_widgets_, 1);
gab 2015/07/08 18:50:56 DCHECK_GT(visible_wigets, 0); slightly better IM
1085 visible_widgets_--; 1080 if (--visible_widgets_ == 0) {
1086 DCHECK_GE(visible_widgets_, 0); 1081 DCHECK(!is_process_backgrounded_);
1087 if (visible_widgets_ == 0) { 1082 UpdateProcessPriority();
1088 DCHECK(!backgrounded_);
1089 SetBackgrounded(true);
1090 } 1083 }
1091 } 1084 }
1092 1085
1093 int RenderProcessHostImpl::VisibleWidgetCount() const { 1086 int RenderProcessHostImpl::VisibleWidgetCount() const {
1094 return visible_widgets_; 1087 return visible_widgets_;
1095 } 1088 }
1096 1089
1097 bool RenderProcessHostImpl::IsForGuestsOnly() const { 1090 bool RenderProcessHostImpl::IsForGuestsOnly() const {
1098 return is_for_guests_only_; 1091 return is_for_guests_only_;
1099 } 1092 }
(...skipping 1009 matching lines...) Expand 10 before | Expand all | Expand 10 after
2109 2102
2110 RendererClosedDetails details(status, exit_code); 2103 RendererClosedDetails details(status, exit_code);
2111 mojo_application_host_->WillDestroySoon(); 2104 mojo_application_host_->WillDestroySoon();
2112 2105
2113 child_process_launcher_.reset(); 2106 child_process_launcher_.reset();
2114 channel_.reset(); 2107 channel_.reset();
2115 while (!queued_messages_.empty()) { 2108 while (!queued_messages_.empty()) {
2116 delete queued_messages_.front(); 2109 delete queued_messages_.front();
2117 queued_messages_.pop(); 2110 queued_messages_.pop();
2118 } 2111 }
2112 UpdateProcessPriority();
2113 DCHECK(!is_process_backgrounded_);
2119 2114
2120 within_process_died_observer_ = true; 2115 within_process_died_observer_ = true;
2121 NotificationService::current()->Notify( 2116 NotificationService::current()->Notify(
2122 NOTIFICATION_RENDERER_PROCESS_CLOSED, 2117 NOTIFICATION_RENDERER_PROCESS_CLOSED,
2123 Source<RenderProcessHost>(this), 2118 Source<RenderProcessHost>(this),
2124 Details<RendererClosedDetails>(&details)); 2119 Details<RendererClosedDetails>(&details));
2125 FOR_EACH_OBSERVER(RenderProcessHostObserver, 2120 FOR_EACH_OBSERVER(RenderProcessHostObserver,
2126 observers_, 2121 observers_,
2127 RenderProcessExited(this, status, exit_code)); 2122 RenderProcessExited(this, status, exit_code));
2128 within_process_died_observer_ = false; 2123 within_process_died_observer_ = false;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
2231 2226
2232 mojo_application_host_->WillDestroySoon(); 2227 mojo_application_host_->WillDestroySoon();
2233 2228
2234 Send(new ChildProcessMsg_Shutdown()); 2229 Send(new ChildProcessMsg_Shutdown());
2235 } 2230 }
2236 2231
2237 void RenderProcessHostImpl::SuddenTerminationChanged(bool enabled) { 2232 void RenderProcessHostImpl::SuddenTerminationChanged(bool enabled) {
2238 SetSuddenTerminationAllowed(enabled); 2233 SetSuddenTerminationAllowed(enabled);
2239 } 2234 }
2240 2235
2241 void RenderProcessHostImpl::SetBackgrounded(bool backgrounded) { 2236 void RenderProcessHostImpl::UpdateProcessPriority() {
2242 TRACE_EVENT1("renderer_host", "RenderProcessHostImpl::SetBackgrounded", 2237 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
gab 2015/07/08 18:50:56 const
2243 "backgrounded", backgrounded); 2238 bool process_exists =
2244 // Note: we always set the backgrounded_ value. If the process is NULL 2239 child_process_launcher_.get() && !child_process_launcher_->IsStarting();
2245 // (and hence hasn't been created yet), we will set the process priority 2240
2246 // later when we create the process. 2241 // We background a process as soon as it hosts no active audio streams and no
2247 backgrounded_ = backgrounded; 2242 // visible widgets -- the callers must call this function whenever we
2248 if (!child_process_launcher_.get() || child_process_launcher_->IsStarting()) 2243 // transition in/out of those states. Processes are initially launched with
2244 // foreground priority, so when the process doesn't exist.
2245 bool backgrounded =
gab 2015/07/08 18:50:56 s/backgrounded/should_background/ ?
2246 process_exists && visible_widgets_ == 0 &&
2247 !audio_renderer_host_->HasActiveAudio() &&
2248 !command_line->HasSwitch(switches::kDisableRendererBackgrounding);
2249
2250 if (is_process_backgrounded_ == backgrounded)
2249 return; 2251 return;
gab 2015/07/08 18:50:56 I would just keep this early return, I find it eas
ncarter (slow) 2015/07/08 19:07:19 Good point. Though, it's important to actually se
2250 2252
2251 // Don't background processes which have active audio streams. 2253 TRACE_EVENT1("renderer_host", "RenderProcessHostImpl::UpdateProcessPriority",
gab 2015/07/08 18:50:56 I think the trace should remain at the top (it's n
ncarter (slow) 2015/07/08 19:07:19 Because we're now computing |backgrounded| in the
2252 if (backgrounded_ && audio_renderer_host_->HasActiveAudio()) 2254 "backgrounded", backgrounded);
2253 return; 2255 is_process_backgrounded_ = backgrounded;
2254 2256
2255 const base::CommandLine* command_line = 2257 if (!process_exists)
2256 base::CommandLine::ForCurrentProcess(); 2258 return; // Nothing to background.
2257 if (command_line->HasSwitch(switches::kDisableRendererBackgrounding))
2258 return;
2259 2259
2260 #if defined(OS_WIN) 2260 #if defined(OS_WIN)
2261 // The cbstext.dll loads as a global GetMessage hook in the browser process 2261 // The cbstext.dll loads as a global GetMessage hook in the browser process
2262 // and intercepts/unintercepts the kernel32 API SetPriorityClass in a 2262 // and intercepts/unintercepts the kernel32 API SetPriorityClass in a
2263 // background thread. If the UI thread invokes this API just when it is 2263 // background thread. If the UI thread invokes this API just when it is
2264 // intercepted the stack is messed up on return from the interceptor 2264 // intercepted the stack is messed up on return from the interceptor
2265 // which causes random crashes in the browser process. Our hack for now 2265 // which causes random crashes in the browser process. Our hack for now
2266 // is to not invoke the SetPriorityClass API if the dll is loaded. 2266 // is to not invoke the SetPriorityClass API if the dll is loaded.
2267 if (GetModuleHandle(L"cbstext.dll")) 2267 if (GetModuleHandle(L"cbstext.dll"))
2268 return; 2268 return;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2304 if (deleting_soon_) 2304 if (deleting_soon_)
2305 return; 2305 return;
2306 2306
2307 if (child_process_launcher_) { 2307 if (child_process_launcher_) {
2308 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 2308 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
2309 // is fixed. 2309 // is fixed.
2310 tracked_objects::ScopedTracker tracking_profile2( 2310 tracked_objects::ScopedTracker tracking_profile2(
2311 FROM_HERE_WITH_EXPLICIT_FUNCTION( 2311 FROM_HERE_WITH_EXPLICIT_FUNCTION(
2312 "465841 RenderProcessHostImpl::OnProcessLaunched::Backgrounded")); 2312 "465841 RenderProcessHostImpl::OnProcessLaunched::Backgrounded"));
2313 DCHECK(child_process_launcher_->GetProcess().IsValid()); 2313 DCHECK(child_process_launcher_->GetProcess().IsValid());
2314 SetBackgrounded(backgrounded_); 2314 DCHECK(!is_process_backgrounded_);
2315 UpdateProcessPriority();
2315 } 2316 }
2316 2317
2317 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 2318 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841
2318 // is fixed. 2319 // is fixed.
2319 tracked_objects::ScopedTracker tracking_profile3( 2320 tracked_objects::ScopedTracker tracking_profile3(
2320 FROM_HERE_WITH_EXPLICIT_FUNCTION( 2321 FROM_HERE_WITH_EXPLICIT_FUNCTION(
2321 "465841 RenderProcessHostImpl::OnProcessLaunched::Notify")); 2322 "465841 RenderProcessHostImpl::OnProcessLaunched::Notify"));
2322 // NOTE: This needs to be before sending queued messages because 2323 // NOTE: This needs to be before sending queued messages because
2323 // ExtensionService uses this notification to initialize the renderer process 2324 // ExtensionService uses this notification to initialize the renderer process
2324 // with state that must be there before any JavaScript executes. 2325 // with state that must be there before any JavaScript executes.
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
2514 void RenderProcessHostImpl::GetAudioOutputControllers( 2515 void RenderProcessHostImpl::GetAudioOutputControllers(
2515 const GetAudioOutputControllersCallback& callback) const { 2516 const GetAudioOutputControllersCallback& callback) const {
2516 audio_renderer_host()->GetOutputControllers(callback); 2517 audio_renderer_host()->GetOutputControllers(callback);
2517 } 2518 }
2518 2519
2519 BluetoothDispatcherHost* RenderProcessHostImpl::GetBluetoothDispatcherHost() { 2520 BluetoothDispatcherHost* RenderProcessHostImpl::GetBluetoothDispatcherHost() {
2520 return bluetooth_dispatcher_host_.get(); 2521 return bluetooth_dispatcher_host_.get();
2521 } 2522 }
2522 2523
2523 } // namespace content 2524 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_process_host_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698