diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-20 22:20:20 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-20 22:20:20 +0000 |
commit | f717ea6403554cc60a5dd9312fe585cdf64a8815 (patch) | |
tree | 523186875fe4c36bcc1c6905b3da36943a174318 /chrome/renderer | |
parent | e74b81de4f2785b5cff5cb0cc85e76b3d434248e (diff) | |
download | chromium_src-f717ea6403554cc60a5dd9312fe585cdf64a8815.zip chromium_src-f717ea6403554cc60a5dd9312fe585cdf64a8815.tar.gz chromium_src-f717ea6403554cc60a5dd9312fe585cdf64a8815.tar.bz2 |
Switch the first thread in a child process to be the main thread, and make the IO thread be the second thread. The change is needed for plugins on mac.
Review URL: http://codereview.chromium.org/149558
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21117 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/mock_render_process.h | 3 | ||||
-rw-r--r-- | chrome/renderer/render_process.cc | 51 | ||||
-rw-r--r-- | chrome/renderer/render_process.h | 8 | ||||
-rw-r--r-- | chrome/renderer/render_process_unittest.cc | 2 | ||||
-rw-r--r-- | chrome/renderer/render_thread.cc | 100 | ||||
-rw-r--r-- | chrome/renderer/render_thread.h | 21 | ||||
-rw-r--r-- | chrome/renderer/render_thread_unittest.cc | 11 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 8 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 6 | ||||
-rw-r--r-- | chrome/renderer/renderer_main.cc | 9 | ||||
-rw-r--r-- | chrome/renderer/webplugin_delegate_proxy.cc | 5 |
11 files changed, 73 insertions, 151 deletions
diff --git a/chrome/renderer/mock_render_process.h b/chrome/renderer/mock_render_process.h index 629967f..49bc02c 100644 --- a/chrome/renderer/mock_render_process.h +++ b/chrome/renderer/mock_render_process.h @@ -14,8 +14,7 @@ class ChildThread; // a render widget instance. class MockProcess : public ChildProcess { public: - explicit MockProcess() : ChildProcess(NULL) {} - explicit MockProcess(ChildThread* thread) : ChildProcess(thread) {} + explicit MockProcess() : ChildProcess() {} }; #endif // CHROME_RENDERER_MOCK_RENDER_PROCESS_H_ diff --git a/chrome/renderer/render_process.cc b/chrome/renderer/render_process.cc index fd06081..925a67b 100644 --- a/chrome/renderer/render_process.cc +++ b/chrome/renderer/render_process.cc @@ -47,43 +47,10 @@ static size_t GetMaxSharedMemorySize() { //----------------------------------------------------------------------------- RenderProcess::RenderProcess() - : ChildProcess(new RenderThread()), - ALLOW_THIS_IN_INITIALIZER_LIST(shared_mem_cache_cleaner_( + : ALLOW_THIS_IN_INITIALIZER_LIST(shared_mem_cache_cleaner_( base::TimeDelta::FromSeconds(5), this, &RenderProcess::ClearTransportDIBCache)), sequence_number_(0) { - Init(); -} - -RenderProcess::RenderProcess(const std::string& channel_name) - : ChildProcess(new RenderThread(channel_name)), - ALLOW_THIS_IN_INITIALIZER_LIST(shared_mem_cache_cleaner_( - base::TimeDelta::FromSeconds(5), - this, &RenderProcess::ClearTransportDIBCache)), - sequence_number_(0) { - Init(); -} - -RenderProcess::~RenderProcess() { - // TODO(port) - // Try and limit what we pull in for our non-Win unit test bundle -#ifndef NDEBUG - // log important leaked objects - webkit_glue::CheckForLeaks(); -#endif - - GetShutDownEvent()->Signal(); - - // We need to stop the RenderThread as the clearer_factory_ - // member could be in use while the object itself is destroyed, - // as a result of the containing RenderProcess object being destroyed. - // This race condition causes a crash when the renderer process is shutting - // down. - child_thread()->Stop(); - ClearTransportDIBCache(); -} - -void RenderProcess::Init() { in_process_plugins_ = InProcessPlugins(); for (size_t i = 0; i < arraysize(shared_mem_cache_); ++i) shared_mem_cache_[i] = NULL; @@ -131,6 +98,18 @@ void RenderProcess::Init() { media::InitializeMediaLibrary(module_path); } +RenderProcess::~RenderProcess() { + // TODO(port) + // Try and limit what we pull in for our non-Win unit test bundle +#ifndef NDEBUG + // log important leaked objects + webkit_glue::CheckForLeaks(); +#endif + + GetShutDownEvent()->Signal(); + ClearTransportDIBCache(); +} + bool RenderProcess::InProcessPlugins() { const CommandLine& command_line = *CommandLine::ForCurrentProcess(); #if defined(OS_LINUX) @@ -157,7 +136,7 @@ TransportDIB* RenderProcess::CreateTransportDIB(size_t size) { // get one. TransportDIB::Handle handle; IPC::Message* msg = new ViewHostMsg_AllocTransportDIB(size, &handle); - if (!child_thread()->Send(msg)) + if (!main_thread()->Send(msg)) return NULL; if (handle.fd < 0) return NULL; @@ -173,7 +152,7 @@ void RenderProcess::FreeTransportDIB(TransportDIB* dib) { // On Mac we need to tell the browser that it can drop a reference to the // shared memory. IPC::Message* msg = new ViewHostMsg_FreeTransportDIB(dib->id()); - child_thread()->Send(msg); + main_thread()->Send(msg); #endif delete dib; diff --git a/chrome/renderer/render_process.h b/chrome/renderer/render_process.h index 727aae5..d445fbe 100644 --- a/chrome/renderer/render_process.h +++ b/chrome/renderer/render_process.h @@ -21,11 +21,7 @@ class TransportDIB; // each renderer. class RenderProcess : public ChildProcess { public: - // This constructor grabs the channel name from the command line arguments. RenderProcess(); - // This constructor uses the given channel name. - RenderProcess(const std::string& channel_name); - ~RenderProcess(); // Get a canvas suitable for drawing and transporting to the browser @@ -52,14 +48,10 @@ class RenderProcess : public ChildProcess { return static_cast<RenderProcess*>(ChildProcess::current()); } - protected: - friend class RenderThread; // Just like in_process_plugins(), but called before RenderProcess is created. static bool InProcessPlugins(); private: - void Init(); - // Look in the shared memory cache for a suitable object to reuse. // result: (output) the memory found // size: the resulting memory will be >= this size, in bytes diff --git a/chrome/renderer/render_process_unittest.cc b/chrome/renderer/render_process_unittest.cc index feac0aa..5692d81 100644 --- a/chrome/renderer/render_process_unittest.cc +++ b/chrome/renderer/render_process_unittest.cc @@ -17,7 +17,7 @@ class RenderProcessTest : public testing::Test { virtual void SetUp() { // Need a MODE_SERVER to make MODE_CLIENTs (like a RenderThread) happy. channel_ = new IPC::Channel(kThreadName, IPC::Channel::MODE_SERVER, NULL); - render_process_.reset(new RenderProcess(kThreadName)); + render_process_.reset(new RenderProcess()); } virtual void TearDown() { diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc index e35377a..7a5a8be 100644 --- a/chrome/renderer/render_thread.cc +++ b/chrome/renderer/render_thread.cc @@ -17,7 +17,6 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/render_messages.h" #include "chrome/common/renderer_preferences.h" -#include "chrome/common/notification_service.h" #include "chrome/common/url_constants.h" #include "chrome/plugin/npobject_util.h" // TODO(port) @@ -55,54 +54,10 @@ using WebKit::WebCache; using WebKit::WebString; +namespace { static const unsigned int kCacheStatsDelayMS = 2000 /* milliseconds */; - static base::LazyInstance<base::ThreadLocalPointer<RenderThread> > lazy_tls( base::LINKER_INITIALIZED); - -//----------------------------------------------------------------------------- -// Methods below are only called on the owner's thread: - -// When we run plugins in process, we actually run them on the render thread, -// which means that we need to make the render thread pump UI events. -RenderThread::RenderThread() - : ChildThread( - base::Thread::Options(RenderProcess::InProcessPlugins() ? - MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT, kV8StackSize)), - plugin_refresh_allowed_(true) { -} - -RenderThread::RenderThread(const std::string& channel_name) - : ChildThread( - base::Thread::Options(RenderProcess::InProcessPlugins() ? - MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT, kV8StackSize)), - plugin_refresh_allowed_(true) { - SetChannelName(channel_name); -} - -RenderThread::~RenderThread() { -} - -RenderThread* RenderThread::current() { - return lazy_tls.Pointer()->Get(); -} - -void RenderThread::AddFilter(IPC::ChannelProxy::MessageFilter* filter) { - channel()->AddFilter(filter); -} - -void RenderThread::RemoveFilter(IPC::ChannelProxy::MessageFilter* filter) { - channel()->RemoveFilter(filter); -} - -void RenderThread::Resolve(const char* name, size_t length) { - return dns_master_->Resolve(name, length); -} - -void RenderThread::SendHistograms(int sequence_number) { - return histogram_snapshots_->SendHistograms(sequence_number); -} - static WebAppCacheContext* CreateAppCacheContextForRenderer() { return new AppCacheContextImpl(RenderThread::current()); } @@ -128,6 +83,20 @@ class SuicideOnChannelErrorFilter : public IPC::ChannelProxy::MessageFilter { } }; #endif +} // namespace + +// When we run plugins in process, we actually run them on the render thread, +// which means that we need to make the render thread pump UI events. +RenderThread::RenderThread() + : plugin_refresh_allowed_(true) { + Init(); +} + +RenderThread::RenderThread(const std::string& channel_name) + : plugin_refresh_allowed_(true) { + SetChannelName(channel_name); + Init(); +} void RenderThread::Init() { lazy_tls.Pointer()->Set(this); @@ -138,8 +107,6 @@ void RenderThread::Init() { CoInitialize(0); #endif - ChildThread::Init(); - notification_service_.reset(new NotificationService); cache_stats_factory_.reset( new ScopedRunnableMethodFactory<RenderThread>(this)); @@ -158,24 +125,13 @@ void RenderThread::Init() { #endif } -void RenderThread::CleanUp() { +RenderThread::~RenderThread() { // Shutdown in reverse of the initialization order. RemoveFilter(devtools_agent_filter_.get()); - devtools_agent_filter_ = NULL; WebAppCacheContext::SetFactory(NULL); - app_cache_dispatcher_.reset(); - histogram_snapshots_.reset(); - dns_master_.reset(); - user_script_slave_.reset(); - visited_link_slave_.reset(); - - if (webkit_client_.get()) { + if (webkit_client_.get()) WebKit::shutdown(); - webkit_client_.reset(); - } - notification_service_.reset(); - ChildThread::CleanUp(); lazy_tls.Pointer()->Set(NULL); // TODO(port) @@ -188,6 +144,26 @@ void RenderThread::CleanUp() { #endif } +RenderThread* RenderThread::current() { + return lazy_tls.Pointer()->Get(); +} + +void RenderThread::AddFilter(IPC::ChannelProxy::MessageFilter* filter) { + channel()->AddFilter(filter); +} + +void RenderThread::RemoveFilter(IPC::ChannelProxy::MessageFilter* filter) { + channel()->RemoveFilter(filter); +} + +void RenderThread::Resolve(const char* name, size_t length) { + return dns_master_->Resolve(name, length); +} + +void RenderThread::SendHistograms(int sequence_number) { + return histogram_snapshots_->SendHistograms(sequence_number); +} + void RenderThread::OnUpdateVisitedLinks(base::SharedMemoryHandle table) { DCHECK(base::SharedMemory::IsHandleValid(table)) << "Bad table handle"; visited_link_slave_->Init(table); @@ -274,8 +250,6 @@ void RenderThread::OnCreateNewView(gfx::NativeViewId parent_hwnd, true, false); #endif - // TODO(darin): once we have a RenderThread per RenderView, this will need to - // change to assert that we are not creating more than one view. RenderView::Create( this, parent_hwnd, waitable_event, MSG_ROUTING_NONE, renderer_prefs, webkit_prefs, new SharedRenderViewCounter(0), view_id); diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h index 5ced914..d2a1fcd 100644 --- a/chrome/renderer/render_thread.h +++ b/chrome/renderer/render_thread.h @@ -20,7 +20,7 @@ class AppCacheDispatcher; class DevToolsAgentFilter; class FilePath; class ListValue; -class NotificationService; + class RenderDnsMaster; class RendererHistogram; class RendererWebKitClientImpl; @@ -114,9 +114,7 @@ class RenderThread : public RenderThreadBase, private: virtual void OnControlMessageReceived(const IPC::Message& msg); - // Called by the thread base class. - virtual void Init(); - virtual void CleanUp(); + void Init(); void OnUpdateVisitedLinks(base::SharedMemoryHandle table); void OnAddVisitedLinks(const VisitedLinkSlave::Fingerprints& fingerprints); @@ -154,23 +152,14 @@ class RenderThread : public RenderThreadBase, void EnsureWebKitInitialized(); // These objects live solely on the render thread. + scoped_ptr<ScopedRunnableMethodFactory<RenderThread> > cache_stats_factory_; scoped_ptr<VisitedLinkSlave> visited_link_slave_; - scoped_ptr<UserScriptSlave> user_script_slave_; - scoped_ptr<RenderDnsMaster> dns_master_; - - scoped_ptr<RendererHistogramSnapshots> histogram_snapshots_; - - scoped_ptr<ScopedRunnableMethodFactory<RenderThread> > cache_stats_factory_; - - scoped_ptr<NotificationService> notification_service_; - - scoped_ptr<RendererWebKitClientImpl> webkit_client_; - scoped_ptr<AppCacheDispatcher> app_cache_dispatcher_; - scoped_refptr<DevToolsAgentFilter> devtools_agent_filter_; + scoped_ptr<RendererHistogramSnapshots> histogram_snapshots_; + scoped_ptr<RendererWebKitClientImpl> webkit_client_; #if defined(OS_POSIX) scoped_refptr<IPC::ChannelProxy::MessageFilter> diff --git a/chrome/renderer/render_thread_unittest.cc b/chrome/renderer/render_thread_unittest.cc index bb2e297..aa370a5 100644 --- a/chrome/renderer/render_thread_unittest.cc +++ b/chrome/renderer/render_thread_unittest.cc @@ -18,7 +18,8 @@ class RenderThreadTest : public testing::Test { virtual void SetUp() { // Need a MODE_SERVER to make MODE_CLIENTs (like a RenderThread) happy. channel_ = new IPC::Channel(kThreadName, IPC::Channel::MODE_SERVER, NULL); - mock_process_.reset(new MockProcess(new RenderThread(kThreadName))); + mock_process_.reset(new MockProcess()); + mock_process_->set_main_thread(new RenderThread(kThreadName)); } virtual void TearDown() { @@ -34,15 +35,13 @@ class RenderThreadTest : public testing::Test { } protected: - MessageLoopForIO message_loop_; + MessageLoop message_loop_; scoped_ptr<MockProcess> mock_process_; IPC::Channel *channel_; }; TEST_F(RenderThreadTest, TestGlobal) { - // Can't reach the RenderThread object on other threads, since it's not - // thread-safe! - ASSERT_FALSE(RenderThread::current()); + ASSERT_TRUE(RenderThread::current()); } TEST_F(RenderThreadTest, TestVisitedMsg) { @@ -55,7 +54,7 @@ TEST_F(RenderThreadTest, TestVisitedMsg) { ASSERT_TRUE(msg); // Message goes nowhere, but this confirms Init() has happened. // Unusually (?), RenderThread() Start()s itself in it's constructor. - mock_process_->child_thread()->Send(msg); + mock_process_->main_thread()->Send(msg); // No need to delete msg; per Message::Send() documentation, "The // implementor takes ownership of the given Message regardless of diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 0052e1e..9aa0592 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -2810,14 +2810,6 @@ std::string RenderView::GetAltHTMLForTemplate( template_html, &error_strings, "t"); } -MessageLoop* RenderView::GetMessageLoopForIO() { - // Assume that we have only one RenderThread in the process and the owner loop - // of RenderThread is an IO message loop. - if (RenderThread::current()) - return RenderThread::current()->owner_loop(); - return NULL; -} - void RenderView::OnMoveOrResizeStarted() { if (webview()) webview()->HideAutofillPopup(); diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index 9d8705a..c2aca8d 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -360,12 +360,6 @@ class RenderView : public RenderWidget, delay_seconds_for_form_state_sync_ = delay_in_seconds; } - // Returns a message loop of type IO that can be used to run I/O jobs. The - // renderer thread is of type TYPE_DEFAULT, so doesn't support everything - // needed by some consumers. The returned thread will be the main thread of - // the renderer, which processes all IPC, to any I/O should be non-blocking. - MessageLoop* GetMessageLoopForIO(); - AudioMessageFilter* audio_message_filter() { return audio_message_filter_; } void OnClearFocusedNode(); diff --git a/chrome/renderer/renderer_main.cc b/chrome/renderer/renderer_main.cc index 2dfe061..f0980bd 100644 --- a/chrome/renderer/renderer_main.cc +++ b/chrome/renderer/renderer_main.cc @@ -22,6 +22,7 @@ #include "chrome/common/main_function_params.h" #include "chrome/renderer/renderer_main_platform_delegate.h" #include "chrome/renderer/render_process.h" +#include "chrome/renderer/render_thread.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" @@ -84,8 +85,11 @@ int RendererMain(const MainFunctionParams& parameters) { StatsScope<StatsCounterTimer> startup_timer(chrome::Counters::renderer_main()); - // The main thread of the renderer services IO. - MessageLoopForIO main_message_loop; + // The main message loop of the renderer services doesn't have IO or UI tasks, + // unless in-process-plugins is used. + MessageLoop main_message_loop(RenderProcess::InProcessPlugins() ? + MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT); + std::wstring app_name = chrome::kBrowserAppName; PlatformThread::SetName(WideToASCII(app_name + L"_RendererMain").c_str()); @@ -116,6 +120,7 @@ int RendererMain(const MainFunctionParams& parameters) { { RenderProcess render_process; + render_process.set_main_thread(new RenderThread()); bool run_loop = true; if (!no_sandbox) { run_loop = platform.EnableSandbox(); diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc index 45a98bf..603db89 100644 --- a/chrome/renderer/webplugin_delegate_proxy.cc +++ b/chrome/renderer/webplugin_delegate_proxy.cc @@ -237,10 +237,9 @@ bool WebPluginDelegateProxy::Initialize(const GURL& url, char** argn, IPC::AddChannelSocket(channel_handle.name, channel_handle.socket.fd); #endif - MessageLoop* ipc_message_loop = RenderThread::current()->owner_loop(); scoped_refptr<PluginChannelHost> channel_host = - PluginChannelHost::GetPluginChannelHost(channel_handle.name, - ipc_message_loop); + PluginChannelHost::GetPluginChannelHost( + channel_handle.name, ChildProcess::current()->io_message_loop()); if (!channel_host.get()) return false; |