| OLD | NEW | 
|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "chrome/renderer/render_thread.h" | 5 #include "chrome/renderer/render_thread.h" | 
| 6 | 6 | 
| 7 #include <algorithm> | 7 #include <algorithm> | 
| 8 #include <vector> | 8 #include <vector> | 
| 9 | 9 | 
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" | 
| 11 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" | 
|  | 12 #include "base/logging.h" | 
| 12 #include "base/shared_memory.h" | 13 #include "base/shared_memory.h" | 
| 13 #include "base/stats_table.h" | 14 #include "base/stats_table.h" | 
| 14 #include "base/thread_local.h" | 15 #include "base/thread_local.h" | 
| 15 #include "chrome/common/appcache/appcache_dispatcher.h" | 16 #include "chrome/common/appcache/appcache_dispatcher.h" | 
| 16 #include "chrome/common/chrome_switches.h" | 17 #include "chrome/common/chrome_switches.h" | 
| 17 #include "chrome/common/db_message_filter.h" | 18 #include "chrome/common/db_message_filter.h" | 
| 18 #include "chrome/common/render_messages.h" | 19 #include "chrome/common/render_messages.h" | 
| 19 #include "chrome/common/renderer_preferences.h" | 20 #include "chrome/common/renderer_preferences.h" | 
| 20 #include "chrome/common/url_constants.h" | 21 #include "chrome/common/url_constants.h" | 
| 21 #include "chrome/plugin/npobject_util.h" | 22 #include "chrome/plugin/npobject_util.h" | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 51 #if defined(OS_WIN) | 52 #if defined(OS_WIN) | 
| 52 #include <windows.h> | 53 #include <windows.h> | 
| 53 #include <objbase.h> | 54 #include <objbase.h> | 
| 54 #endif | 55 #endif | 
| 55 | 56 | 
| 56 using WebKit::WebCache; | 57 using WebKit::WebCache; | 
| 57 using WebKit::WebString; | 58 using WebKit::WebString; | 
| 58 | 59 | 
| 59 namespace { | 60 namespace { | 
| 60 static const unsigned int kCacheStatsDelayMS = 2000 /* milliseconds */; | 61 static const unsigned int kCacheStatsDelayMS = 2000 /* milliseconds */; | 
|  | 62 static const double kInitialIdleHandlerDelayS = 1.0 /* seconds */; | 
|  | 63 | 
| 61 static base::LazyInstance<base::ThreadLocalPointer<RenderThread> > lazy_tls( | 64 static base::LazyInstance<base::ThreadLocalPointer<RenderThread> > lazy_tls( | 
| 62     base::LINKER_INITIALIZED); | 65     base::LINKER_INITIALIZED); | 
| 63 | 66 | 
| 64 #if defined(OS_POSIX) | 67 #if defined(OS_POSIX) | 
| 65 class SuicideOnChannelErrorFilter : public IPC::ChannelProxy::MessageFilter { | 68 class SuicideOnChannelErrorFilter : public IPC::ChannelProxy::MessageFilter { | 
| 66   void OnChannelError() { | 69   void OnChannelError() { | 
| 67     // On POSIX, at least, one can install an unload handler which loops | 70     // On POSIX, at least, one can install an unload handler which loops | 
| 68     // forever and leave behind a renderer process which eats 100% CPU forever. | 71     // forever and leave behind a renderer process which eats 100% CPU forever. | 
| 69     // | 72     // | 
| 70     // This is because the terminate signals (ViewMsg_ShouldClose and the error | 73     // This is because the terminate signals (ViewMsg_ShouldClose and the error | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 98 void RenderThread::Init() { | 101 void RenderThread::Init() { | 
| 99   lazy_tls.Pointer()->Set(this); | 102   lazy_tls.Pointer()->Set(this); | 
| 100 #if defined(OS_WIN) | 103 #if defined(OS_WIN) | 
| 101   // If you are running plugins in this thread you need COM active but in | 104   // If you are running plugins in this thread you need COM active but in | 
| 102   // the normal case you don't. | 105   // the normal case you don't. | 
| 103   if (RenderProcess::InProcessPlugins()) | 106   if (RenderProcess::InProcessPlugins()) | 
| 104     CoInitialize(0); | 107     CoInitialize(0); | 
| 105 #endif | 108 #endif | 
| 106 | 109 | 
| 107   plugin_refresh_allowed_ = true; | 110   plugin_refresh_allowed_ = true; | 
| 108   cache_stats_factory_.reset( | 111   cache_stats_task_pending_ = false; | 
| 109       new ScopedRunnableMethodFactory<RenderThread>(this)); | 112   widget_count_ = 0; | 
|  | 113   hidden_widget_count_ = 0; | 
|  | 114   idle_notification_delay_in_s_ = kInitialIdleHandlerDelayS; | 
|  | 115   task_factory_.reset(new ScopedRunnableMethodFactory<RenderThread>(this)); | 
| 110 | 116 | 
| 111   visited_link_slave_.reset(new VisitedLinkSlave()); | 117   visited_link_slave_.reset(new VisitedLinkSlave()); | 
| 112   user_script_slave_.reset(new UserScriptSlave()); | 118   user_script_slave_.reset(new UserScriptSlave()); | 
| 113   dns_master_.reset(new RenderDnsMaster()); | 119   dns_master_.reset(new RenderDnsMaster()); | 
| 114   histogram_snapshots_.reset(new RendererHistogramSnapshots()); | 120   histogram_snapshots_.reset(new RendererHistogramSnapshots()); | 
| 115   appcache_dispatcher_.reset(new AppCacheDispatcher(this)); | 121   appcache_dispatcher_.reset(new AppCacheDispatcher(this)); | 
| 116   devtools_agent_filter_ = new DevToolsAgentFilter(); | 122   devtools_agent_filter_ = new DevToolsAgentFilter(); | 
| 117   AddFilter(devtools_agent_filter_.get()); | 123   AddFilter(devtools_agent_filter_.get()); | 
| 118   db_message_filter_ = new DBMessageFilter(); | 124   db_message_filter_ = new DBMessageFilter(); | 
| 119   AddFilter(db_message_filter_.get()); | 125   AddFilter(db_message_filter_.get()); | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 149 } | 155 } | 
| 150 | 156 | 
| 151 void RenderThread::AddFilter(IPC::ChannelProxy::MessageFilter* filter) { | 157 void RenderThread::AddFilter(IPC::ChannelProxy::MessageFilter* filter) { | 
| 152   channel()->AddFilter(filter); | 158   channel()->AddFilter(filter); | 
| 153 } | 159 } | 
| 154 | 160 | 
| 155 void RenderThread::RemoveFilter(IPC::ChannelProxy::MessageFilter* filter) { | 161 void RenderThread::RemoveFilter(IPC::ChannelProxy::MessageFilter* filter) { | 
| 156   channel()->RemoveFilter(filter); | 162   channel()->RemoveFilter(filter); | 
| 157 } | 163 } | 
| 158 | 164 | 
|  | 165 void RenderThread::WidgetHidden() { | 
|  | 166   DCHECK(hidden_widget_count_ < widget_count_); | 
|  | 167   hidden_widget_count_++ ; | 
|  | 168   if (widget_count_ && hidden_widget_count_ == widget_count_) { | 
|  | 169     // Reset the delay. | 
|  | 170     idle_notification_delay_in_s_ = kInitialIdleHandlerDelayS; | 
|  | 171 | 
|  | 172     // Schedule the IdleHandler to wakeup in a bit. | 
|  | 173     MessageLoop::current()->PostDelayedTask(FROM_HERE, | 
|  | 174         task_factory_->NewRunnableMethod(&RenderThread::IdleHandler), | 
|  | 175         static_cast<int64>(floor(idle_notification_delay_in_s_)) * 1000); | 
|  | 176   } | 
|  | 177 } | 
|  | 178 | 
|  | 179 void RenderThread::WidgetRestored() { | 
|  | 180   DCHECK(hidden_widget_count_ > 0); | 
|  | 181   hidden_widget_count_--; | 
|  | 182 | 
|  | 183   // Note: we may have a timer pending to call the IdleHandler (see the | 
|  | 184   // WidgetHidden() code).  But we don't bother to cancel it as it is | 
|  | 185   // benign and won't do anything if the tab is un-hidden when it is | 
|  | 186   // called. | 
|  | 187 } | 
|  | 188 | 
| 159 void RenderThread::Resolve(const char* name, size_t length) { | 189 void RenderThread::Resolve(const char* name, size_t length) { | 
| 160   return dns_master_->Resolve(name, length); | 190   return dns_master_->Resolve(name, length); | 
| 161 } | 191 } | 
| 162 | 192 | 
| 163 void RenderThread::SendHistograms(int sequence_number) { | 193 void RenderThread::SendHistograms(int sequence_number) { | 
| 164   return histogram_snapshots_->SendHistograms(sequence_number); | 194   return histogram_snapshots_->SendHistograms(sequence_number); | 
| 165 } | 195 } | 
| 166 | 196 | 
| 167 void RenderThread::OnUpdateVisitedLinks(base::SharedMemoryHandle table) { | 197 void RenderThread::OnUpdateVisitedLinks(base::SharedMemoryHandle table) { | 
| 168   DCHECK(base::SharedMemory::IsHandleValid(table)) << "Bad table handle"; | 198   DCHECK(base::SharedMemory::IsHandleValid(table)) << "Bad table handle"; | 
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 309 | 339 | 
| 310 void RenderThread::OnGetRendererHistograms(int sequence_number) { | 340 void RenderThread::OnGetRendererHistograms(int sequence_number) { | 
| 311   SendHistograms(sequence_number); | 341   SendHistograms(sequence_number); | 
| 312 } | 342 } | 
| 313 | 343 | 
| 314 void RenderThread::InformHostOfCacheStats() { | 344 void RenderThread::InformHostOfCacheStats() { | 
| 315   EnsureWebKitInitialized(); | 345   EnsureWebKitInitialized(); | 
| 316   WebCache::UsageStats stats; | 346   WebCache::UsageStats stats; | 
| 317   WebCache::getUsageStats(&stats); | 347   WebCache::getUsageStats(&stats); | 
| 318   Send(new ViewHostMsg_UpdatedCacheStats(stats)); | 348   Send(new ViewHostMsg_UpdatedCacheStats(stats)); | 
|  | 349   cache_stats_task_pending_ = false; | 
| 319 } | 350 } | 
| 320 | 351 | 
| 321 void RenderThread::InformHostOfCacheStatsLater() { | 352 void RenderThread::InformHostOfCacheStatsLater() { | 
| 322   // Rate limit informing the host of our cache stats. | 353   // Rate limit informing the host of our cache stats. | 
| 323   if (!cache_stats_factory_->empty()) | 354   if (cache_stats_task_pending_) | 
| 324     return; | 355     return; | 
| 325 | 356 | 
|  | 357   cache_stats_task_pending_ = true; | 
| 326   MessageLoop::current()->PostDelayedTask(FROM_HERE, | 358   MessageLoop::current()->PostDelayedTask(FROM_HERE, | 
| 327       cache_stats_factory_->NewRunnableMethod( | 359       task_factory_->NewRunnableMethod( | 
| 328           &RenderThread::InformHostOfCacheStats), | 360           &RenderThread::InformHostOfCacheStats), | 
| 329       kCacheStatsDelayMS); | 361       kCacheStatsDelayMS); | 
| 330 } | 362 } | 
| 331 | 363 | 
| 332 void RenderThread::CloseIdleConnections() { | 364 void RenderThread::CloseIdleConnections() { | 
| 333   Send(new ViewHostMsg_CloseIdleConnections()); | 365   Send(new ViewHostMsg_CloseIdleConnections()); | 
| 334 } | 366 } | 
| 335 | 367 | 
| 336 void RenderThread::SetCacheMode(bool enabled) { | 368 void RenderThread::SetCacheMode(bool enabled) { | 
| 337   Send(new ViewHostMsg_SetCacheMode(enabled)); | 369   Send(new ViewHostMsg_SetCacheMode(enabled)); | 
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 417     WebKit::enableMediaPlayer(); | 449     WebKit::enableMediaPlayer(); | 
| 418 | 450 | 
| 419   // Note: We are forcing --enable-databases to on with --enable-extensions so | 451   // Note: We are forcing --enable-databases to on with --enable-extensions so | 
| 420   // that extension developers can test databases. | 452   // that extension developers can test databases. | 
| 421   if (command_line.HasSwitch(switches::kEnableDatabases) || | 453   if (command_line.HasSwitch(switches::kEnableDatabases) || | 
| 422       command_line.HasSwitch(switches::kEnableExtensions)) { | 454       command_line.HasSwitch(switches::kEnableExtensions)) { | 
| 423     WebKit::enableDatabases(); | 455     WebKit::enableDatabases(); | 
| 424   } | 456   } | 
| 425 } | 457 } | 
| 426 | 458 | 
|  | 459 void RenderThread::IdleHandler() { | 
|  | 460   // It is possible that the timer was set while the widgets were idle, | 
|  | 461   // but that they are no longer idle.  If so, just return. | 
|  | 462   if (!widget_count_ || hidden_widget_count_ < widget_count_) | 
|  | 463     return; | 
|  | 464 | 
|  | 465   if (v8::V8::IsDead()) | 
|  | 466     return; | 
|  | 467 | 
|  | 468   LOG(INFO) << "RenderThread calling v8 IdleNotification for " << this; | 
|  | 469 | 
|  | 470   // When V8::IdleNotification returns true, it means that it has cleaned up | 
|  | 471   // as much as it can.  There is no point in continuing to call it. | 
|  | 472   if (!v8::V8::IdleNotification(false)) { | 
|  | 473     // Dampen the delay using the algorithm: | 
|  | 474     //    delay = delay + 1 / (delay + 2) | 
|  | 475     // Using floor(delay) has a dampening effect such as: | 
|  | 476     //    1s, 1, 1, 2, 2, 2, 2, 3, 3, ... | 
|  | 477     idle_notification_delay_in_s_ += | 
|  | 478         1.0 / (idle_notification_delay_in_s_ + 2.0); | 
|  | 479 | 
|  | 480     // Schedule the next timer. | 
|  | 481     MessageLoop::current()->PostDelayedTask(FROM_HERE, | 
|  | 482         task_factory_->NewRunnableMethod(&RenderThread::IdleHandler), | 
|  | 483         static_cast<int64>(floor(idle_notification_delay_in_s_)) * 1000); | 
|  | 484   } | 
|  | 485 } | 
|  | 486 | 
| 427 void RenderThread::OnExtensionMessageInvoke(const std::string& function_name, | 487 void RenderThread::OnExtensionMessageInvoke(const std::string& function_name, | 
| 428                                             const ListValue& args) { | 488                                             const ListValue& args) { | 
| 429   RendererExtensionBindings::Invoke(function_name, args, NULL); | 489   RendererExtensionBindings::Invoke(function_name, args, NULL); | 
| 430 } | 490 } | 
| 431 | 491 | 
| 432 void RenderThread::OnPurgePluginListCache() { | 492 void RenderThread::OnPurgePluginListCache() { | 
| 433   // The call below will cause a GetPlugins call with refresh=true, but at this | 493   // The call below will cause a GetPlugins call with refresh=true, but at this | 
| 434   // point we already know that the browser has refreshed its list, so disable | 494   // point we already know that the browser has refreshed its list, so disable | 
| 435   // refresh temporarily to prevent each renderer process causing the list to be | 495   // refresh temporarily to prevent each renderer process causing the list to be | 
| 436   // regenerated. | 496   // regenerated. | 
| 437   plugin_refresh_allowed_ = false; | 497   plugin_refresh_allowed_ = false; | 
| 438   WebKit::resetPluginCache(); | 498   WebKit::resetPluginCache(); | 
| 439   plugin_refresh_allowed_ = true; | 499   plugin_refresh_allowed_ = true; | 
| 440 } | 500 } | 
| OLD | NEW | 
|---|