summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.cc18
-rw-r--r--chrome/common/child_process.cc29
-rw-r--r--chrome/common/child_process.h28
-rw-r--r--chrome/common/child_thread.cc80
-rw-r--r--chrome/common/child_thread.h45
-rw-r--r--chrome/common/histogram_synchronizer.cc1
-rw-r--r--chrome/plugin/plugin_main.cc7
-rw-r--r--chrome/plugin/plugin_thread.cc56
-rw-r--r--chrome/plugin/plugin_thread.h8
-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
-rw-r--r--chrome/utility/utility_main.cc7
-rw-r--r--chrome/utility/utility_thread.cc13
-rw-r--r--chrome/utility/utility_thread.h5
-rw-r--r--chrome/worker/worker_main.cc7
-rw-r--r--chrome/worker/worker_thread.cc29
-rw-r--r--chrome/worker/worker_thread.h5
-rw-r--r--ipc/ipc_channel_proxy.cc4
-rw-r--r--ipc/ipc_channel_proxy.h4
-rw-r--r--tools/valgrind/memcheck/suppressions.txt5
29 files changed, 219 insertions, 355 deletions
diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc
index 2370fd3..07f202a 100644
--- a/chrome/browser/renderer_host/browser_render_process_host.cc
+++ b/chrome/browser/renderer_host/browser_render_process_host.cc
@@ -54,6 +54,7 @@
#include "chrome/common/render_messages.h"
#include "chrome/common/result_codes.h"
#include "chrome/renderer/render_process.h"
+#include "chrome/renderer/render_thread.h"
#include "chrome/installer/util/google_update_settings.h"
#include "grit/generated_resources.h"
@@ -92,7 +93,8 @@ class RendererMainThread : public base::Thread {
CoInitialize(NULL);
#endif
- render_process_ = new RenderProcess(channel_id_);
+ render_process_ = new RenderProcess();
+ render_process_->set_main_thread(new RenderThread(channel_id_));
// It's a little lame to manually set this flag. But the single process
// RendererThread will receive the WM_QUIT. We don't need to assert on
// this thread, so just force the flag manually.
@@ -411,18 +413,14 @@ bool BrowserRenderProcessHost::Init() {
if (run_renderer_in_process()) {
// Crank up a thread and run the initialization there. With the way that
// messages flow between the browser and renderer, this thread is required
- // to prevent a deadlock in single-process mode. When using multiple
- // processes, the primordial thread in the renderer process has a message
- // loop which is used for sending messages asynchronously to the io thread
- // in the browser process. If we don't create this thread, then the
- // RenderThread is both responsible for rendering and also for
- // communicating IO. This can lead to deadlocks where the RenderThread is
- // waiting for the IO to complete, while the browsermain is trying to pass
- // an event to the RenderThread.
+ // to prevent a deadlock in single-process mode. Since the primordial
+ // thread in the renderer process runs the WebKit code and can sometimes
+ // blocking calls to the UI thread (i.e. this thread), they need to run on
+ // separate threads.
in_process_renderer_.reset(new RendererMainThread(channel_id));
base::Thread::Options options;
- options.message_loop_type = MessageLoop::TYPE_IO;
+ options.message_loop_type = MessageLoop::TYPE_UI;
in_process_renderer_->StartWithOptions(options);
} else {
base::ProcessHandle process = 0;
diff --git a/chrome/common/child_process.cc b/chrome/common/child_process.cc
index f32708c..34ea7a2 100644
--- a/chrome/common/child_process.cc
+++ b/chrome/common/child_process.cc
@@ -9,14 +9,14 @@
ChildProcess* ChildProcess::child_process_;
-ChildProcess::ChildProcess(ChildThread* child_thread)
- : child_thread_(child_thread),
- ref_count_(0),
- shutdown_event_(true, false) {
+ChildProcess::ChildProcess()
+ : ref_count_(0),
+ shutdown_event_(true, false),
+ io_thread_("Chrome_ChildIOThread") {
DCHECK(!child_process_);
child_process_ = this;
- if (child_thread_.get()) // null in unittests.
- child_thread_->Run();
+
+ io_thread_.StartWithOptions(base::Thread::Options(MessageLoop::TYPE_IO, 0));
}
ChildProcess::~ChildProcess() {
@@ -28,28 +28,29 @@ ChildProcess::~ChildProcess() {
// notice shutdown before the render process begins waiting for them to exit.
shutdown_event_.Signal();
- if (child_thread_.get())
- child_thread_->Stop();
+ // Kill the main thread object before nulling child_process_, since
+ // destruction code might depend on it.
+ main_thread_.reset();
child_process_ = NULL;
}
void ChildProcess::AddRefProcess() {
- DCHECK(!child_thread_.get() || // null in unittests.
- MessageLoop::current() == child_thread_->message_loop());
+ DCHECK(!main_thread_.get() || // null in unittests.
+ MessageLoop::current() == main_thread_->message_loop());
ref_count_++;
}
void ChildProcess::ReleaseProcess() {
- DCHECK(!child_thread_.get() || // null in unittests.
- MessageLoop::current() == child_thread_->message_loop());
+ DCHECK(!main_thread_.get() || // null in unittests.
+ MessageLoop::current() == main_thread_->message_loop());
DCHECK(ref_count_);
DCHECK(child_process_);
if (--ref_count_)
return;
- if (child_thread_.get()) // null in unittests.
- child_thread_->OnProcessFinalRelease();
+ if (main_thread_.get()) // null in unittests.
+ main_thread_->OnProcessFinalRelease();
}
base::WaitableEvent* ChildProcess::GetShutDownEvent() {
diff --git a/chrome/common/child_process.h b/chrome/common/child_process.h
index 1366a02..5e125bc 100644
--- a/chrome/common/child_process.h
+++ b/chrome/common/child_process.h
@@ -7,21 +7,23 @@
#include "base/basictypes.h"
#include "base/scoped_ptr.h"
+#include "base/thread.h"
#include "base/waitable_event.h"
-
-class ChildThread;
+#include "chrome/common/child_thread.h"
// Base class for child processes of the browser process (i.e. renderer and
// plugin host). This is a singleton object for each child process.
class ChildProcess {
public:
- // Child processes should have an object that derives from this class. The
- // constructor will return once ChildThread has started.
- ChildProcess(ChildThread* child_thread);
+ // Child processes should have an object that derives from this class.
+ ChildProcess();
virtual ~ChildProcess();
- // Getter for this process' main thread.
- ChildThread* child_thread() { return child_thread_.get(); }
+ // Getter for the child process' main thread.
+ ChildThread* main_thread() { return main_thread_.get(); }
+ void set_main_thread(ChildThread* thread) { main_thread_.reset(thread); }
+
+ MessageLoop* io_message_loop() { return io_thread_.message_loop(); }
// A global event object that is signalled when the main thread's message
// loop exits. This gives background threads a way to observe the main
@@ -45,15 +47,19 @@ class ChildProcess {
static ChildProcess* current() { return child_process_; }
private:
- // NOTE: make sure that child_thread_ is listed before shutdown_event_, since
- // it depends on it (indirectly through IPC::SyncChannel).
- scoped_ptr<ChildThread> child_thread_;
-
int ref_count_;
// An event that will be signalled when we shutdown.
base::WaitableEvent shutdown_event_;
+ // The thread that handles IO events.
+ base::Thread io_thread_;
+
+ // NOTE: make sure that main_thread_ is listed after shutdown_event_, since
+ // it depends on it (indirectly through IPC::SyncChannel). Same for
+ // io_thread_.
+ scoped_ptr<ChildThread> main_thread_;
+
// The singleton instance for this process.
static ChildProcess* child_process_;
diff --git a/chrome/common/child_thread.cc b/chrome/common/child_thread.cc
index 15a98b3..e2f7c5f 100644
--- a/chrome/common/child_thread.cc
+++ b/chrome/common/child_thread.cc
@@ -8,40 +8,67 @@
#include "base/command_line.h"
#include "chrome/common/child_process.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/common/notification_service.h"
#include "chrome/common/plugin_messages.h"
#include "ipc/ipc_logging.h"
#include "webkit/glue/webkit_glue.h"
-// V8 needs a 1MB stack size.
-const size_t ChildThread::kV8StackSize = 1024 * 1024;
-
-ChildThread::ChildThread(Thread::Options options)
- : Thread("Chrome_ChildThread"),
- owner_loop_(MessageLoop::current()),
- options_(options),
- check_with_browser_before_shutdown_(false) {
- DCHECK(owner_loop_);
+ChildThread::ChildThread() {
channel_name_ = WideToASCII(
CommandLine::ForCurrentProcess()->GetSwitchValue(
switches::kProcessChannelID));
+ Init();
+}
+ChildThread::ChildThread(const std::string channel_name)
+ : channel_name_(channel_name) {
+ Init();
+}
+
+void ChildThread::Init() {
+ check_with_browser_before_shutdown_ = false;
+ message_loop_ = MessageLoop::current();
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUserAgent)) {
webkit_glue::SetUserAgent(WideToUTF8(
CommandLine::ForCurrentProcess()->GetSwitchValue(
switches::kUserAgent)));
}
+
+ channel_.reset(new IPC::SyncChannel(channel_name_,
+ IPC::Channel::MODE_CLIENT, this, NULL,
+ ChildProcess::current()->io_message_loop(), true,
+ ChildProcess::current()->GetShutDownEvent()));
+#ifdef IPC_MESSAGE_LOG_ENABLED
+ IPC::Logging::current()->SetIPCSender(this);
+#endif
+
+ resource_dispatcher_.reset(new ResourceDispatcher(this));
+
+ // When running in unit tests, there is already a NotificationService object.
+ // Since only one can exist at a time per thread, check first.
+ if (!NotificationService::current())
+ notification_service_.reset(new NotificationService);
}
ChildThread::~ChildThread() {
-}
+#ifdef IPC_MESSAGE_LOG_ENABLED
+ IPC::Logging::current()->SetIPCSender(NULL);
+#endif
-bool ChildThread::Run() {
- return StartWithOptions(options_);
+ // The ChannelProxy object caches a pointer to the IPC thread, so need to
+ // reset it as it's not guaranteed to outlive this object.
+ // NOTE: this also has the side-effect of not closing the main IPC channel to
+ // the browser process. This is needed because this is the signal that the
+ // browser uses to know that this process has died, so we need it to be alive
+ // until this process is shut down, and the OS closes the handle
+ // automatically. We used to watch the object handle on Windows to do this,
+ // but it wasn't possible to do so on POSIX.
+ channel_->ClearIPCMessageLoop();
}
void ChildThread::OnChannelError() {
- owner_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
+ MessageLoop::current()->Quit();
}
bool ChildThread::Send(IPC::Message* msg) {
@@ -76,7 +103,7 @@ void ChildThread::OnMessageReceived(const IPC::Message& msg) {
}
if (msg.type() == PluginProcessMsg_Shutdown::ID) {
- owner_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
+ MessageLoop::current()->Quit();
return;
}
@@ -88,33 +115,12 @@ void ChildThread::OnMessageReceived(const IPC::Message& msg) {
}
ChildThread* ChildThread::current() {
- return ChildProcess::current()->child_thread();
-}
-
-void ChildThread::Init() {
- channel_.reset(new IPC::SyncChannel(channel_name_,
- IPC::Channel::MODE_CLIENT, this, NULL, owner_loop_, true,
- ChildProcess::current()->GetShutDownEvent()));
-#ifdef IPC_MESSAGE_LOG_ENABLED
- IPC::Logging::current()->SetIPCSender(this);
-#endif
-
- resource_dispatcher_.reset(new ResourceDispatcher(this));
-}
-
-void ChildThread::CleanUp() {
-#ifdef IPC_MESSAGE_LOG_ENABLED
- IPC::Logging::current()->SetIPCSender(NULL);
-#endif
- // Need to destruct the SyncChannel to the browser before we go away because
- // it caches a pointer to this thread.
- channel_.reset();
- resource_dispatcher_.reset();
+ return ChildProcess::current()->main_thread();
}
void ChildThread::OnProcessFinalRelease() {
if (!check_with_browser_before_shutdown_) {
- owner_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
+ MessageLoop::current()->Quit();
return;
}
diff --git a/chrome/common/child_thread.h b/chrome/common/child_thread.h
index 1affe25..91ea9b7 100644
--- a/chrome/common/child_thread.h
+++ b/chrome/common/child_thread.h
@@ -7,18 +7,20 @@
#include "base/basictypes.h"
#include "base/scoped_ptr.h"
-#include "base/thread.h"
#include "chrome/common/message_router.h"
#include "chrome/common/resource_dispatcher.h"
#include "ipc/ipc_sync_channel.h"
-// Child processes's background thread should derive from this class.
+class NotificationService;
+
+// The main thread of a child process derives from this class.
class ChildThread : public IPC::Channel::Listener,
- public IPC::Message::Sender,
- public base::Thread {
+ public IPC::Message::Sender {
public:
// Creates the thread.
- ChildThread(Thread::Options options);
+ ChildThread();
+ // Used for single-process mode.
+ ChildThread(const std::string channel_name);
virtual ~ChildThread();
// IPC::Message::Sender implementation:
@@ -28,58 +30,39 @@ class ChildThread : public IPC::Channel::Listener,
void AddRoute(int32 routing_id, IPC::Channel::Listener* listener);
void RemoveRoute(int32 routing_id);
- MessageLoop* owner_loop() { return owner_loop_; }
-
ResourceDispatcher* resource_dispatcher() {
return resource_dispatcher_.get();
}
+ MessageLoop* message_loop() { return message_loop_; }
+
// Returns the one child thread.
static ChildThread* current();
protected:
friend class ChildProcess;
- // Starts the thread.
- bool Run();
-
- // Overrides the channel name. Used for --single-process mode.
- void SetChannelName(const std::string& name) { channel_name_ = name; }
-
// Called when the process refcount is 0.
void OnProcessFinalRelease();
- protected:
- // The required stack size if V8 runs on a thread.
- static const size_t kV8StackSize;
-
virtual void OnControlMessageReceived(const IPC::Message& msg) { }
IPC::SyncChannel* channel() { return channel_.get(); }
- // Thread implementation.
- virtual void Init();
- virtual void CleanUp();
-
private:
+ void Init();
+
// IPC::Channel::Listener implementation:
virtual void OnMessageReceived(const IPC::Message& msg);
virtual void OnChannelError();
- // The message loop used to run tasks on the thread that started this thread.
- MessageLoop* owner_loop_;
-
std::string channel_name_;
scoped_ptr<IPC::SyncChannel> channel_;
- // Used only on the background render thread to implement message routing
- // functionality to the consumers of the ChildThread.
+ // Implements message routing functionality to the consumers of ChildThread.
MessageRouter router_;
- Thread::Options options_;
-
// Handles resource loads for this process.
- // NOTE: this object lives on the owner thread.
scoped_ptr<ResourceDispatcher> resource_dispatcher_;
// If true, checks with the browser process before shutdown. This avoids race
@@ -87,6 +70,10 @@ class ChildThread : public IPC::Channel::Listener,
// that would addref it.
bool check_with_browser_before_shutdown_;
+ MessageLoop* message_loop_;
+
+ scoped_ptr<NotificationService> notification_service_;
+
DISALLOW_COPY_AND_ASSIGN(ChildThread);
};
diff --git a/chrome/common/histogram_synchronizer.cc b/chrome/common/histogram_synchronizer.cc
index 4713084..9ed94b0 100644
--- a/chrome/common/histogram_synchronizer.cc
+++ b/chrome/common/histogram_synchronizer.cc
@@ -7,6 +7,7 @@
#include "base/histogram.h"
#include "base/logging.h"
#include "base/string_util.h"
+#include "base/thread.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
diff --git a/chrome/plugin/plugin_main.cc b/chrome/plugin/plugin_main.cc
index 7361d64..63d295d 100644
--- a/chrome/plugin/plugin_main.cc
+++ b/chrome/plugin/plugin_main.cc
@@ -29,8 +29,8 @@
// main() routine for running as the plugin process.
int PluginMain(const MainFunctionParams& parameters) {
- // The main thread of the plugin services IO.
- MessageLoopForIO main_message_loop;
+ // The main thread of the plugin services UI.
+ MessageLoop main_message_loop(MessageLoop::TYPE_UI);
std::wstring app_name = chrome::kBrowserAppName;
PlatformThread::SetName(WideToASCII(app_name + L"_PluginMain").c_str());
@@ -80,7 +80,8 @@ int PluginMain(const MainFunctionParams& parameters) {
}
{
- ChildProcess plugin_process(new PluginThread());
+ ChildProcess plugin_process;
+ plugin_process.set_main_thread(new PluginThread());
#if defined(OS_WIN)
if (!no_sandbox && target_services)
target_services->LowerToken();
diff --git a/chrome/plugin/plugin_thread.cc b/chrome/plugin/plugin_thread.cc
index da5c68c..ae90e1a 100644
--- a/chrome/plugin/plugin_thread.cc
+++ b/chrome/plugin/plugin_thread.cc
@@ -6,11 +6,6 @@
#include "build/build_config.h"
-#if defined(OS_WIN)
-#include <windows.h>
-#include <objbase.h>
-#endif
-
#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/process_util.h"
@@ -18,7 +13,6 @@
#include "chrome/common/child_process.h"
#include "chrome/common/chrome_plugin_lib.h"
#include "chrome/common/chrome_switches.h"
-#include "chrome/common/notification_service.h"
#include "chrome/common/plugin_messages.h"
#include "chrome/common/render_messages.h"
#include "chrome/plugin/chrome_plugin_host.h"
@@ -32,27 +26,10 @@ static base::LazyInstance<base::ThreadLocalPointer<PluginThread> > lazy_tls(
base::LINKER_INITIALIZED);
PluginThread::PluginThread()
- : ChildThread(base::Thread::Options(MessageLoop::TYPE_UI, 0)),
- preloaded_plugin_module_(NULL) {
+ : preloaded_plugin_module_(NULL) {
plugin_path_ = FilePath::FromWStringHack(
CommandLine::ForCurrentProcess()->GetSwitchValue(switches::kPluginPath));
-}
-
-PluginThread::~PluginThread() {
-}
-
-PluginThread* PluginThread::current() {
- return lazy_tls.Pointer()->Get();
-}
-
-void PluginThread::OnControlMessageReceived(const IPC::Message& msg) {
- IPC_BEGIN_MESSAGE_MAP(PluginThread, msg)
- IPC_MESSAGE_HANDLER(PluginProcessMsg_CreateChannel, OnCreateChannel)
- IPC_MESSAGE_HANDLER(PluginProcessMsg_PluginMessage, OnPluginMessage)
- IPC_END_MESSAGE_MAP()
-}
-void PluginThread::Init() {
lazy_tls.Pointer()->Set(this);
#if defined(OS_LINUX)
{
@@ -75,14 +52,8 @@ void PluginThread::Init() {
}
}
#endif
- ChildThread::Init();
PatchNPNFunctions();
-#if defined(OS_WIN)
- CoInitialize(NULL);
-#endif
-
- notification_service_.reset(new NotificationService);
// Preload the library to avoid loading, unloading then reloading
preloaded_plugin_module_ = base::LoadNativeLibrary(plugin_path_);
@@ -100,7 +71,7 @@ void PluginThread::Init() {
message_loop()->set_exception_restoration(true);
}
-void PluginThread::CleanUp() {
+PluginThread::~PluginThread() {
if (preloaded_plugin_module_) {
base::UnloadNativeLibrary(preloaded_plugin_module_);
preloaded_plugin_module_ = NULL;
@@ -108,26 +79,29 @@ void PluginThread::CleanUp() {
PluginChannelBase::CleanupChannels();
NPAPI::PluginLib::UnloadAllPlugins();
ChromePluginLib::UnloadAllPlugins();
- notification_service_.reset();
-#if defined(OS_WIN)
- CoUninitialize();
-#endif
if (webkit_glue::ShouldForcefullyTerminatePluginProcess())
base::KillProcess(base::GetCurrentProcessHandle(), 0, /* wait= */ false);
- // Call this last because it deletes the ResourceDispatcher, which is used
- // in some of the above cleanup.
- // See http://code.google.com/p/chromium/issues/detail?id=8980
- ChildThread::CleanUp();
lazy_tls.Pointer()->Set(NULL);
}
+PluginThread* PluginThread::current() {
+ return lazy_tls.Pointer()->Get();
+}
+
+void PluginThread::OnControlMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(PluginThread, msg)
+ IPC_MESSAGE_HANDLER(PluginProcessMsg_CreateChannel, OnCreateChannel)
+ IPC_MESSAGE_HANDLER(PluginProcessMsg_PluginMessage, OnPluginMessage)
+ IPC_END_MESSAGE_MAP()
+}
+
void PluginThread::OnCreateChannel(
int process_id,
bool off_the_record) {
- scoped_refptr<PluginChannel> channel =
- PluginChannel::GetPluginChannel(process_id, owner_loop());
+ scoped_refptr<PluginChannel> channel = PluginChannel::GetPluginChannel(
+ process_id, ChildProcess::current()->io_message_loop());
IPC::ChannelHandle channel_handle;
if (channel.get()) {
channel_handle.name = channel->channel_name();
diff --git a/chrome/plugin/plugin_thread.h b/chrome/plugin/plugin_thread.h
index e9074aa..2e9803c 100644
--- a/chrome/plugin/plugin_thread.h
+++ b/chrome/plugin/plugin_thread.h
@@ -16,8 +16,6 @@
#include "base/file_descriptor_posix.h"
#endif
-class NotificationService;
-
// The PluginThread class represents a background thread where plugin instances
// live. Communication occurs between WebPluginDelegateProxy in the renderer
// process and WebPluginDelegateStub in this thread through IPC messages.
@@ -32,18 +30,12 @@ class PluginThread : public ChildThread {
private:
virtual void OnControlMessageReceived(const IPC::Message& msg);
- // Thread implementation:
- virtual void Init();
- virtual void CleanUp();
-
// Callback for when a channel has been created.
void OnCreateChannel(
int process_id,
bool off_the_record);
void OnPluginMessage(const std::vector<uint8> &data);
- scoped_ptr<NotificationService> notification_service_;
-
// The plugin module which is preloaded in Init
base::NativeLibrary preloaded_plugin_module_;
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 1b8509f..ba5c37a 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..80811b2 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,18 @@ 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);
@@ -138,8 +105,7 @@ void RenderThread::Init() {
CoInitialize(0);
#endif
- ChildThread::Init();
- notification_service_.reset(new NotificationService);
+ plugin_refresh_allowed_ = true;
cache_stats_factory_.reset(
new ScopedRunnableMethodFactory<RenderThread>(this));
@@ -158,24 +124,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 +143,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 +249,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 76491fe..e22cabb 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 21c40e2..fd8f61a 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -2814,14 +2814,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 7624620..d83bab9 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 f5d7811..55234ec 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"
@@ -96,8 +97,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());
@@ -128,6 +132,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 34a728d..233749b9 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;
diff --git a/chrome/utility/utility_main.cc b/chrome/utility/utility_main.cc
index ad66043c..bb669a7 100644
--- a/chrome/utility/utility_main.cc
+++ b/chrome/utility/utility_main.cc
@@ -20,15 +20,16 @@
// Mainline routine for running as the utility process.
int UtilityMain(const MainFunctionParams& parameters) {
- // The main thread of the render process.
- MessageLoopForIO main_message_loop;
+ // The main message loop of the utility process.
+ MessageLoop main_message_loop;
std::wstring app_name = chrome::kBrowserAppName;
PlatformThread::SetName(WideToASCII(app_name + L"_UtilityMain").c_str());
// Initialize the SystemMonitor
base::SystemMonitor::Start();
- ChildProcess utility_process(new UtilityThread());
+ ChildProcess utility_process;
+ utility_process.set_main_thread(new UtilityThread());
#if defined(OS_WIN)
sandbox::TargetServices* target_services =
parameters.sandbox_info_.TargetServices();
diff --git a/chrome/utility/utility_thread.cc b/chrome/utility/utility_thread.cc
index 46815b1..dc9f965 100644
--- a/chrome/utility/utility_thread.cc
+++ b/chrome/utility/utility_thread.cc
@@ -11,20 +11,11 @@
#include "chrome/common/extensions/extension_unpacker.h"
#include "chrome/common/render_messages.h"
-UtilityThread::UtilityThread() : ChildThread(base::Thread::Options()) {
-}
-
-UtilityThread::~UtilityThread() {
-}
-
-void UtilityThread::Init() {
- ChildThread::Init();
+UtilityThread::UtilityThread() {
ChildProcess::current()->AddRefProcess();
}
-void UtilityThread::CleanUp() {
- // Shutdown in reverse of the initialization order.
- ChildThread::CleanUp();
+UtilityThread::~UtilityThread() {
}
void UtilityThread::OnControlMessageReceived(const IPC::Message& msg) {
diff --git a/chrome/utility/utility_thread.h b/chrome/utility/utility_thread.h
index 1c128ad..4fad53e 100644
--- a/chrome/utility/utility_thread.h
+++ b/chrome/utility/utility_thread.h
@@ -7,7 +7,6 @@
#include <string>
-#include "base/thread.h"
#include "chrome/common/child_thread.h"
class GURL;
@@ -31,10 +30,6 @@ class UtilityThread : public ChildThread {
// IPC messages for web resource service.
void OnUnpackWebResource(const std::string& resource_data);
- // Called by the thread base class
- virtual void Init();
- virtual void CleanUp();
-
DISALLOW_COPY_AND_ASSIGN(UtilityThread);
};
diff --git a/chrome/worker/worker_main.cc b/chrome/worker/worker_main.cc
index 03831b8b..d6304ab 100644
--- a/chrome/worker/worker_main.cc
+++ b/chrome/worker/worker_main.cc
@@ -20,15 +20,16 @@
// Mainline routine for running as the worker process.
int WorkerMain(const MainFunctionParams& parameters) {
- // The main thread of the render process.
- MessageLoopForIO main_message_loop;
+ // The main message loop of the worker process.
+ MessageLoop main_message_loop;
std::wstring app_name = chrome::kBrowserAppName;
PlatformThread::SetName(WideToASCII(app_name + L"_WorkerMain").c_str());
// Initialize the SystemMonitor
base::SystemMonitor::Start();
- ChildProcess worker_process(new WorkerThread());
+ ChildProcess worker_process;
+ worker_process.set_main_thread(new WorkerThread());
#if defined(OS_WIN)
sandbox::TargetServices* target_services =
parameters.sandbox_info_.TargetServices();
diff --git a/chrome/worker/worker_thread.cc b/chrome/worker/worker_thread.cc
index 7663b7a..e4be0b9 100644
--- a/chrome/worker/worker_thread.cc
+++ b/chrome/worker/worker_thread.cc
@@ -15,37 +15,22 @@ static base::LazyInstance<base::ThreadLocalPointer<WorkerThread> > lazy_tls(
base::LINKER_INITIALIZED);
-WorkerThread::WorkerThread()
- : ChildThread(base::Thread::Options(MessageLoop::TYPE_DEFAULT,
- kV8StackSize)) {
-}
-
-WorkerThread::~WorkerThread() {
-}
-
-WorkerThread* WorkerThread::current() {
- return lazy_tls.Pointer()->Get();
-}
-
-void WorkerThread::Init() {
+WorkerThread::WorkerThread() {
lazy_tls.Pointer()->Set(this);
- ChildThread::Init();
webkit_client_.reset(new WorkerWebKitClientImpl);
WebKit::initialize(webkit_client_.get());
}
-void WorkerThread::CleanUp() {
+WorkerThread::~WorkerThread() {
// Shutdown in reverse of the initialization order.
-
- if (webkit_client_.get()) {
- WebKit::shutdown();
- webkit_client_.reset();
- }
-
- ChildThread::CleanUp();
+ WebKit::shutdown();
lazy_tls.Pointer()->Set(NULL);
}
+WorkerThread* WorkerThread::current() {
+ return lazy_tls.Pointer()->Get();
+}
+
void WorkerThread::OnControlMessageReceived(const IPC::Message& msg) {
IPC_BEGIN_MESSAGE_MAP(WorkerThread, msg)
IPC_MESSAGE_HANDLER(WorkerProcessMsg_CreateWorker, OnCreateWorker)
diff --git a/chrome/worker/worker_thread.h b/chrome/worker/worker_thread.h
index 6bea33c..27d0abf 100644
--- a/chrome/worker/worker_thread.h
+++ b/chrome/worker/worker_thread.h
@@ -5,7 +5,6 @@
#ifndef CHROME_WORKER_WORKER_THREAD_H_
#define CHROME_WORKER_WORKER_THREAD_H_
-#include "base/thread.h"
#include "chrome/common/child_thread.h"
class GURL;
@@ -22,10 +21,6 @@ class WorkerThread : public ChildThread {
private:
virtual void OnControlMessageReceived(const IPC::Message& msg);
- // Called by the thread base class
- virtual void Init();
- virtual void CleanUp();
-
void OnCreateWorker(const GURL& url, int route_id);
scoped_ptr<WorkerWebKitClientImpl> webkit_client_;
diff --git a/ipc/ipc_channel_proxy.cc b/ipc/ipc_channel_proxy.cc
index d96e413..eba506d 100644
--- a/ipc/ipc_channel_proxy.cc
+++ b/ipc/ipc_channel_proxy.cc
@@ -272,6 +272,10 @@ void ChannelProxy::RemoveFilter(MessageFilter* filter) {
context_.get(), &Context::OnRemoveFilter, filter));
}
+void ChannelProxy::ClearIPCMessageLoop() {
+ context()->ClearIPCMessageLoop();
+}
+
#if defined(OS_POSIX)
// See the TODO regarding lazy initialization of the channel in
// ChannelProxy::Init().
diff --git a/ipc/ipc_channel_proxy.h b/ipc/ipc_channel_proxy.h
index 1aed33e..77ddd87 100644
--- a/ipc/ipc_channel_proxy.h
+++ b/ipc/ipc_channel_proxy.h
@@ -117,6 +117,9 @@ class ChannelProxy : public Message::Sender {
void AddFilter(MessageFilter* filter);
void RemoveFilter(MessageFilter* filter);
+ // Called to clear the pointer to the IPC message loop when it's going away.
+ void ClearIPCMessageLoop();
+
#if defined(OS_POSIX)
// Calls through to the underlying channel's methods.
// TODO(playmobil): For now this is only implemented in the case of
@@ -140,6 +143,7 @@ class ChannelProxy : public Message::Sender {
Context(Channel::Listener* listener, MessageFilter* filter,
MessageLoop* ipc_thread);
virtual ~Context() { }
+ void ClearIPCMessageLoop() { ipc_message_loop_ = NULL; }
MessageLoop* ipc_message_loop() const { return ipc_message_loop_; }
const std::string& channel_id() const { return channel_id_; }
diff --git a/tools/valgrind/memcheck/suppressions.txt b/tools/valgrind/memcheck/suppressions.txt
index 26b7fc6..8e1db34 100644
--- a/tools/valgrind/memcheck/suppressions.txt
+++ b/tools/valgrind/memcheck/suppressions.txt
@@ -735,8 +735,9 @@
Memcheck:Leak
fun:_Znwj
fun:_ZN3IPC11SyncChannelC1ERKSsNS_7Channel4ModeEPNS3_8ListenerEPNS_12ChannelProxy13MessageFilterEP11MessageLoopbPN4base13WaitableEventE
- fun:_ZN11ChildThread4InitEv
- fun:_ZN12RenderThread4InitEv
+ ...
+ fun:_ZN11ChildThreadC2Ev
+ fun:_ZN12RenderThreadC1Ev
}
{
bug_16129