summaryrefslogtreecommitdiffstats
path: root/chrome/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/renderer')
-rw-r--r--chrome/renderer/mock_render_process.h3
-rw-r--r--chrome/renderer/render_process.cc51
-rw-r--r--chrome/renderer/render_process.h8
-rw-r--r--chrome/renderer/render_process_unittest.cc2
-rw-r--r--chrome/renderer/render_thread.cc99
-rw-r--r--chrome/renderer/render_thread.h21
-rw-r--r--chrome/renderer/render_thread_unittest.cc11
-rw-r--r--chrome/renderer/render_view.cc8
-rw-r--r--chrome/renderer/render_view.h6
-rw-r--r--chrome/renderer/renderer_main.cc9
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.cc5
11 files changed, 151 insertions, 72 deletions
diff --git a/chrome/renderer/mock_render_process.h b/chrome/renderer/mock_render_process.h
index 49bc02c..629967f 100644
--- a/chrome/renderer/mock_render_process.h
+++ b/chrome/renderer/mock_render_process.h
@@ -14,7 +14,8 @@ class ChildThread;
// a render widget instance.
class MockProcess : public ChildProcess {
public:
- explicit MockProcess() : ChildProcess() {}
+ explicit MockProcess() : ChildProcess(NULL) {}
+ explicit MockProcess(ChildThread* thread) : ChildProcess(thread) {}
};
#endif // CHROME_RENDERER_MOCK_RENDER_PROCESS_H_
diff --git a/chrome/renderer/render_process.cc b/chrome/renderer/render_process.cc
index 2718d37..3fe22c5 100644
--- a/chrome/renderer/render_process.cc
+++ b/chrome/renderer/render_process.cc
@@ -47,10 +47,43 @@ static size_t GetMaxSharedMemorySize() {
//-----------------------------------------------------------------------------
RenderProcess::RenderProcess()
- : ALLOW_THIS_IN_INITIALIZER_LIST(shared_mem_cache_cleaner_(
+ : ChildProcess(new RenderThread()),
+ 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;
@@ -98,18 +131,6 @@ RenderProcess::RenderProcess()
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)
@@ -136,7 +157,7 @@ TransportDIB* RenderProcess::CreateTransportDIB(size_t size) {
// get one.
TransportDIB::Handle handle;
IPC::Message* msg = new ViewHostMsg_AllocTransportDIB(size, &handle);
- if (!main_thread()->Send(msg))
+ if (!child_thread()->Send(msg))
return NULL;
if (handle.fd < 0)
return NULL;
@@ -152,7 +173,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());
- main_thread()->Send(msg);
+ child_thread()->Send(msg);
#endif
delete dib;
diff --git a/chrome/renderer/render_process.h b/chrome/renderer/render_process.h
index d445fbe..727aae5 100644
--- a/chrome/renderer/render_process.h
+++ b/chrome/renderer/render_process.h
@@ -21,7 +21,11 @@ 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
@@ -48,10 +52,14 @@ 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 5692d81..feac0aa 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());
+ render_process_.reset(new RenderProcess(kThreadName));
}
virtual void TearDown() {
diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc
index 80811b2..e35377a 100644
--- a/chrome/renderer/render_thread.cc
+++ b/chrome/renderer/render_thread.cc
@@ -17,6 +17,7 @@
#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)
@@ -54,10 +55,54 @@
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());
}
@@ -83,18 +128,6 @@ 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() {
- Init();
-}
-
-RenderThread::RenderThread(const std::string& channel_name)
- : ChildThread(channel_name) {
- Init();
-}
void RenderThread::Init() {
lazy_tls.Pointer()->Set(this);
@@ -105,7 +138,8 @@ void RenderThread::Init() {
CoInitialize(0);
#endif
- plugin_refresh_allowed_ = true;
+ ChildThread::Init();
+ notification_service_.reset(new NotificationService);
cache_stats_factory_.reset(
new ScopedRunnableMethodFactory<RenderThread>(this));
@@ -124,13 +158,24 @@ void RenderThread::Init() {
#endif
}
-RenderThread::~RenderThread() {
+void RenderThread::CleanUp() {
// Shutdown in reverse of the initialization order.
RemoveFilter(devtools_agent_filter_.get());
+ devtools_agent_filter_ = NULL;
WebAppCacheContext::SetFactory(NULL);
- if (webkit_client_.get())
+ app_cache_dispatcher_.reset();
+ histogram_snapshots_.reset();
+ dns_master_.reset();
+ user_script_slave_.reset();
+ visited_link_slave_.reset();
+
+ if (webkit_client_.get()) {
WebKit::shutdown();
+ webkit_client_.reset();
+ }
+ notification_service_.reset();
+ ChildThread::CleanUp();
lazy_tls.Pointer()->Set(NULL);
// TODO(port)
@@ -143,26 +188,6 @@ RenderThread::~RenderThread() {
#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);
@@ -249,6 +274,8 @@ 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 d2a1fcd..5ced914 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,7 +114,9 @@ class RenderThread : public RenderThreadBase,
private:
virtual void OnControlMessageReceived(const IPC::Message& msg);
- void Init();
+ // Called by the thread base class.
+ virtual void Init();
+ virtual void CleanUp();
void OnUpdateVisitedLinks(base::SharedMemoryHandle table);
void OnAddVisitedLinks(const VisitedLinkSlave::Fingerprints& fingerprints);
@@ -152,15 +154,24 @@ 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<AppCacheDispatcher> app_cache_dispatcher_;
- scoped_refptr<DevToolsAgentFilter> devtools_agent_filter_;
+
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_;
+
#if defined(OS_POSIX)
scoped_refptr<IPC::ChannelProxy::MessageFilter>
suicide_on_channel_error_filter_;
diff --git a/chrome/renderer/render_thread_unittest.cc b/chrome/renderer/render_thread_unittest.cc
index e22cabb..76491fe 100644
--- a/chrome/renderer/render_thread_unittest.cc
+++ b/chrome/renderer/render_thread_unittest.cc
@@ -18,8 +18,7 @@ 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());
- mock_process_->set_main_thread(new RenderThread(kThreadName));
+ mock_process_.reset(new MockProcess(new RenderThread(kThreadName)));
}
virtual void TearDown() {
@@ -35,13 +34,15 @@ class RenderThreadTest : public testing::Test {
}
protected:
- MessageLoop message_loop_;
+ MessageLoopForIO message_loop_;
scoped_ptr<MockProcess> mock_process_;
IPC::Channel *channel_;
};
TEST_F(RenderThreadTest, TestGlobal) {
- ASSERT_TRUE(RenderThread::current());
+ // Can't reach the RenderThread object on other threads, since it's not
+ // thread-safe!
+ ASSERT_FALSE(RenderThread::current());
}
TEST_F(RenderThreadTest, TestVisitedMsg) {
@@ -54,7 +55,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_->main_thread()->Send(msg);
+ mock_process_->child_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 fd8f61a..21c40e2 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -2814,6 +2814,14 @@ 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 d83bab9..7624620 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -360,6 +360,12 @@ 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 55234ec..f5d7811 100644
--- a/chrome/renderer/renderer_main.cc
+++ b/chrome/renderer/renderer_main.cc
@@ -22,7 +22,6 @@
#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"
@@ -97,11 +96,8 @@ int RendererMain(const MainFunctionParams& parameters) {
StatsScope<StatsCounterTimer>
startup_timer(chrome::Counters::renderer_main());
- // 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);
-
+ // The main thread of the renderer services IO.
+ MessageLoopForIO main_message_loop;
std::wstring app_name = chrome::kBrowserAppName;
PlatformThread::SetName(WideToASCII(app_name + L"_RendererMain").c_str());
@@ -132,7 +128,6 @@ 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 233749b9..34a728d 100644
--- a/chrome/renderer/webplugin_delegate_proxy.cc
+++ b/chrome/renderer/webplugin_delegate_proxy.cc
@@ -237,9 +237,10 @@ 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, ChildProcess::current()->io_message_loop());
+ PluginChannelHost::GetPluginChannelHost(channel_handle.name,
+ ipc_message_loop);
if (!channel_host.get())
return false;