| Index: chrome/renderer/render_thread.cc
|
| ===================================================================
|
| --- chrome/renderer/render_thread.cc (revision 24436)
|
| +++ chrome/renderer/render_thread.cc (working copy)
|
| @@ -9,6 +9,7 @@
|
|
|
| #include "base/command_line.h"
|
| #include "base/lazy_instance.h"
|
| +#include "base/logging.h"
|
| #include "base/shared_memory.h"
|
| #include "base/stats_table.h"
|
| #include "base/thread_local.h"
|
| @@ -58,6 +59,8 @@
|
|
|
| namespace {
|
| static const unsigned int kCacheStatsDelayMS = 2000 /* milliseconds */;
|
| +static const double kInitialIdleHandlerDelayS = 1.0 /* seconds */;
|
| +
|
| static base::LazyInstance<base::ThreadLocalPointer<RenderThread> > lazy_tls(
|
| base::LINKER_INITIALIZED);
|
|
|
| @@ -105,8 +108,11 @@
|
| #endif
|
|
|
| plugin_refresh_allowed_ = true;
|
| - cache_stats_factory_.reset(
|
| - new ScopedRunnableMethodFactory<RenderThread>(this));
|
| + cache_stats_task_pending_ = false;
|
| + widget_count_ = 0;
|
| + hidden_widget_count_ = 0;
|
| + idle_notification_delay_in_s_ = kInitialIdleHandlerDelayS;
|
| + task_factory_.reset(new ScopedRunnableMethodFactory<RenderThread>(this));
|
|
|
| visited_link_slave_.reset(new VisitedLinkSlave());
|
| user_script_slave_.reset(new UserScriptSlave());
|
| @@ -156,6 +162,30 @@
|
| channel()->RemoveFilter(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);
|
| + }
|
| +}
|
| +
|
| +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.
|
| +}
|
| +
|
| void RenderThread::Resolve(const char* name, size_t length) {
|
| return dns_master_->Resolve(name, length);
|
| }
|
| @@ -316,15 +346,17 @@
|
| WebCache::UsageStats stats;
|
| WebCache::getUsageStats(&stats);
|
| Send(new ViewHostMsg_UpdatedCacheStats(stats));
|
| + cache_stats_task_pending_ = false;
|
| }
|
|
|
| void RenderThread::InformHostOfCacheStatsLater() {
|
| // Rate limit informing the host of our cache stats.
|
| - if (!cache_stats_factory_->empty())
|
| + if (cache_stats_task_pending_)
|
| return;
|
|
|
| + cache_stats_task_pending_ = true;
|
| MessageLoop::current()->PostDelayedTask(FROM_HERE,
|
| - cache_stats_factory_->NewRunnableMethod(
|
| + task_factory_->NewRunnableMethod(
|
| &RenderThread::InformHostOfCacheStats),
|
| kCacheStatsDelayMS);
|
| }
|
| @@ -424,6 +456,34 @@
|
| }
|
| }
|
|
|
| +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 (v8::V8::IsDead())
|
| + return;
|
| +
|
| + LOG(INFO) << "RenderThread calling v8 IdleNotification for " << this;
|
| +
|
| + // When V8::IdleNotification returns true, it means that it has cleaned up
|
| + // as much as it can. There is no point in continuing to call it.
|
| + if (!v8::V8::IdleNotification(false)) {
|
| + // Dampen the delay using the algorithm:
|
| + // delay = delay + 1 / (delay + 2)
|
| + // Using floor(delay) has a dampening effect such as:
|
| + // 1s, 1, 1, 2, 2, 2, 2, 3, 3, ...
|
| + idle_notification_delay_in_s_ +=
|
| + 1.0 / (idle_notification_delay_in_s_ + 2.0);
|
| +
|
| + // 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::OnExtensionMessageInvoke(const std::string& function_name,
|
| const ListValue& args) {
|
| RendererExtensionBindings::Invoke(function_name, args, NULL);
|
|
|