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

Unified Diff: chrome/renderer/render_thread.cc

Issue 460062: Hook up V8 idle notifications for extension prcoesses. (Closed)
Patch Set: dampen max timer Created 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/renderer/render_thread.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/renderer/render_thread.cc
diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc
index 2a620059f6eb4d92df6b95bf20252ba0f2ea5f54..9dd5cdcc282eaa9afc6ba682815fac213d6971f8 100644
--- a/chrome/renderer/render_thread.cc
+++ b/chrome/renderer/render_thread.cc
@@ -93,6 +93,8 @@ using WebKit::WebView;
namespace {
static const unsigned int kCacheStatsDelayMS = 2000 /* milliseconds */;
static const double kInitialIdleHandlerDelayS = 1.0 /* seconds */;
+static const double kInitialExtensionIdleHandlerDelayS = 5.0 /* seconds */;
+static const int64 kMaxExtensionIdleHandlerDelayS = 5*60 /* seconds */;
static base::LazyInstance<base::ThreadLocalPointer<RenderThread> > lazy_tls(
base::LINKER_INITIALIZED);
@@ -161,11 +163,15 @@ void RenderThread::Init() {
CoInitialize(0);
#endif
+ std::string type_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kProcessType);
+ is_extension_process_ = type_str == switches::kExtensionProcess;
plugin_refresh_allowed_ = true;
cache_stats_task_pending_ = false;
widget_count_ = 0;
hidden_widget_count_ = 0;
- idle_notification_delay_in_s_ = kInitialIdleHandlerDelayS;
+ idle_notification_delay_in_s_ = is_extension_process_ ?
+ kInitialExtensionIdleHandlerDelayS : kInitialIdleHandlerDelayS;
task_factory_.reset(new ScopedRunnableMethodFactory<RenderThread>(this));
visited_link_slave_.reset(new VisitedLinkSlave());
@@ -220,25 +226,16 @@ void RenderThread::RemoveFilter(IPC::ChannelProxy::MessageFilter* filter) {
void RenderThread::WidgetHidden() {
DCHECK(hidden_widget_count_ < widget_count_);
hidden_widget_count_++;
- if (widget_count_ && hidden_widget_count_ == widget_count_) {
- // Reset the delay.
- idle_notification_delay_in_s_ = kInitialIdleHandlerDelayS;
-
- // Schedule the IdleHandler to wakeup in a bit.
- MessageLoop::current()->PostDelayedTask(FROM_HERE,
- task_factory_->NewRunnableMethod(&RenderThread::IdleHandler),
- static_cast<int64>(floor(idle_notification_delay_in_s_)) * 1000);
- }
+ if (!is_extension_process() &&
+ widget_count_ && hidden_widget_count_ == widget_count_)
+ ScheduleIdleHandler(kInitialIdleHandlerDelayS);
}
void RenderThread::WidgetRestored() {
DCHECK(hidden_widget_count_ > 0);
hidden_widget_count_--;
-
- // Note: we may have a timer pending to call the IdleHandler (see the
- // WidgetHidden() code). But we don't bother to cancel it as it is
- // benign and won't do anything if the tab is un-hidden when it is
- // called.
+ if (!is_extension_process())
+ idle_timer_.Stop();
}
void RenderThread::Resolve(const char* name, size_t length) {
@@ -291,6 +288,11 @@ void RenderThread::OnExtensionSetAPIPermissions(
const std::string& extension_id,
const std::vector<std::string>& permissions) {
ExtensionProcessBindings::SetAPIPermissions(extension_id, permissions);
+
+ // This is called when starting a new extension page, so start the idle
+ // handler ticking.
+ DCHECK(is_extension_process());
+ ScheduleIdleHandler(kInitialExtensionIdleHandlerDelayS);
}
void RenderThread::OnExtensionSetHostPermissions(
@@ -500,6 +502,14 @@ void RenderThread::EnsureWebKitInitialized() {
if (webkit_client_.get())
return;
+ // For extensions, we want to ensure we call the IdleHandler every so often,
+ // even if the extension keeps up activity.
+ if (is_extension_process()) {
+ forced_idle_timer_.Start(
+ base::TimeDelta::FromSeconds(kMaxExtensionIdleHandlerDelayS),
+ this, &RenderThread::IdleHandler);
+ }
+
v8::V8::SetCounterFunction(StatsTable::FindLocation);
v8::V8::SetCreateHistogramFunction(CreateHistogram);
v8::V8::SetAddHistogramSampleFunction(AddHistogramSample);
@@ -601,11 +611,6 @@ void RenderThread::EnsureWebKitInitialized() {
}
void RenderThread::IdleHandler() {
- // It is possible that the timer was set while the widgets were idle,
- // but that they are no longer idle. If so, just return.
- if (!widget_count_ || hidden_widget_count_ < widget_count_)
- return;
-
#if defined(OS_WIN) && defined(USE_TCMALLOC)
MallocExtension::instance()->ReleaseFreeMemory();
#endif
@@ -620,18 +625,37 @@ void RenderThread::IdleHandler() {
// 1s, 1, 1, 2, 2, 2, 2, 3, 3, ...
// Note that idle_notification_delay_in_s_ would be reset to
// kInitialIdleHandlerDelayS in RenderThread::WidgetHidden.
- idle_notification_delay_in_s_ +=
- 1.0 / (idle_notification_delay_in_s_ + 2.0);
+ ScheduleIdleHandler(idle_notification_delay_in_s_ +
+ 1.0 / (idle_notification_delay_in_s_ + 2.0));
+ if (is_extension_process()) {
+ // Dampen the forced delay as well if the extension stays idle for long
+ // periods of time.
+ int64 forced_delay_s =
+ std::max(static_cast<int64>(idle_notification_delay_in_s_),
+ kMaxExtensionIdleHandlerDelayS);
+ forced_idle_timer_.Stop();
+ forced_idle_timer_.Start(
+ base::TimeDelta::FromSeconds(forced_delay_s),
+ this, &RenderThread::IdleHandler);
+ }
+}
- // Schedule the next timer.
- MessageLoop::current()->PostDelayedTask(FROM_HERE,
- task_factory_->NewRunnableMethod(&RenderThread::IdleHandler),
- static_cast<int64>(floor(idle_notification_delay_in_s_)) * 1000);
+void RenderThread::ScheduleIdleHandler(double initial_delay_s) {
+ idle_notification_delay_in_s_ = initial_delay_s;
+ idle_timer_.Stop();
+ idle_timer_.Start(
+ base::TimeDelta::FromSeconds(static_cast<int64>(initial_delay_s)),
+ this, &RenderThread::IdleHandler);
}
void RenderThread::OnExtensionMessageInvoke(const std::string& function_name,
const ListValue& args) {
RendererExtensionBindings::Invoke(function_name, args, NULL);
+
+ // Reset the idle handler each time there's any activity like event or message
+ // dispatch, for which Invoke is the chokepoint.
+ if (is_extension_process())
+ ScheduleIdleHandler(kInitialExtensionIdleHandlerDelayS);
}
void RenderThread::OnPurgeMemory() {
« no previous file with comments | « chrome/renderer/render_thread.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698