summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-20 05:23:36 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-20 05:23:36 +0000
commit514e711ea07b6a1aef47ebf20250a37bd632402c (patch)
tree632f5e8902cc4231e9c14d0ad28035d63a0c964d
parent4acbad918766b81f1da3f10e2ae8aa2b10bb0593 (diff)
downloadchromium_src-514e711ea07b6a1aef47ebf20250a37bd632402c.zip
chromium_src-514e711ea07b6a1aef47ebf20250a37bd632402c.tar.gz
chromium_src-514e711ea07b6a1aef47ebf20250a37bd632402c.tar.bz2
Refactor code from RenderThread and PluginThread and move it to ChildThread. ChildProcess now owns the ChildThread, which removes duplicate code and simplifies things.
Clean up ChildProcess, there really was no need for all the templates and statics in it and its subclasses. Review URL: http://codereview.chromium.org/21502 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10080 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/thread.h2
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.cc7
-rw-r--r--chrome/chrome.xcodeproj/project.pbxproj6
-rw-r--r--chrome/common/child_process.cc108
-rw-r--r--chrome/common/child_process.h76
-rw-r--r--chrome/common/child_thread.cc95
-rw-r--r--chrome/common/child_thread.h76
-rw-r--r--chrome/common/common.scons2
-rw-r--r--chrome/common/common.vcproj8
-rw-r--r--chrome/common/ipc_sync_channel_unittest.cc26
-rw-r--r--chrome/common/temp_scaffolding_stubs.cc1
-rw-r--r--chrome/plugin/chrome_plugin_host.cc17
-rw-r--r--chrome/plugin/plugin_channel.cc8
-rw-r--r--chrome/plugin/plugin_channel_base.cc6
-rw-r--r--chrome/plugin/plugin_main.cc9
-rw-r--r--chrome/plugin/plugin_process.cc49
-rw-r--r--chrome/plugin/plugin_process.h28
-rw-r--r--chrome/plugin/plugin_thread.cc146
-rw-r--r--chrome/plugin/plugin_thread.h48
-rw-r--r--chrome/plugin/webplugin_proxy.cc4
-rw-r--r--chrome/renderer/chrome_plugin_host.cc8
-rw-r--r--chrome/renderer/mock_render_process.h12
-rw-r--r--chrome/renderer/net/render_dns_master.cc8
-rw-r--r--chrome/renderer/render_process.cc78
-rw-r--r--chrome/renderer/render_process.h46
-rw-r--r--chrome/renderer/render_process_unittest.cc9
-rw-r--r--chrome/renderer/render_thread.cc126
-rw-r--r--chrome/renderer/render_thread.h70
-rw-r--r--chrome/renderer/render_thread_unittest.cc23
-rw-r--r--chrome/renderer/render_view.cc17
-rw-r--r--chrome/renderer/render_view_unittest.cc9
-rw-r--r--chrome/renderer/render_widget.cc16
-rw-r--r--chrome/renderer/render_widget.h2
-rw-r--r--chrome/renderer/render_widget_unittest.cc11
-rw-r--r--chrome/renderer/renderer_glue.cc48
-rw-r--r--chrome/renderer/renderer_main.cc7
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.cc4
37 files changed, 560 insertions, 656 deletions
diff --git a/base/thread.h b/base/thread.h
index 5a51bec..4254168 100644
--- a/base/thread.h
+++ b/base/thread.h
@@ -29,6 +29,8 @@ class Thread : PlatformThread::Delegate {
size_t stack_size;
Options() : message_loop_type(MessageLoop::TYPE_DEFAULT), stack_size(0) {}
+ Options(MessageLoop::Type type, size_t size)
+ : message_loop_type(type), stack_size(size) {}
};
// Constructor.
diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc
index d17ab83..fc3bdfd 100644
--- a/chrome/browser/renderer_host/browser_render_process_host.cc
+++ b/chrome/browser/renderer_host/browser_render_process_host.cc
@@ -18,6 +18,7 @@
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/rand_util.h"
+#include "base/scoped_ptr.h"
#include "base/shared_memory.h"
#include "base/singleton.h"
#include "base/string_util.h"
@@ -83,8 +84,7 @@ class RendererMainThread : public base::Thread {
CoInitialize(NULL);
#endif
- bool rv = RenderProcess::GlobalInit(channel_id_);
- DCHECK(rv);
+ render_process_.reset(new RenderProcess(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.
@@ -94,7 +94,7 @@ class RendererMainThread : public base::Thread {
}
virtual void CleanUp() {
- RenderProcess::GlobalCleanup();
+ render_process_.reset();
#if defined(OS_WIN)
CoUninitialize();
@@ -103,6 +103,7 @@ class RendererMainThread : public base::Thread {
private:
std::wstring channel_id_;
+ scoped_ptr<RenderProcess> render_process_;
};
// Used for a View_ID where the renderer has not been attached yet
diff --git a/chrome/chrome.xcodeproj/project.pbxproj b/chrome/chrome.xcodeproj/project.pbxproj
index 522aa5c..1f4c80f 100644
--- a/chrome/chrome.xcodeproj/project.pbxproj
+++ b/chrome/chrome.xcodeproj/project.pbxproj
@@ -248,6 +248,7 @@
534E66C40F311BEC0006B2B2 /* temp_scaffolding_stubs.cc in Sources */ = {isa = PBXBuildFile; fileRef = 534E66C30F311BEC0006B2B2 /* temp_scaffolding_stubs.cc */; };
544FBC49CB83E458B6B7069D /* test_web_contents.cc in Sources */ = {isa = PBXBuildFile; fileRef = 56E1D7DF17D327BFCB0B895D /* test_web_contents.cc */; };
623E5BE905E098E8280304DA /* dns_master_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFA6F0E9D4981009A6919 /* dns_master_unittest.cc */; };
+ 5DD7664089E8660524ED1CBC /* child_thread.cc in Sources */ = {isa = PBXBuildFile; fileRef = E81681ADC802675FE949BC63 /* child_thread.cc */; };
6532B3A0E10294CDF999C20A /* child_process_info.cc in Sources */ = {isa = PBXBuildFile; fileRef = BA9BC2620F44DCBE00588450 /* child_process_info.cc */; };
65930533A98EF22451EEA01D /* history_publisher_none.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7849CCC221723C1BC14D6384 /* history_publisher_none.cc */; };
6685F5375CC4ECE98C4C2213 /* browser_about_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BF8320E9D4839009A6919 /* browser_about_handler.cc */; };
@@ -2440,6 +2441,7 @@
826850600F2FCC27009F6555 /* libxslt.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libxslt.xcodeproj; path = third_party/libxslt/libxslt.xcodeproj; sourceTree = "<group>"; };
826858F80F326FA3009F6555 /* testing_profile.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = testing_profile.cc; sourceTree = "<group>"; };
826858F90F326FA3009F6555 /* testing_profile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = testing_profile.h; sourceTree = "<group>"; };
+ 829FBA2DED615C19FB7E7522 /* child_thread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = child_thread.h; sourceTree = "<group>"; };
82BB33080F44B57C00761F43 /* base_view.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = base_view.h; path = cocoa/base_view.h; sourceTree = "<group>"; };
82BB33090F44B57C00761F43 /* base_view.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = base_view.mm; path = cocoa/base_view.mm; sourceTree = "<group>"; };
82FA32740F3A537C00271C5A /* web_contents_view_mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = web_contents_view_mac.h; path = tab_contents/web_contents_view_mac.h; sourceTree = "<group>"; };
@@ -2789,6 +2791,7 @@
E4F324420EE5CE94002533CE /* extension_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = extension_unittest.cc; sourceTree = "<group>"; };
E4F324780EE5D17E002533CE /* referrer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = referrer.h; sourceTree = "<group>"; };
E4F324790EE5D17E002533CE /* referrer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = referrer.cc; sourceTree = "<group>"; };
+ E81681ADC802675FE949BC63 /* child_thread.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = child_thread.cc; sourceTree = "<group>"; };
EA72C084DB3FC0FC595E525E /* template_url_model.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = template_url_model.cc; sourceTree = "<group>"; };
EA72CF50C0AB4492A644C703 /* url_fetcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = url_fetcher.h; sourceTree = "<group>"; };
F174BA4A5FF6B3DFC64105AD /* transport_dib_mac.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = transport_dib_mac.cc; sourceTree = "<group>"; };
@@ -3652,6 +3655,8 @@
4D7BFB8A0E9D4C9F009A6919 /* child_process.h */,
BA9BC2620F44DCBE00588450 /* child_process_info.cc */,
BA9BC2630F44DCC400588450 /* child_process_info.h */,
+ E81681ADC802675FE949BC63 /* child_thread.cc */,
+ 829FBA2DED615C19FB7E7522 /* child_thread.h */,
4D7BFB8B0E9D4C9F009A6919 /* chrome_constants.cc */,
4D7BFB8C0E9D4C9F009A6919 /* chrome_constants.h */,
4D7BFB8D0E9D4C9F009A6919 /* chrome_counters.cc */,
@@ -5657,6 +5662,7 @@
buildActionMask = 2147483647;
files = (
4D7BFC260E9D4CE8009A6919 /* animation.cc in Sources */,
+ 5DD7664089E8660524ED1CBC /* child_thread.cc in Sources */,
B562E2D50F05834500FB1A4F /* chrome_canvas.cc in Sources */,
4D7BFC280E9D4CEB009A6919 /* chrome_constants.cc in Sources */,
4D7BFC2A0E9D4CED009A6919 /* chrome_counters.cc in Sources */,
diff --git a/chrome/common/child_process.cc b/chrome/common/child_process.cc
index b64984c..27265d3 100644
--- a/chrome/common/child_process.cc
+++ b/chrome/common/child_process.cc
@@ -4,109 +4,63 @@
#include "chrome/common/child_process.h"
-#include "base/atomic_ref_count.h"
#include "base/basictypes.h"
-#include "base/command_line.h"
#include "base/string_util.h"
-#include "base/waitable_event.h"
-#include "chrome/common/chrome_switches.h"
-#include "webkit/glue/webkit_glue.h"
+#include "chrome/common/child_thread.h"
ChildProcess* ChildProcess::child_process_;
-MessageLoop* ChildProcess::main_thread_loop_;
-static base::AtomicRefCount ref_count;
-base::WaitableEvent* ChildProcess::shutdown_event_;
-
-ChildProcess::ChildProcess() {
+ChildProcess::ChildProcess(ChildThread* child_thread)
+ : shutdown_event_(true, false),
+ ref_count_(0),
+ child_thread_(child_thread) {
DCHECK(!child_process_);
+ child_process_ = this;
+ if (child_thread_.get()) // null in unittests.
+ child_thread_->Run();
}
ChildProcess::~ChildProcess() {
DCHECK(child_process_ == this);
+
+ // Signal this event before destroying the child process. That way all
+ // background threads can cleanup.
+ // For example, in the renderer the RenderThread instances will be able to
+ // notice shutdown before the render process begins waiting for them to exit.
+ shutdown_event_.Signal();
+
+ if (child_thread_.get())
+ child_thread_->Stop();
+
+ child_process_ = NULL;
}
// Called on any thread
void ChildProcess::AddRefProcess() {
- base::AtomicRefCountInc(&ref_count);
+ base::AtomicRefCountInc(&ref_count_);
}
// Called on any thread
void ChildProcess::ReleaseProcess() {
- DCHECK(!base::AtomicRefCountIsZero(&ref_count));
+ DCHECK(!base::AtomicRefCountIsZero(&ref_count_));
DCHECK(child_process_);
- if (!base::AtomicRefCountDec(&ref_count))
+ if (!base::AtomicRefCountDec(&ref_count_))
child_process_->OnFinalRelease();
}
+base::WaitableEvent* ChildProcess::GetShutDownEvent() {
+ DCHECK(child_process_);
+ return &child_process_->shutdown_event_;
+}
+
// Called on any thread
-// static
bool ChildProcess::ProcessRefCountIsZero() {
- return base::AtomicRefCountIsZero(&ref_count);
+ return base::AtomicRefCountIsZero(&ref_count_);
}
void ChildProcess::OnFinalRelease() {
- DCHECK(main_thread_loop_);
- main_thread_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
-}
-
-base::WaitableEvent* ChildProcess::GetShutDownEvent() {
- return shutdown_event_;
-}
-
-// On error, it is OK to leave the global pointers, as long as the only
-// non-NULL pointers are valid. GlobalCleanup will always get called, which
-// will delete any non-NULL services.
-bool ChildProcess::GlobalInit(const std::wstring &channel_name,
- ChildProcessFactoryInterface *factory) {
- // OK to be called multiple times.
- if (main_thread_loop_)
- return true;
-
- if (channel_name.empty()) {
- NOTREACHED() << "Unable to get the channel name";
- return false;
+ if (child_thread_.get()) {
+ child_thread_->owner_loop()->PostTask(
+ FROM_HERE, new MessageLoop::QuitTask());
}
-
- // Remember the current message loop, so we can communicate with this thread
- // again when we need to shutdown (see ReleaseProcess).
- main_thread_loop_ = MessageLoop::current();
-
- // An event that will be signalled when we shutdown.
- shutdown_event_ = new base::WaitableEvent(true, false);
-
- child_process_ = factory->Create(channel_name);
-
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- if (command_line.HasSwitch(switches::kUserAgent)) {
-#if defined(OS_WIN)
- // TODO(port): calling this connects an, otherwise disconnected, subgraph
- // of symbols, causing huge numbers of linker errors.
- webkit_glue::SetUserAgent(WideToUTF8(
- command_line.GetSwitchValue(switches::kUserAgent)));
-#endif
- }
-
- return true;
}
-
-void ChildProcess::GlobalCleanup() {
- // Signal this event before destroying the child process. That way all
- // background threads.
- // For example, in the renderer the RenderThread instances will be able to
- // notice shutdown before the render process begins waiting for them to exit.
- shutdown_event_->Signal();
-
- // Destroy the child process first to force all background threads to
- // terminate before we bring down other resources. (We null pointers
- // just in case.)
- child_process_->Cleanup();
- delete child_process_;
- child_process_ = NULL;
-
- main_thread_loop_ = NULL;
-
- delete shutdown_event_;
- shutdown_event_ = NULL;
-}
-
diff --git a/chrome/common/child_process.h b/chrome/common/child_process.h
index 4a63efb..14fa406 100644
--- a/chrome/common/child_process.h
+++ b/chrome/common/child_process.h
@@ -7,45 +7,26 @@
#include <string>
#include <vector>
+#include "base/atomic_ref_count.h"
#include "base/basictypes.h"
#include "base/message_loop.h"
+#include "base/scoped_ptr.h"
+#include "base/waitable_event.h"
-namespace base {
- class WaitableEvent;
-};
-
-class ChildProcess;
+class ChildThread;
-class ChildProcessFactoryInterface {
- public:
- virtual ChildProcess* Create(const std::wstring& channel_name) = 0;
-};
-
-template<class T>
-class ChildProcessFactory : public ChildProcessFactoryInterface {
- virtual ChildProcess* Create(const std::wstring& channel_name) {
- return new T(channel_name);
- }
-};
// 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);
+ virtual ~ChildProcess();
- // initializes/cleansup the global variables, services, and libraries
- // Derived classes need to implement a static GlobalInit, that calls
- // into ChildProcess::GlobalInit with a class factory
-//static bool GlobalInit(const std::wstring& channel_name);
- static void GlobalCleanup();
-
- // These are used for ref-counting the child process. The process shuts
- // itself down when the ref count reaches 0. These functions may be called
- // on any thread.
- // For example, in the renderer process, generally each tab managed by this
- // process will hold a reference to the process, and release when closed.
- static void AddRefProcess();
- static void ReleaseProcess();
+ // Getter for this process' main thread.
+ ChildThread* child_thread() { return child_thread_.get(); }
// 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
@@ -56,22 +37,24 @@ class ChildProcess {
// up waiting.
// For example, see the renderer code used to implement
// webkit_glue::GetCookies.
- static base::WaitableEvent* GetShutDownEvent();
+ base::WaitableEvent* GetShutDownEvent();
- // You must call Init after creating this object before it will be valid
- ChildProcess();
- virtual ~ChildProcess();
+ // These are used for ref-counting the child process. The process shuts
+ // itself down when the ref count reaches 0. These functions may be called
+ // on any thread.
+ // For example, in the renderer process, generally each tab managed by this
+ // process will hold a reference to the process, and release when closed.
+ void AddRefProcess();
+ void ReleaseProcess();
protected:
- static bool GlobalInit(const std::wstring& channel_name,
- ChildProcessFactoryInterface* factory);
-
- static bool ProcessRefCountIsZero();
+ friend class ChildThread;
- // The singleton instance for this process.
- static ChildProcess* child_process_;
+ // Getter for the one ChildProcess object for this process.
+ static ChildProcess* current() { return child_process_; }
- static MessageLoop* main_thread_loop_;
+ protected:
+ bool ProcessRefCountIsZero();
// Derived classes can override this to alter the behavior when the ref count
// reaches 0. The default implementation calls Quit on the main message loop
@@ -80,10 +63,15 @@ class ChildProcess {
virtual void OnFinalRelease();
private:
- // Derived classes can override this to handle any cleanup, called by
- // GlobalCleanup.
- virtual void Cleanup() {}
- static base::WaitableEvent* shutdown_event_;
+ // The singleton instance for this process.
+ static ChildProcess* child_process_;
+
+ // An event that will be signalled when we shutdown.
+ base::WaitableEvent shutdown_event_;
+
+ base::AtomicRefCount ref_count_;
+
+ scoped_ptr<ChildThread> child_thread_;
DISALLOW_EVIL_CONSTRUCTORS(ChildProcess);
};
diff --git a/chrome/common/child_thread.cc b/chrome/common/child_thread.cc
new file mode 100644
index 0000000..8aca654
--- /dev/null
+++ b/chrome/common/child_thread.cc
@@ -0,0 +1,95 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/child_thread.h"
+
+#include "base/command_line.h"
+#include "chrome/common/child_process.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/ipc_logging.h"
+#include "webkit/glue/webkit_glue.h"
+
+ChildThread::ChildThread(Thread::Options options)
+ : Thread("Chrome_ChildThread"),
+ owner_loop_(MessageLoop::current()),
+ in_send_(0),
+ options_(options) {
+ DCHECK(owner_loop_);
+ channel_name_ = CommandLine::ForCurrentProcess()->GetSwitchValue(
+ switches::kProcessChannelID);
+
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUserAgent)) {
+#if defined(OS_WIN)
+ // TODO(port): calling this connects an, otherwise disconnected, subgraph
+ // of symbols, causing huge numbers of linker errors.
+ webkit_glue::SetUserAgent(WideToUTF8(
+ CommandLine::ForCurrentProcess()->GetSwitchValue(switches::kUserAgent)));
+#endif
+ }
+}
+
+ChildThread::~ChildThread() {
+}
+
+bool ChildThread::Run() {
+ return StartWithOptions(options_);
+}
+
+void ChildThread::OnChannelError() {
+ owner_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
+}
+
+bool ChildThread::Send(IPC::Message* msg) {
+ if (!channel_.get()) {
+ delete msg;
+ return false;
+ }
+
+ in_send_++;
+ bool rv = channel_->Send(msg);
+ in_send_--;
+ return rv;
+}
+
+void ChildThread::AddRoute(int32 routing_id, IPC::Channel::Listener* listener) {
+ DCHECK(MessageLoop::current() == message_loop());
+
+ router_.AddRoute(routing_id, listener);
+}
+
+void ChildThread::RemoveRoute(int32 routing_id) {
+ DCHECK(MessageLoop::current() == message_loop());
+
+ router_.RemoveRoute(routing_id);
+}
+
+void ChildThread::OnMessageReceived(const IPC::Message& msg) {
+ if (msg.routing_id() == MSG_ROUTING_CONTROL) {
+ OnControlMessageReceived(msg);
+ } else {
+ router_.OnMessageReceived(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
+}
+
+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();
+}
diff --git a/chrome/common/child_thread.h b/chrome/common/child_thread.h
new file mode 100644
index 0000000..ac835cc
--- /dev/null
+++ b/chrome/common/child_thread.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_COMMON_CHILD_THREAD_H_
+#define CHROME_COMMON_CHILD_THREAD_H_
+
+#include "base/thread.h"
+#include "chrome/common/ipc_sync_channel.h"
+#include "chrome/common/message_router.h"
+
+// Child processes's background thread should derive from this class.
+class ChildThread : public IPC::Channel::Listener,
+ public IPC::Message::Sender,
+ public base::Thread {
+ public:
+ // Creates the thread.
+ ChildThread(Thread::Options options);
+ virtual ~ChildThread();
+
+ // IPC::Message::Sender implementation:
+ virtual bool Send(IPC::Message* msg);
+
+ // See documentation on MessageRouter for AddRoute and RemoveRoute
+ void AddRoute(int32 routing_id, IPC::Channel::Listener* listener);
+ void RemoveRoute(int32 routing_id);
+
+ MessageLoop* owner_loop() { return owner_loop_; }
+
+ protected:
+ friend class ChildProcess;
+
+ // Starts the thread.
+ bool Run();
+
+ // Overrides the channel name. Used for --single-process mode.
+ void SetChannelName(const std::wstring& name) { channel_name_ = name; }
+
+ protected:
+ virtual void OnControlMessageReceived(const IPC::Message& msg) { }
+
+ // Returns the one child thread.
+ static ChildThread* current();
+
+ IPC::SyncChannel* channel() { return channel_.get(); }
+
+ // Indicates if ChildThread::Send() is on the call stack.
+ virtual bool InSend() const { return in_send_ != 0; }
+
+ // Thread implementation.
+ virtual void Init();
+ virtual void CleanUp();
+
+ private:
+ // 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::wstring 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.
+ MessageRouter router_;
+
+ int in_send_;
+
+ Thread::Options options_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(ChildThread);
+};
+
+#endif // CHROME_COMMON_CHILD_THREAD_H_
diff --git a/chrome/common/common.scons b/chrome/common/common.scons
index b2cc936..cc5e95d 100644
--- a/chrome/common/common.scons
+++ b/chrome/common/common.scons
@@ -110,6 +110,8 @@ input_files = ChromeFileList([
'child_process_host.h',
'child_process_info.cc',
'child_process_info.h',
+ 'child_thread.cc',
+ 'child_thread.h',
'chrome_constants.cc',
'chrome_constants.h',
'chrome_counters.cc',
diff --git a/chrome/common/common.vcproj b/chrome/common/common.vcproj
index 67a664e..2e91a0d 100644
--- a/chrome/common/common.vcproj
+++ b/chrome/common/common.vcproj
@@ -358,6 +358,14 @@
>
</File>
<File
+ RelativePath=".\child_thread.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\child_thread.h"
+ >
+ </File>
+ <File
RelativePath=".\chrome_constants.cc"
>
</File>
diff --git a/chrome/common/ipc_sync_channel_unittest.cc b/chrome/common/ipc_sync_channel_unittest.cc
index 596faed..f59cced 100644
--- a/chrome/common/ipc_sync_channel_unittest.cc
+++ b/chrome/common/ipc_sync_channel_unittest.cc
@@ -14,7 +14,6 @@
#include "base/string_util.h"
#include "base/thread.h"
#include "base/waitable_event.h"
-#include "chrome/common/child_process.h"
#include "chrome/common/ipc_message.h"
#include "chrome/common/ipc_sync_channel.h"
#include "chrome/common/stl_util-inl.h"
@@ -29,17 +28,6 @@ using base::WaitableEvent;
namespace {
-// SyncChannel should only be used in child processes as we don't want to hang
-// the browser. So in the unit test we need to have a ChildProcess object.
-class TestProcess : public ChildProcess {
- public:
- explicit TestProcess(const std::wstring& channel_name) {}
- static void GlobalInit() {
- ChildProcessFactory<TestProcess> factory;
- ChildProcess::GlobalInit(L"blah", &factory);
- }
-};
-
// Base class for a "process" with listener and IPC threads.
class Worker : public Channel::Listener, public Message::Sender {
public:
@@ -50,7 +38,8 @@ class Worker : public Channel::Listener, public Message::Sender {
mode_(mode),
ipc_thread_((thread_name + "_ipc").c_str()),
listener_thread_((thread_name + "_listener").c_str()),
- overrided_thread_(NULL) { }
+ overrided_thread_(NULL),
+ shutdown_event_(true, false) { }
// Will create a named channel and use this name for the threads' name.
Worker(const std::wstring& channel_name, Channel::Mode mode)
@@ -60,7 +49,8 @@ class Worker : public Channel::Listener, public Message::Sender {
mode_(mode),
ipc_thread_((WideToUTF8(channel_name) + "_ipc").c_str()),
listener_thread_((WideToUTF8(channel_name) + "_listener").c_str()),
- overrided_thread_(NULL) { }
+ overrided_thread_(NULL),
+ shutdown_event_(true, false) { }
// The IPC thread needs to outlive SyncChannel, so force the correct order of
// destruction.
@@ -153,7 +143,7 @@ class Worker : public Channel::Listener, public Message::Sender {
StartThread(&ipc_thread_, MessageLoop::TYPE_IO);
channel_.reset(new SyncChannel(
channel_name_, mode_, this, NULL, ipc_thread_.message_loop(), true,
- TestProcess::GetShutDownEvent()));
+ &shutdown_event_));
channel_created_->Signal();
Run();
}
@@ -195,6 +185,8 @@ class Worker : public Channel::Listener, public Message::Sender {
base::Thread listener_thread_;
base::Thread* overrided_thread_;
+ base::WaitableEvent shutdown_event_;
+
DISALLOW_EVIL_CONSTRUCTORS(Worker);
};
@@ -202,8 +194,6 @@ class Worker : public Channel::Listener, public Message::Sender {
// Starts the test with the given workers. This function deletes the workers
// when it's done.
void RunTest(std::vector<Worker*> workers) {
- TestProcess::GlobalInit();
-
// First we create the workers that are channel servers, or else the other
// workers' channel initialization might fail because the pipe isn't created..
for (size_t i = 0; i < workers.size(); ++i) {
@@ -224,8 +214,6 @@ void RunTest(std::vector<Worker*> workers) {
workers[i]->done_event()->Wait();
STLDeleteContainerPointers(workers.begin(), workers.end());
-
- TestProcess::GlobalCleanup();
}
} // namespace
diff --git a/chrome/common/temp_scaffolding_stubs.cc b/chrome/common/temp_scaffolding_stubs.cc
index 6a1b9c3c..8fcf796 100644
--- a/chrome/common/temp_scaffolding_stubs.cc
+++ b/chrome/common/temp_scaffolding_stubs.cc
@@ -316,7 +316,6 @@ bool RLZTracker::RecordProductEvent(Product product, AccessPoint point,
// This depends on porting all the plugin IPC messages.
bool IsPluginProcess() {
- NOTIMPLEMENTED();
return false;
}
diff --git a/chrome/plugin/chrome_plugin_host.cc b/chrome/plugin/chrome_plugin_host.cc
index 159d4b2..f1d2794 100644
--- a/chrome/plugin/chrome_plugin_host.cc
+++ b/chrome/plugin/chrome_plugin_host.cc
@@ -138,7 +138,7 @@ class PluginRequestHandlerProxy
CPError Start() {
bridge_.reset(
- PluginThread::GetPluginThread()->resource_dispatcher()->CreateBridge(
+ PluginThread::current()->resource_dispatcher()->CreateBridge(
cprequest_->method,
GURL(cprequest_->url),
GURL(cprequest_->url), // TODO(jackson): policy url?
@@ -252,9 +252,9 @@ void STDCALL CPB_SetKeepProcessAlive(CPID id, CPBool keep_alive) {
if (desired_value != g_keep_process_alive) {
g_keep_process_alive = desired_value;
if (g_keep_process_alive)
- PluginProcess::AddRefProcess();
+ PluginProcess::current()->AddRefProcess();
else
- PluginProcess::ReleaseProcess();
+ PluginProcess::current()->ReleaseProcess();
}
}
@@ -276,7 +276,7 @@ CPError STDCALL CPB_GetCookies(CPID id, CPBrowsingContext context,
if (webplugin) {
cookies_str = webplugin->GetCookies(GURL(url), GURL(url));
} else {
- PluginThread::GetPluginThread()->Send(
+ PluginThread::current()->Send(
new PluginProcessHostMsg_GetCookies(context, GURL(url), &cookies_str));
}
@@ -507,10 +507,9 @@ CPError STDCALL CPB_SendMessage(CPID id, const void *data, uint32 data_len) {
CHECK(ChromePluginLib::IsPluginThread());
const uint8* data_ptr = static_cast<const uint8*>(data);
std::vector<uint8> v(data_ptr, data_ptr + data_len);
- if (!PluginThread::GetPluginThread()->Send(
- new PluginProcessHostMsg_PluginMessage(v))) {
+ if (!PluginThread::current()->Send(new PluginProcessHostMsg_PluginMessage(v)))
return CPERR_FAILURE;
- }
+
return CPERR_SUCCESS;
}
@@ -520,7 +519,7 @@ CPError STDCALL CPB_SendSyncMessage(CPID id, const void *data, uint32 data_len,
const uint8* data_ptr = static_cast<const uint8*>(data);
std::vector<uint8> v(data_ptr, data_ptr + data_len);
std::vector<uint8> r;
- if (!PluginThread::GetPluginThread()->Send(
+ if (!PluginThread::current()->Send(
new PluginProcessHostMsg_PluginSyncMessage(v, &r))) {
return CPERR_FAILURE;
}
@@ -540,7 +539,7 @@ CPError STDCALL CPB_SendSyncMessage(CPID id, const void *data, uint32 data_len,
CPError STDCALL CPB_PluginThreadAsyncCall(CPID id,
void (*func)(void *),
void *user_data) {
- MessageLoop *message_loop = PluginThread::GetPluginThread()->message_loop();
+ MessageLoop *message_loop = PluginThread::current()->message_loop();
if (!message_loop) {
return CPERR_FAILURE;
}
diff --git a/chrome/plugin/plugin_channel.cc b/chrome/plugin/plugin_channel.cc
index 605feab..ab2d508 100644
--- a/chrome/plugin/plugin_channel.cc
+++ b/chrome/plugin/plugin_channel.cc
@@ -8,8 +8,8 @@
#include "chrome/common/plugin_messages.h"
#include "base/string_util.h"
-#include "chrome/plugin/plugin_thread.h"
#include "chrome/plugin/plugin_process.h"
+#include "chrome/plugin/plugin_thread.h"
PluginChannel* PluginChannel::GetPluginChannel(
int process_id, HANDLE renderer_handle, MessageLoop* ipc_message_loop) {
@@ -33,11 +33,11 @@ PluginChannel* PluginChannel::GetPluginChannel(
PluginChannel::PluginChannel() : in_send_(0) {
SendUnblockingOnlyDuringDispatch();
- PluginProcess::AddRefProcess();
+ PluginProcess::current()->AddRefProcess();
}
PluginChannel::~PluginChannel() {
- PluginProcess::ReleaseProcess();
+ PluginProcess::current()->ReleaseProcess();
}
bool PluginChannel::Send(IPC::Message* msg) {
@@ -84,7 +84,7 @@ void PluginChannel::OnGenerateRouteID(int* route_id) {
}
int PluginChannel::GenerateRouteID() {
- static LONG last_id = 0;
+ static LONG last_id = 0;
return InterlockedIncrement(&last_id);
}
diff --git a/chrome/plugin/plugin_channel_base.cc b/chrome/plugin/plugin_channel_base.cc
index c44c52e..2785328 100644
--- a/chrome/plugin/plugin_channel_base.cc
+++ b/chrome/plugin/plugin_channel_base.cc
@@ -76,9 +76,9 @@ void PluginChannelBase::CleanupChannels() {
bool PluginChannelBase::Init(MessageLoop* ipc_message_loop,
bool create_pipe_now) {
- channel_.reset(new IPC::SyncChannel(channel_name_, mode_, this, NULL,
- ipc_message_loop, create_pipe_now,
- PluginProcess::GetShutDownEvent()));
+ channel_.reset(new IPC::SyncChannel(
+ channel_name_, mode_, this, NULL, ipc_message_loop, create_pipe_now,
+ PluginProcess::current()->GetShutDownEvent()));
channel_valid_ = true;
return true;
}
diff --git a/chrome/plugin/plugin_main.cc b/chrome/plugin/plugin_main.cc
index c7bb53d..bc40fb9 100644
--- a/chrome/plugin/plugin_main.cc
+++ b/chrome/plugin/plugin_main.cc
@@ -53,12 +53,8 @@ int PluginMain(const MainFunctionParams& parameters) {
MB_OK | MB_SETFOREGROUND);
}
- std::wstring channel_name =
- parsed_command_line.GetSwitchValue(switches::kProcessChannelID);
- FilePath plugin_path =
- FilePath::FromWStringHack(
- parsed_command_line.GetSwitchValue(switches::kPluginPath));
- if (PluginProcess::GlobalInit(channel_name, plugin_path)) {
+ {
+ PluginProcess plugin_process;
if (!no_sandbox && target_services) {
target_services->LowerToken();
}
@@ -83,7 +79,6 @@ int PluginMain(const MainFunctionParams& parameters) {
// message loop to use it when translating messages.
MessageLoop::current()->Run();
}
- PluginProcess::GlobalCleanup();
CoUninitialize();
return 0;
diff --git a/chrome/plugin/plugin_process.cc b/chrome/plugin/plugin_process.cc
index fe19b9b..9d0f567 100644
--- a/chrome/plugin/plugin_process.cc
+++ b/chrome/plugin/plugin_process.cc
@@ -13,20 +13,6 @@
#include "chrome/common/render_messages.h"
#include "webkit/glue/webkit_glue.h"
-// Custom factory to allow us to pass additional ctor arguments.
-class PluginProcessFactory : public ChildProcessFactoryInterface {
- public:
- explicit PluginProcessFactory(const FilePath& plugin_path)
- : plugin_path_(plugin_path) {
- }
-
- virtual ChildProcess* Create(const std::wstring& channel_name) {
- return new PluginProcess(channel_name, plugin_path_);
- }
-
- const FilePath& plugin_path_;
-};
-
// How long to wait after there are no more plugin instances before killing the
// process.
static const int kProcessShutdownDelayMs = 10 * 1000;
@@ -39,31 +25,21 @@ template <> struct RunnableMethodTraits<PluginProcess> {
static void ReleaseCallee(PluginProcess*) {}
};
-PluginProcess::PluginProcess(const std::wstring& channel_name,
- const FilePath& plugin_path) :
- plugin_path_(plugin_path),
-#pragma warning(suppress: 4355) // Okay to pass "this" here.
- plugin_thread_(this, channel_name) {
+PluginProcess::PluginProcess()
+ : ChildProcess(new PluginThread()) {
}
PluginProcess::~PluginProcess() {
}
-bool PluginProcess::GlobalInit(const std::wstring &channel_name,
- const FilePath &plugin_path) {
- PluginProcessFactory factory(plugin_path);
- return ChildProcess::GlobalInit(channel_name, &factory);
-}
-
-
// Note: may be called on any thread
void PluginProcess::OnFinalRelease() {
// We override this to have the process linger for a few seconds to
// better accomdate back/forth navigation. This avoids shutting down and
// immediately starting a new plugin process. If a new channel is
// opened in the interim, the current process will not be shutdown.
- main_thread_loop_->PostDelayedTask(FROM_HERE, NewRunnableMethod(
- this, &PluginProcess::OnProcessShutdownTimeout),
+ child_thread()->owner_loop()->PostDelayedTask(FROM_HERE, NewRunnableMethod(
+ this, &PluginProcess::OnProcessShutdownTimeout),
kProcessShutdownDelayMs);
}
@@ -74,25 +50,10 @@ void PluginProcess::OnProcessShutdownTimeout() {
// process host instance in the browser to verify if it is ok to shutdown
// the plugin process. The browser then sends back a response indicating
// whether it is ok to shutdown.
- plugin_thread_.Send(new PluginProcessHostMsg_ShutdownRequest);
- }
-}
-
-// static
-void PluginProcess::ShutdownProcessResponse(bool ok_to_shutdown) {
- if (ok_to_shutdown) {
- PluginProcess* plugin_process =
- static_cast<PluginProcess*>(child_process_);
- DCHECK(plugin_process);
- plugin_process->Shutdown();
+ child_thread()->Send(new PluginProcessHostMsg_ShutdownRequest);
}
}
-void PluginProcess::BrowserShutdown() {
- ShutdownProcessResponse(true);
-}
-
void PluginProcess::Shutdown() {
ChildProcess::OnFinalRelease();
}
-
diff --git a/chrome/plugin/plugin_process.h b/chrome/plugin/plugin_process.h
index b315bce..467b46d 100644
--- a/chrome/plugin/plugin_process.h
+++ b/chrome/plugin/plugin_process.h
@@ -14,38 +14,24 @@
// each plugin.
class PluginProcess : public ChildProcess {
public:
- static bool GlobalInit(const std::wstring& channel_name,
- const FilePath& plugin_path);
-
- // Invoked with the response from the browser indicating whether it is
- // ok to shutdown the plugin process.
- static void ShutdownProcessResponse(bool ok_to_shutdown);
+ PluginProcess();
+ virtual ~PluginProcess();
// Invoked when the browser is shutdown. This ensures that the plugin
// process does not hang around waiting for future invocations
// from the browser.
- static void BrowserShutdown();
+ void Shutdown();
- // File path of the plugin this process hosts.
- const FilePath& plugin_path() { return plugin_path_; }
+ // Returns a pointer to the PluginProcess singleton instance.
+ static PluginProcess* current() {
+ return static_cast<PluginProcess*>(ChildProcess::current());
+ }
private:
- friend class PluginProcessFactory;
- PluginProcess(const std::wstring& channel_name,
- const FilePath& plugin_path);
- virtual ~PluginProcess();
virtual void OnFinalRelease();
- void Shutdown();
void OnProcessShutdownTimeout();
- const FilePath plugin_path_;
-
- // The thread where plugin instances live. Since NPAPI plugins weren't
- // created with multi-threading in mind, running multiple instances on
- // different threads would be asking for trouble.
- PluginThread plugin_thread_;
-
DISALLOW_EVIL_CONSTRUCTORS(PluginProcess);
};
diff --git a/chrome/plugin/plugin_thread.cc b/chrome/plugin/plugin_thread.cc
index d37edf4..671e977 100644
--- a/chrome/plugin/plugin_thread.cc
+++ b/chrome/plugin/plugin_thread.cc
@@ -7,84 +7,63 @@
#include "chrome/plugin/plugin_thread.h"
+#include "base/command_line.h"
#include "chrome/common/chrome_plugin_lib.h"
-#include "chrome/common/ipc_logging.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"
#include "chrome/plugin/npobject_util.h"
#include "chrome/plugin/plugin_process.h"
+#include "chrome/renderer/render_thread.h"
#include "net/base/net_errors.h"
#include "webkit/glue/plugins/plugin_lib.h"
#include "webkit/glue/webkit_glue.h"
-PluginThread* PluginThread::plugin_thread_;
-
-PluginThread::PluginThread(PluginProcess* process,
- const std::wstring& channel_name)
- : plugin_process_(process),
- channel_name_(channel_name),
- owner_loop_(MessageLoop::current()),
- preloaded_plugin_module_(NULL),
- Thread("Chrome_PluginThread") {
- DCHECK(plugin_process_);
- DCHECK(owner_loop_);
- DCHECK(!plugin_thread_);
- plugin_thread_ = this;
-
- // We need to run a UI message loop to support plugin execution.
- base::Thread::Options options;
- options.message_loop_type = MessageLoop::TYPE_UI;
- StartWithOptions(options);
+
+PluginThread::PluginThread()
+ : ChildThread(base::Thread::Options(MessageLoop::TYPE_UI, 0)),
+ preloaded_plugin_module_(NULL) {
+ plugin_path_ = FilePath::FromWStringHack(
+ CommandLine::ForCurrentProcess()->GetSwitchValue(switches::kPluginPath));
}
PluginThread::~PluginThread() {
- Stop();
- plugin_thread_ = NULL;
}
-void PluginThread::OnChannelError() {
- owner_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
+PluginThread* PluginThread::current() {
+ DCHECK(IsPluginProcess());
+ return static_cast<PluginThread*>(ChildThread::current());
}
-bool PluginThread::Send(IPC::Message* msg) {
- return channel_.get() ? channel_->Send(msg) : false;
-}
+void PluginThread::OnControlMessageReceived(const IPC::Message& msg) {
+ // Resource responses are sent to the resource dispatcher.
+ if (resource_dispatcher_->OnMessageReceived(msg))
+ return;
-void PluginThread::OnMessageReceived(const IPC::Message& msg) {
- if (msg.routing_id() == MSG_ROUTING_CONTROL) {
- // Resource responses are sent to the resource dispatcher.
- if (resource_dispatcher_->OnMessageReceived(msg))
- return;
- IPC_BEGIN_MESSAGE_MAP(PluginThread, msg)
- IPC_MESSAGE_HANDLER(PluginProcessMsg_CreateChannel, OnCreateChannel)
- IPC_MESSAGE_HANDLER(PluginProcessMsg_ShutdownResponse, OnShutdownResponse)
- IPC_MESSAGE_HANDLER(PluginProcessMsg_PluginMessage, OnPluginMessage)
- IPC_MESSAGE_HANDLER(PluginProcessMsg_BrowserShutdown, OnBrowserShutdown)
- IPC_END_MESSAGE_MAP()
- } else {
- NOTREACHED() << "Only control messages should reach PluginThread.";
- }
+ IPC_BEGIN_MESSAGE_MAP(PluginThread, msg)
+ IPC_MESSAGE_HANDLER(PluginProcessMsg_CreateChannel, OnCreateChannel)
+ IPC_MESSAGE_HANDLER(PluginProcessMsg_ShutdownResponse, OnShutdownResponse)
+ IPC_MESSAGE_HANDLER(PluginProcessMsg_PluginMessage, OnPluginMessage)
+ IPC_MESSAGE_HANDLER(PluginProcessMsg_BrowserShutdown, OnBrowserShutdown)
+ IPC_END_MESSAGE_MAP()
}
void PluginThread::Init() {
+ ChildThread::Init();
PatchNPNFunctions();
CoInitialize(NULL);
- channel_.reset(new IPC::SyncChannel(channel_name_,
- IPC::Channel::MODE_CLIENT, this, NULL, owner_loop_, true,
- PluginProcess::GetShutDownEvent()));
notification_service_.reset(new NotificationService);
resource_dispatcher_ = new ResourceDispatcher(this);
// Preload the library to avoid loading, unloading then reloading
- preloaded_plugin_module_ = NPAPI::PluginLib::LoadNativeLibrary(
- plugin_process_->plugin_path());
+ preloaded_plugin_module_ = NPAPI::PluginLib::LoadNativeLibrary(plugin_path_);
- ChromePluginLib::Create(plugin_process_->plugin_path(),
- GetCPBrowserFuncsForPlugin());
+ ChromePluginLib::Create(plugin_path_, GetCPBrowserFuncsForPlugin());
scoped_refptr<NPAPI::PluginLib> plugin =
- NPAPI::PluginLib::CreatePluginLib(plugin_process_->plugin_path());
+ NPAPI::PluginLib::CreatePluginLib(plugin_path_);
if (plugin.get()) {
plugin->NP_Initialize();
}
@@ -92,23 +71,14 @@ void PluginThread::Init() {
// Certain plugins, such as flash, steal the unhandled exception filter
// thus we never get crash reports when they fault. This call fixes it.
message_loop()->set_exception_restoration(true);
-
-#ifdef IPC_MESSAGE_LOG_ENABLED
- IPC::Logging::current()->SetIPCSender(this);
-#endif
}
void PluginThread::CleanUp() {
-#ifdef IPC_MESSAGE_LOG_ENABLED
- IPC::Logging::current()->SetIPCSender(NULL);
-#endif
+ ChildThread::CleanUp();
if (preloaded_plugin_module_) {
FreeLibrary(preloaded_plugin_module_);
preloaded_plugin_module_ = NULL;
}
- // Need to destruct the SyncChannel to the browser before we go away because
- // it caches a pointer to this thread.
- channel_.reset();
PluginChannelBase::CleanupChannels();
NPAPI::PluginLib::UnloadAllPlugins();
ChromePluginLib::UnloadAllPlugins();
@@ -118,13 +88,12 @@ void PluginThread::CleanUp() {
if (webkit_glue::ShouldForcefullyTerminatePluginProcess())
TerminateProcess(GetCurrentProcess(), 0);
-
}
-void PluginThread::OnCreateChannel(int process_id, HANDLE renderer_handle) {
+void PluginThread::OnCreateChannel(int process_id, HANDLE renderer) {
std::wstring channel_name;
scoped_refptr<PluginChannel> channel =
- PluginChannel::GetPluginChannel(process_id, renderer_handle, owner_loop_);
+ PluginChannel::GetPluginChannel(process_id, renderer, owner_loop());
if (channel.get())
channel_name = channel->channel_name();
@@ -132,32 +101,32 @@ void PluginThread::OnCreateChannel(int process_id, HANDLE renderer_handle) {
}
void PluginThread::OnShutdownResponse(bool ok_to_shutdown) {
- PluginProcess::ShutdownProcessResponse(ok_to_shutdown);
+ if (ok_to_shutdown)
+ PluginProcess::current()->Shutdown();
}
void PluginThread::OnBrowserShutdown() {
- PluginProcess::BrowserShutdown();
+ PluginProcess::current()->Shutdown();
}
void PluginThread::OnPluginMessage(const std::vector<unsigned char> &data) {
// We Add/Release ref here to ensure that something will trigger the
// shutdown mechanism for processes started in the absence of renderer's
// opening a plugin channel.
- PluginProcess::AddRefProcess();
- ChromePluginLib *chrome_plugin =
- ChromePluginLib::Find(plugin_process_->plugin_path());
+ PluginProcess::current()->AddRefProcess();
+ ChromePluginLib *chrome_plugin = ChromePluginLib::Find(plugin_path_);
if (chrome_plugin) {
void *data_ptr = const_cast<void*>(reinterpret_cast<const void*>(&data[0]));
uint32 data_len = static_cast<uint32>(data.size());
chrome_plugin->functions().on_message(data_ptr, data_len);
}
- PluginProcess::ReleaseProcess();
+ PluginProcess::current()->ReleaseProcess();
}
namespace webkit_glue {
bool DownloadUrl(const std::string& url, HWND caller_window) {
- PluginThread* plugin_thread = PluginThread::GetPluginThread();
+ PluginThread* plugin_thread = PluginThread::current();
if (!plugin_thread) {
return false;
}
@@ -175,10 +144,9 @@ bool GetPluginFinderURL(std::string* plugin_finder_url) {
return false;
}
- PluginThread* plugin_thread = PluginThread::GetPluginThread();
- if (!plugin_thread) {
+ PluginThread* plugin_thread = PluginThread::current();
+ if (!plugin_thread)
return false;
- }
plugin_thread->Send(
new PluginProcessHostMsg_GetPluginFinderUrl(plugin_finder_url));
@@ -190,36 +158,26 @@ bool IsDefaultPluginEnabled() {
return true;
}
-static int ResolveProxyFromPluginThread(const GURL& url,
- std::string* proxy_result) {
- int net_error;
- bool ipc_ok = PluginThread::GetPluginThread()->Send(
- new PluginProcessHostMsg_ResolveProxy(url, &net_error, proxy_result));
- return ipc_ok ? net_error : net::ERR_UNEXPECTED;
-}
-
-extern int ResolveProxyFromRenderThread(const GURL&, std::string*);
// Dispatch the resolve proxy resquest to the right code, depending on which
// process the plugin is running in {renderer, browser, plugin}.
-//
-// TODO(eroman): Find a better place to put this; plugin_thread.cc isn't really
-// correct since this depends on the renderer thread. One solution is to save
-// the function pointers into a table during initialization.
bool FindProxyForUrl(const GURL& url, std::string* proxy_list) {
int net_error;
std::string proxy_result;
- if (PluginThread::GetPluginThread())
- net_error = ResolveProxyFromPluginThread(url, &proxy_result);
- else
- net_error = ResolveProxyFromRenderThread(url, &proxy_result);
-
- if (net_error == net::OK) {
- *proxy_list = proxy_result;
- return true; // Success.
+ bool result;
+ if (IsPluginProcess()) {
+ result = PluginThread::current()->Send(
+ new PluginProcessHostMsg_ResolveProxy(url, &net_error, &proxy_result));
+ } else {
+ result = RenderThread::current()->Send(
+ new ViewHostMsg_ResolveProxy(url, &net_error, &proxy_result));
}
- return false; // Fail.
+
+ if (!result || net_error != net::OK)
+ return false;
+
+ *proxy_list = proxy_result;
+ return true;
}
} // namespace webkit_glue
-
diff --git a/chrome/plugin/plugin_thread.h b/chrome/plugin/plugin_thread.h
index 46da0e4..38b989e 100644
--- a/chrome/plugin/plugin_thread.h
+++ b/chrome/plugin/plugin_thread.h
@@ -5,59 +5,39 @@
#ifndef CHROME_PLUGIN_PLUGIN_THREAD_H_
#define CHROME_PLUGIN_PLUGIN_THREAD_H_
-#include "base/thread.h"
-#include "chrome/common/ipc_sync_channel.h"
-#include "chrome/common/message_router.h"
+#include "base/file_path.h"
+#include "chrome/common/child_thread.h"
#include "chrome/common/resource_dispatcher.h"
#include "chrome/plugin/plugin_channel.h"
-class PluginProcess;
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.
-class PluginThread : public IPC::Channel::Listener,
- public IPC::Message::Sender,
- public base::Thread {
+class PluginThread : public ChildThread {
public:
- PluginThread(PluginProcess *process, const std::wstring& channel_name);
+ PluginThread();
~PluginThread();
- // IPC::Channel::Listener implementation:
- virtual void OnMessageReceived(const IPC::Message& msg);
- virtual void OnChannelError();
-
- // IPC::Message::Sender implementation:
- virtual bool Send(IPC::Message* msg);
-
// Returns the one plugin thread.
- static PluginThread* GetPluginThread() { return plugin_thread_; }
+ static PluginThread* current();
// Returns the one true dispatcher.
- ResourceDispatcher* resource_dispatcher() {
- return resource_dispatcher_.get();
- }
+ ResourceDispatcher* resource_dispatcher() { return resource_dispatcher_.get(); }
private:
- // Thread implementation:
- void Init();
- void CleanUp();
+ virtual void OnControlMessageReceived(const IPC::Message& msg);
+
+ // Thread implementation:
+ virtual void Init();
+ virtual void CleanUp();
- void OnCreateChannel(int process_id, HANDLE renderer_handle);
+ void OnCreateChannel(int process_id, HANDLE renderer);
void OnShutdownResponse(bool ok_to_shutdown);
void OnPluginMessage(const std::vector<uint8> &data);
void OnBrowserShutdown();
- // The process that has created this thread
- PluginProcess *plugin_process_;
-
- // The message loop used to run tasks on the thread that started this thread.
- MessageLoop* owner_loop_;
-
- std::wstring channel_name_;
- scoped_ptr<IPC::SyncChannel> channel_;
-
scoped_ptr<NotificationService> notification_service_;
// Handles resource loads for this view.
@@ -67,8 +47,8 @@ class PluginThread : public IPC::Channel::Listener,
// The plugin module which is preloaded in Init
HMODULE preloaded_plugin_module_;
- // Points to the one PluginThread object in the process.
- static PluginThread* plugin_thread_;
+ // Points to the plugin file that this process hosts.
+ FilePath plugin_path_;
DISALLOW_EVIL_CONSTRUCTORS(PluginThread);
};
diff --git a/chrome/plugin/webplugin_proxy.cc b/chrome/plugin/webplugin_proxy.cc
index 448064a..478300a 100644
--- a/chrome/plugin/webplugin_proxy.cc
+++ b/chrome/plugin/webplugin_proxy.cc
@@ -58,7 +58,7 @@ WebPluginProxy::~WebPluginProxy() {
GetContextMap().erase(cp_browsing_context_);
if (parent_window_) {
- PluginThread::GetPluginThread()->Send(
+ PluginThread::current()->Send(
new PluginProcessHostMsg_DestroyWindow(parent_window_));
}
}
@@ -90,7 +90,7 @@ void WebPluginProxy::SetWindow(HWND window, HANDLE pump_messages_event) {
// the browser paints or sends any other (synchronous) WM_ message to the
// plugin window.
msg->EnableMessagePumping();
- PluginThread::GetPluginThread()->Send(msg);
+ PluginThread::current()->Send(msg);
SetParent(window, parent_window_);
diff --git a/chrome/renderer/chrome_plugin_host.cc b/chrome/renderer/chrome_plugin_host.cc
index 6f793b7..9d437c0 100644
--- a/chrome/renderer/chrome_plugin_host.cc
+++ b/chrome/renderer/chrome_plugin_host.cc
@@ -320,7 +320,7 @@ int STDCALL CPB_GetBrowsingContextInfo(
return sizeof(char*);
std::wstring wretval;
- if (!g_render_thread->Send(new ViewHostMsg_GetDataDir(&wretval)))
+ if (!RenderThread::current()->Send(new ViewHostMsg_GetDataDir(&wretval)))
return CPERR_FAILURE;
file_util::AppendToPath(&wretval, chrome::kChromePluginDataDirname);
*static_cast<char**>(buf) = CPB_StringDup(CPB_Alloc, WideToUTF8(wretval));
@@ -491,8 +491,8 @@ CPError STDCALL CPB_SendMessage(CPID id, const void *data, uint32 data_len) {
const uint8* data_ptr = static_cast<const uint8*>(data);
std::vector<uint8> v(data_ptr, data_ptr + data_len);
- if (!g_render_thread->Send(new ViewHostMsg_PluginMessage(plugin->filename(),
- v))) {
+ if (!RenderThread::current()->Send(
+ new ViewHostMsg_PluginMessage(plugin->filename(), v))) {
return CPERR_FAILURE;
}
return CPERR_SUCCESS;
@@ -507,7 +507,7 @@ CPError STDCALL CPB_SendSyncMessage(CPID id, const void *data, uint32 data_len,
const uint8* data_ptr = static_cast<const uint8*>(data);
std::vector<uint8> v(data_ptr, data_ptr + data_len);
std::vector<uint8> r;
- if (!g_render_thread->Send(new ViewHostMsg_PluginSyncMessage(
+ if (!RenderThread::current()->Send(new ViewHostMsg_PluginSyncMessage(
plugin->filename(), v, &r))) {
return CPERR_FAILURE;
}
diff --git a/chrome/renderer/mock_render_process.h b/chrome/renderer/mock_render_process.h
index d7bd178..629967f 100644
--- a/chrome/renderer/mock_render_process.h
+++ b/chrome/renderer/mock_render_process.h
@@ -5,21 +5,17 @@
#ifndef CHROME_RENDERER_MOCK_RENDER_PROCESS_H_
#define CHROME_RENDERER_MOCK_RENDER_PROCESS_H_
-#include <string>
-
#include "chrome/common/child_process.h"
+class ChildThread;
+
// This class is a trivial mock of the child process singleton. It is necessary
// so we don't trip DCHECKs in ChildProcess::ReleaseProcess() when destroying
// a render widget instance.
class MockProcess : public ChildProcess {
public:
- explicit MockProcess(const std::wstring& channel_name) {}
- static void GlobalInit() {
- ChildProcessFactory<MockProcess> factory;
- ChildProcess::GlobalInit(L"dummy", &factory);
- }
+ explicit MockProcess() : ChildProcess(NULL) {}
+ explicit MockProcess(ChildThread* thread) : ChildProcess(thread) {}
};
#endif // CHROME_RENDERER_MOCK_RENDER_PROCESS_H_
-
diff --git a/chrome/renderer/net/render_dns_master.cc b/chrome/renderer/net/render_dns_master.cc
index beacec6..b62b6ca 100644
--- a/chrome/renderer/net/render_dns_master.cc
+++ b/chrome/renderer/net/render_dns_master.cc
@@ -19,7 +19,7 @@
// This API is used in the render process by renderer_glue.cc.
// IF you are in the render process, you MUST be on the renderer thread to call.
void DnsPrefetchCString(const char* hostname, size_t length) {
- g_render_thread->Resolve(hostname, length);
+ RenderThread::current()->Resolve(hostname, length);
}
// The number of hostnames submitted to Browser DNS resolver per call to
@@ -55,7 +55,7 @@ void RenderDnsMaster::Resolve(const char* name, size_t length) {
if (0 != old_size)
return; // Overkill safety net: Don't send too many InvokeLater's.
render_dns_factory_.RevokeAll();
- g_render_thread->message_loop()->PostDelayedTask(FROM_HERE,
+ RenderThread::current()->message_loop()->PostDelayedTask(FROM_HERE,
render_dns_factory_.NewRunnableMethod(
&RenderDnsMaster::SubmitHostnames), 10);
}
@@ -89,7 +89,7 @@ void RenderDnsMaster::SubmitHostnames() {
DnsPrefetchNames(kMAX_SUBMISSION_PER_TASK);
if (new_name_count_ > 0 || 0 < c_string_queue_.Size()) {
render_dns_factory_.RevokeAll();
- g_render_thread->message_loop()->PostDelayedTask(FROM_HERE,
+ RenderThread::current()->message_loop()->PostDelayedTask(FROM_HERE,
render_dns_factory_.NewRunnableMethod(
&RenderDnsMaster::SubmitHostnames), 10);
} else {
@@ -145,7 +145,7 @@ void RenderDnsMaster::DnsPrefetchNames(size_t max_count) {
new_name_count_ -= names.size();
DCHECK(new_name_count_ >= 0);
- g_render_thread->Send(new ViewHostMsg_DnsPrefetch(names));
+ RenderThread::current()->Send(new ViewHostMsg_DnsPrefetch(names));
}
// is_numeric_ip() checks to see if all characters in name are either numeric,
diff --git a/chrome/renderer/render_process.cc b/chrome/renderer/render_process.cc
index 198f854f..ff1cd33 100644
--- a/chrome/renderer/render_process.cc
+++ b/chrome/renderer/render_process.cc
@@ -29,34 +29,48 @@
#include "chrome/renderer/render_view.h"
#include "webkit/glue/webkit_glue.h"
-//-----------------------------------------------------------------------------
-bool RenderProcess::load_plugins_in_process_ = false;
-
-//-----------------------------------------------------------------------------
+RenderProcess::RenderProcess()
+ : 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::wstring& channel_name)
- : render_thread_(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) {
- for (size_t i = 0; i < arraysize(shared_mem_cache_); ++i)
- shared_mem_cache_[i] = NULL;
+ 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
+
// 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.
- render_thread_.Stop();
+ child_thread()->Stop();
ClearTransportDIBCache();
}
-// static
-bool RenderProcess::GlobalInit(const std::wstring &channel_name) {
+void RenderProcess::Init() {
+ in_process_plugins_ = InProcessPlugins();
+ in_process_gears_ = false;
+ for (size_t i = 0; i < arraysize(shared_mem_cache_); ++i)
+ shared_mem_cache_[i] = NULL;
+
#if defined(OS_WIN)
// HACK: See http://b/issue?id=1024307 for rationale.
if (GetModuleHandle(L"LPK.DLL") == NULL) {
@@ -84,10 +98,6 @@ bool RenderProcess::GlobalInit(const std::wstring &channel_name) {
webkit_glue::SetRecordPlaybackMode(true);
}
- if (command_line.HasSwitch(switches::kInProcessPlugins) ||
- command_line.HasSwitch(switches::kSingleProcess))
- load_plugins_in_process_ = true;
-
if (command_line.HasSwitch(switches::kEnableWatchdog)) {
// TODO(JAR): Need to implement renderer IO msgloop watchdog.
}
@@ -98,6 +108,7 @@ bool RenderProcess::GlobalInit(const std::wstring &channel_name) {
if (command_line.HasSwitch(switches::kGearsInRenderer)) {
#if defined(OS_WIN)
+ in_process_gears_ = true;
// Load gears.dll on startup so we can access it before the sandbox
// blocks us.
std::wstring path;
@@ -113,19 +124,12 @@ bool RenderProcess::GlobalInit(const std::wstring &channel_name) {
// TODO(scherkus): check for any DLL dependencies.
webkit_glue::SetMediaPlayerAvailable(true);
}
-
- ChildProcessFactory<RenderProcess> factory;
- return ChildProcess::GlobalInit(channel_name, &factory);
-}
-
-// static
-void RenderProcess::GlobalCleanup() {
- ChildProcess::GlobalCleanup();
}
-// static
-bool RenderProcess::ShouldLoadPluginsInProcess() {
- return load_plugins_in_process_;
+bool RenderProcess::InProcessPlugins() {
+ const CommandLine& command_line = *CommandLine::ForCurrentProcess();
+ return command_line.HasSwitch(switches::kInProcessPlugins) ||
+ command_line.HasSwitch(switches::kSingleProcess);
}
// -----------------------------------------------------------------------------
@@ -155,7 +159,7 @@ TransportDIB* RenderProcess::CreateTransportDIB(size_t size) {
// get one.
IPC::Maybe<TransportDIB::Handle> mhandle;
IPC::Message* msg = new ViewHostMsg_AllocTransportDIB(size, &mhandle);
- if (!render_thread_.Send(msg))
+ if (!child_thread()->Send(msg))
return NULL;
if (!mhandle.valid)
return NULL;
@@ -171,7 +175,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());
- render_thread_.Send(msg);
+ child_thread()->Send(msg);
#endif
delete dib;
@@ -180,14 +184,13 @@ void RenderProcess::FreeTransportDIB(TransportDIB* dib) {
// -----------------------------------------------------------------------------
-// static
skia::PlatformCanvas* RenderProcess::GetDrawingCanvas(
TransportDIB** memory, const gfx::Rect& rect) {
const size_t stride = skia::PlatformCanvas::StrideForWidth(rect.width());
const size_t size = stride * rect.height();
- if (!self()->GetTransportDIBFromCache(memory, size)) {
- *memory = self()->CreateTransportDIB(size);
+ if (!GetTransportDIBFromCache(memory, size)) {
+ *memory = CreateTransportDIB(size);
if (!*memory)
return false;
}
@@ -195,14 +198,13 @@ skia::PlatformCanvas* RenderProcess::GetDrawingCanvas(
return CanvasFromTransportDIB(*memory, rect);
}
-// static
void RenderProcess::ReleaseTransportDIB(TransportDIB* mem) {
- if (self()->PutSharedMemInCache(mem)) {
- self()->shared_mem_cache_cleaner_.Reset();
+ if (PutSharedMemInCache(mem)) {
+ shared_mem_cache_cleaner_.Reset();
return;
}
- self()->FreeTransportDIB(mem);
+ FreeTransportDIB(mem);
}
bool RenderProcess::GetTransportDIBFromCache(TransportDIB** mem,
@@ -266,11 +268,3 @@ void RenderProcess::ClearTransportDIBCache() {
}
}
-void RenderProcess::Cleanup() {
- // 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
-}
diff --git a/chrome/renderer/render_process.h b/chrome/renderer/render_process.h
index 9c4cabe..a4bc0ff5 100644
--- a/chrome/renderer/render_process.h
+++ b/chrome/renderer/render_process.h
@@ -21,11 +21,12 @@ class TransportDIB;
// each renderer.
class RenderProcess : public ChildProcess {
public:
- static bool GlobalInit(const std::wstring& channel_name);
- static void GlobalCleanup();
+ // This constructor grabs the channel name from the command line arguments.
+ RenderProcess();
+ // This constructor uses the given channel name.
+ RenderProcess(const std::wstring& channel_name);
- // Returns true if plugins should be loaded in-process.
- static bool ShouldLoadPluginsInProcess();
+ ~RenderProcess();
// Get a canvas suitable for drawing and transporting to the browser
// memory: (output) the transport DIB memory
@@ -34,25 +35,31 @@ class RenderProcess : public ChildProcess {
//
// When no longer needed, you should pass the TransportDIB to
// ReleaseTransportDIB so that it can be recycled.
- static skia::PlatformCanvas* GetDrawingCanvas(
+ skia::PlatformCanvas* GetDrawingCanvas(
TransportDIB** memory, const gfx::Rect& rect);
// Frees shared memory allocated by AllocSharedMemory. You should only use
// this function to free the SharedMemory object.
- static void ReleaseTransportDIB(TransportDIB* memory);
+ void ReleaseTransportDIB(TransportDIB* memory);
- private:
- friend class ChildProcessFactory<RenderProcess>;
- explicit RenderProcess(const std::wstring& channel_name);
- ~RenderProcess();
+ // Returns true if plugins should be loaded in-process.
+ bool in_process_plugins() const { return in_process_plugins_; }
- // Returns a pointer to the RenderProcess singleton instance. This is
- // guaranteed to be non-NULL between calls to GlobalInit and GlobalCleanup.
- static RenderProcess* self() {
- return static_cast<RenderProcess*>(child_process_);
+ // Returns true if Gears should be loaded in-process.
+ bool in_process_gears() const { return in_process_gears_; }
+
+ // Returns a pointer to the RenderProcess singleton instance.
+ static RenderProcess* current() {
+ return static_cast<RenderProcess*>(ChildProcess::current());
}
- static ChildProcess* ClassFactory(const std::wstring& channel_name);
+ 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
@@ -77,12 +84,6 @@ class RenderProcess : public ChildProcess {
TransportDIB* CreateTransportDIB(size_t size);
void FreeTransportDIB(TransportDIB*);
- // ChildProcess implementation
- virtual void Cleanup();
-
- // The one render thread (to be replaced with a set of render threads).
- RenderThread render_thread_;
-
// A very simplistic and small cache. If an entry in this array is non-null,
// then it points to a SharedMemory object that is available for reuse.
TransportDIB* shared_mem_cache_[2];
@@ -93,7 +94,8 @@ class RenderProcess : public ChildProcess {
// TransportDIB sequence number
uint32 sequence_number_;
- static bool load_plugins_in_process_;
+ bool in_process_plugins_;
+ bool in_process_gears_;
DISALLOW_COPY_AND_ASSIGN(RenderProcess);
};
diff --git a/chrome/renderer/render_process_unittest.cc b/chrome/renderer/render_process_unittest.cc
index 4f77d5d..7859d8f 100644
--- a/chrome/renderer/render_process_unittest.cc
+++ b/chrome/renderer/render_process_unittest.cc
@@ -13,15 +13,16 @@ namespace {
class RenderProcessTest : public testing::Test {
public:
virtual void SetUp() {
- RenderProcess::GlobalInit(L"render_process_unittest");
+ render_process_.reset(new RenderProcess(L"render_process_unittest"));
}
virtual void TearDown() {
- RenderProcess::GlobalCleanup();
+ render_process_.reset();
}
private:
MessageLoopForIO message_loop_;
+ scoped_ptr<RenderProcess> render_process_;
};
@@ -30,10 +31,10 @@ TEST_F(RenderProcessTest, TestTransportDIBAllocation) {
#if !defined(OS_MACOSX)
const gfx::Rect rect(0, 0, 100, 100);
TransportDIB* dib;
- skia::PlatformCanvas* canvas = RenderProcess::GetDrawingCanvas(&dib, rect);
+ skia::PlatformCanvas* canvas = RenderProcess::current()->GetDrawingCanvas(&dib, rect);
ASSERT_TRUE(dib);
ASSERT_TRUE(canvas);
- RenderProcess::ReleaseTransportDIB(dib);
+ RenderProcess::current()->ReleaseTransportDIB(dib);
delete canvas;
#endif
}
diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc
index 2937935..58de4ef 100644
--- a/chrome/renderer/render_thread.cc
+++ b/chrome/renderer/render_thread.cc
@@ -14,9 +14,9 @@
#include "base/shared_memory.h"
#include "chrome/common/chrome_plugin_lib.h"
-#include "chrome/common/ipc_logging.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/notification_service.h"
+#include "chrome/plugin/npobject_util.h"
// TODO(port)
#if defined(OS_WIN)
#include "chrome/plugin/plugin_channel.h"
@@ -34,8 +34,6 @@
#include "webkit/glue/cache_manager.h"
-RenderThread* g_render_thread;
-
static const unsigned int kCacheStatsDelayMS = 2000 /* milliseconds */;
// V8 needs a 1MB stack size.
@@ -44,78 +42,53 @@ static const size_t kStackSize = 1024 * 1024;
//-----------------------------------------------------------------------------
// Methods below are only called on the owner's thread:
-RenderThread::RenderThread(const std::wstring& channel_name)
- : Thread("Chrome_RenderThread"),
- owner_loop_(MessageLoop::current()),
- channel_name_(channel_name),
+// 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, kStackSize)),
visited_link_slave_(NULL),
user_script_slave_(NULL),
- render_dns_master_(NULL),
- in_send_(0) {
- DCHECK(owner_loop_);
- base::Thread::Options options;
- options.stack_size = kStackSize;
- // 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.
- if (RenderProcess::ShouldLoadPluginsInProcess())
- options.message_loop_type = MessageLoop::TYPE_UI;
- StartWithOptions(options);
+ render_dns_master_(NULL) {
}
-RenderThread::~RenderThread() {
- Stop();
+RenderThread::RenderThread(const std::wstring& channel_name)
+ : ChildThread(
+ base::Thread::Options(RenderProcess::InProcessPlugins() ?
+ MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT, kStackSize)),
+ visited_link_slave_(NULL),
+ user_script_slave_(NULL),
+ render_dns_master_(NULL) {
+ SetChannelName(channel_name);
}
-void RenderThread::OnChannelError() {
- owner_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
+RenderThread::~RenderThread() {
}
-bool RenderThread::Send(IPC::Message* msg) {
- in_send_++;
- bool rv = channel_->Send(msg);
- in_send_--;
- return rv;
+RenderThread* RenderThread::current() {
+ DCHECK(!IsPluginProcess());
+ return static_cast<RenderThread*>(ChildThread::current());
}
void RenderThread::AddFilter(IPC::ChannelProxy::MessageFilter* filter) {
- channel_->AddFilter(filter);
+ channel()->AddFilter(filter);
}
void RenderThread::RemoveFilter(IPC::ChannelProxy::MessageFilter* filter) {
- channel_->RemoveFilter(filter);
+ channel()->RemoveFilter(filter);
}
void RenderThread::Resolve(const char* name, size_t length) {
return render_dns_master_->Resolve(name, length);
}
-void RenderThread::AddRoute(int32 routing_id,
- IPC::Channel::Listener* listener) {
- DCHECK(MessageLoop::current() == message_loop());
-
- // This corresponds to the AddRoute call done in CreateView.
- router_.AddRoute(routing_id, listener);
-}
-
-void RenderThread::RemoveRoute(int32 routing_id) {
- DCHECK(MessageLoop::current() == message_loop());
-
- router_.RemoveRoute(routing_id);
-}
-
void RenderThread::Init() {
- DCHECK(!g_render_thread);
- g_render_thread = this;
-
+ ChildThread::Init();
notification_service_.reset(new NotificationService);
-
cache_stats_factory_.reset(
new ScopedRunnableMethodFactory<RenderThread>(this));
- channel_.reset(new IPC::SyncChannel(channel_name_,
- IPC::Channel::MODE_CLIENT, this, NULL, owner_loop_, true,
- RenderProcess::GetShutDownEvent()));
-
#if defined(OS_WIN)
// The renderer thread should wind-up COM.
CoInitialize(0);
@@ -124,19 +97,10 @@ void RenderThread::Init() {
visited_link_slave_ = new VisitedLinkSlave();
user_script_slave_ = new UserScriptSlave();
render_dns_master_.reset(new RenderDnsMaster());
-
-#ifdef IPC_MESSAGE_LOG_ENABLED
- IPC::Logging::current()->SetIPCSender(this);
-#endif
}
void RenderThread::CleanUp() {
- DCHECK(g_render_thread == this);
- g_render_thread = NULL;
-
- // Need to destruct the SyncChannel to the browser before we go away because
- // it caches a pointer to this thread.
- channel_.reset();
+ ChildThread::CleanUp();
// TODO(port)
#if defined(OS_WIN)
@@ -144,10 +108,6 @@ void RenderThread::CleanUp() {
PluginChannelBase::CleanupChannels();
#endif
-#ifdef IPC_MESSAGE_LOG_ENABLED
- IPC::Logging::current()->SetIPCSender(NULL);
-#endif
-
notification_service_.reset();
delete visited_link_slave_;
@@ -172,30 +132,20 @@ void RenderThread::OnUpdateUserScripts(
user_script_slave_->UpdateScripts(scripts);
}
-void RenderThread::OnMessageReceived(const IPC::Message& msg) {
- // NOTE: We could subclass router_ to intercept OnControlMessageReceived, but
- // it seems simpler to just process any control messages that we care about
- // up-front and then send the rest of the messages onto router_.
-
- if (msg.routing_id() == MSG_ROUTING_CONTROL) {
- IPC_BEGIN_MESSAGE_MAP(RenderThread, msg)
- IPC_MESSAGE_HANDLER(ViewMsg_VisitedLink_NewTable, OnUpdateVisitedLinks)
- IPC_MESSAGE_HANDLER(ViewMsg_SetNextPageID, OnSetNextPageID)
- // TODO(port): removed from render_messages_internal.h;
- // is there a new non-windows message I should add here?
- IPC_MESSAGE_HANDLER(ViewMsg_New, OnCreateNewView)
- IPC_MESSAGE_HANDLER(ViewMsg_SetCacheCapacities, OnSetCacheCapacities)
- IPC_MESSAGE_HANDLER(ViewMsg_GetCacheResourceStats,
- OnGetCacheResourceStats)
- IPC_MESSAGE_HANDLER(ViewMsg_PluginMessage, OnPluginMessage)
- IPC_MESSAGE_HANDLER(ViewMsg_UserScripts_NewScripts,
- OnUpdateUserScripts)
- // send the rest to the router
- IPC_MESSAGE_UNHANDLED(router_.OnMessageReceived(msg))
- IPC_END_MESSAGE_MAP()
- } else {
- router_.OnMessageReceived(msg);
- }
+void RenderThread::OnControlMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(RenderThread, msg)
+ IPC_MESSAGE_HANDLER(ViewMsg_VisitedLink_NewTable, OnUpdateVisitedLinks)
+ IPC_MESSAGE_HANDLER(ViewMsg_SetNextPageID, OnSetNextPageID)
+ // TODO(port): removed from render_messages_internal.h;
+ // is there a new non-windows message I should add here?
+ IPC_MESSAGE_HANDLER(ViewMsg_New, OnCreateNewView)
+ IPC_MESSAGE_HANDLER(ViewMsg_SetCacheCapacities, OnSetCacheCapacities)
+ IPC_MESSAGE_HANDLER(ViewMsg_GetCacheResourceStats,
+ OnGetCacheResourceStats)
+ IPC_MESSAGE_HANDLER(ViewMsg_PluginMessage, OnPluginMessage)
+ IPC_MESSAGE_HANDLER(ViewMsg_UserScripts_NewScripts,
+ OnUpdateUserScripts)
+ IPC_END_MESSAGE_MAP()
}
void RenderThread::OnPluginMessage(const FilePath& plugin_path,
diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h
index 44dd548..a3bd534 100644
--- a/chrome/renderer/render_thread.h
+++ b/chrome/renderer/render_thread.h
@@ -10,10 +10,8 @@
#include "base/gfx/native_widget_types.h"
#include "base/shared_memory.h"
#include "base/task.h"
-#include "base/thread.h"
#include "build/build_config.h"
-#include "chrome/common/ipc_sync_channel.h"
-#include "chrome/common/message_router.h"
+#include "chrome/common/child_thread.h"
class FilePath;
class NotificationService;
@@ -27,10 +25,12 @@ struct WebPreferences;
// The RenderThreadBase is the minimal interface that a RenderView/Widget
// expects from a render thread. The interface basically abstracts a way to send
// and receive messages.
-class RenderThreadBase : public IPC::Message::Sender {
+class RenderThreadBase {
public:
virtual ~RenderThreadBase() {}
+ virtual bool Send(IPC::Message* msg) = 0;
+
// True if currently sending a message.
virtual bool InSend() const = 0;
@@ -52,21 +52,35 @@ class RenderThreadBase : public IPC::Message::Sender {
// Most of the communication occurs in the form of IPC messages. They are
// routed to the RenderThread according to the routing IDs of the messages.
// The routing IDs correspond to RenderView instances.
-class RenderThread : public IPC::Channel::Listener,
- public RenderThreadBase,
- public base::Thread {
+class RenderThread : public RenderThreadBase,
+ public ChildThread {
public:
- explicit RenderThread(const std::wstring& channel_name);
+ // Grabs the IPC channel name from the command line.
+ RenderThread();
+ // Constructor that's used when running in single process mode.
+ RenderThread(const std::wstring& channel_name);
virtual ~RenderThread();
- // IPC::Channel::Listener implementation:
- virtual void OnMessageReceived(const IPC::Message& msg);
- virtual void OnChannelError();
-
- // IPC::Message::Sender implementation:
- virtual bool Send(IPC::Message* msg);
+ // Returns the one render thread for this process. Note that this should only
+ // be accessed when running on the render thread itself
+ static RenderThread* current();
// Overridded from RenderThreadBase.
+ virtual bool Send(IPC::Message* msg) {
+ return ChildThread::Send(msg);
+ }
+
+ virtual bool InSend() const {
+ return ChildThread::InSend();
+ }
+
+ virtual void AddRoute(int32 routing_id, IPC::Channel::Listener* listener) {
+ return ChildThread::AddRoute(routing_id, listener);
+ }
+ virtual void RemoveRoute(int32 routing_id) {
+ return ChildThread::RemoveRoute(routing_id);
+ }
+
virtual void AddFilter(IPC::ChannelProxy::MessageFilter* filter);
virtual void RemoveFilter(IPC::ChannelProxy::MessageFilter* filter);
@@ -79,25 +93,17 @@ class RenderThread : public IPC::Channel::Listener,
// Do DNS prefetch resolution of a hostname.
void Resolve(const char* name, size_t length);
- // See documentation on MessageRouter for AddRoute and RemoveRoute
- virtual void AddRoute(int32 routing_id, IPC::Channel::Listener* listener);
- virtual void RemoveRoute(int32 routing_id);
-
// Invokes InformHostOfCacheStats after a short delay. Used to move this
// bookkeeping operation off the critical latency path.
void InformHostOfCacheStatsLater();
- MessageLoop* owner_loop() { return owner_loop_; }
-
- // Indicates if RenderThread::Send() is on the call stack.
- virtual bool InSend() const { return in_send_ != 0; }
+ private:
+ virtual void OnControlMessageReceived(const IPC::Message& msg);
- protected:
// Called by the thread base class
virtual void Init();
virtual void CleanUp();
- private:
void OnUpdateVisitedLinks(base::SharedMemoryHandle table);
void OnUpdateUserScripts(base::SharedMemoryHandle table);
@@ -119,16 +125,6 @@ class RenderThread : public IPC::Channel::Listener,
// decisions about how to allocation resources using current information.
void InformHostOfCacheStats();
- // The message loop used to run tasks on the thread that started this thread.
- MessageLoop* owner_loop_;
-
- // Used only on the background render thread to implement message routing
- // functionality to the consumers of the RenderThread.
- MessageRouter router_;
-
- std::wstring channel_name_;
- scoped_ptr<IPC::SyncChannel> channel_;
-
// These objects live solely on the render thread.
VisitedLinkSlave* visited_link_slave_;
UserScriptSlave* user_script_slave_;
@@ -139,13 +135,7 @@ class RenderThread : public IPC::Channel::Listener,
scoped_ptr<NotificationService> notification_service_;
- int in_send_;
-
DISALLOW_COPY_AND_ASSIGN(RenderThread);
};
-// The global RenderThread object for this process. Note that this should only
-// be accessed when running on the render thread itself.
-extern RenderThread* g_render_thread;
-
#endif // CHROME_RENDERER_RENDER_THREAD_H_
diff --git a/chrome/renderer/render_thread_unittest.cc b/chrome/renderer/render_thread_unittest.cc
index 12e6941..4192f68 100644
--- a/chrome/renderer/render_thread_unittest.cc
+++ b/chrome/renderer/render_thread_unittest.cc
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/string_util.h"
#include "base/waitable_event.h"
#include "chrome/common/ipc_sync_channel.h"
#include "chrome/common/render_messages.h"
@@ -12,39 +11,33 @@
namespace {
-const char kThreadName[] = "render_thread_unittest";
+const wchar_t kThreadName[] = L"render_thread_unittest";
class RenderThreadTest : public testing::Test {
public:
virtual void SetUp() {
- MockProcess::GlobalInit();
+ mock_process_.reset(new MockProcess(new RenderThread(kThreadName)));
// Need a MODE_SERVER to make MODE_CLIENTs (like a RenderThread) happy.
- channel_ = new IPC::Channel(ASCIIToWide(kThreadName),
- IPC::Channel::MODE_SERVER, NULL);
+ channel_ = new IPC::Channel(kThreadName, IPC::Channel::MODE_SERVER, NULL);
}
virtual void TearDown() {
message_loop_.RunAllPending();
delete channel_;
- MockProcess::GlobalCleanup();
+ mock_process_.reset();
}
- private:
+ protected:
MessageLoopForIO message_loop_;
+ scoped_ptr<MockProcess> mock_process_;
IPC::Channel *channel_;
};
TEST_F(RenderThreadTest, TestGlobal) {
- ASSERT_FALSE(g_render_thread);
- {
- RenderThread thread(ASCIIToWide(kThreadName));
- ASSERT_TRUE(g_render_thread);
- }
- ASSERT_FALSE(g_render_thread);
+ ASSERT_TRUE(RenderThread::current());
}
TEST_F(RenderThreadTest, TestVisitedMsg) {
- RenderThread thread(ASCIIToWide(kThreadName));
#if defined(OS_WIN)
IPC::Message* msg = new ViewMsg_VisitedLink_NewTable(NULL);
#elif defined(OS_POSIX)
@@ -54,7 +47,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.
- 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 9528187..d87b327 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -1461,8 +1461,8 @@ void RenderView::DidFinishDocumentLoadForFrame(WebView* webview,
// Check whether we have new encoding name.
UpdateEncoding(frame, webview->GetMainFrameEncodingName());
- if (g_render_thread) // Will be NULL during unit tests.
- g_render_thread->user_script_slave()->InjectScripts(
+ if (RenderThread::current()) // Will be NULL during unit tests.
+ RenderThread::current()->user_script_slave()->InjectScripts(
frame, UserScript::DOCUMENT_END);
}
@@ -1532,8 +1532,8 @@ void RenderView::WindowObjectCleared(WebFrame* webframe) {
}
void RenderView::DocumentElementAvailable(WebFrame* frame) {
- if (g_render_thread) // Will be NULL during unit tests.
- g_render_thread->user_script_slave()->InjectScripts(
+ if (RenderThread::current()) // Will be NULL during unit tests.
+ RenderThread::current()->user_script_slave()->InjectScripts(
frame, UserScript::DOCUMENT_START);
}
@@ -1863,13 +1863,12 @@ WebWidget* RenderView::CreatePopupWidget(WebView* webview,
static bool ShouldLoadPluginInProcess(const std::string& mime_type,
bool* is_gears) {
- if (RenderProcess::ShouldLoadPluginsInProcess())
+ if (RenderProcess::current()->in_process_plugins())
return true;
if (mime_type == "application/x-googlegears") {
*is_gears = true;
- return CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kGearsInRenderer);
+ return RenderProcess::current()->in_process_gears();
}
return false;
@@ -2866,8 +2865,8 @@ std::string RenderView::GetAltHTMLForTemplate(
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 (g_render_thread)
- return g_render_thread->owner_loop();
+ if (RenderThread::current())
+ return RenderThread::current()->owner_loop();
return NULL;
}
diff --git a/chrome/renderer/render_view_unittest.cc b/chrome/renderer/render_view_unittest.cc
index 82aff43..5443c73 100644
--- a/chrome/renderer/render_view_unittest.cc
+++ b/chrome/renderer/render_view_unittest.cc
@@ -60,7 +60,7 @@ class RenderViewTest : public testing::Test {
// testing::Test
virtual void SetUp() {
- MockProcess::GlobalInit();
+ mock_process_.reset(new MockProcess());
render_thread_.set_routing_id(kRouteId);
@@ -77,15 +77,12 @@ class RenderViewTest : public testing::Test {
view_ = NULL;
- // There is a delayed task that the child process posts to terminate the
- // message loop so we need to spin the message loop to delete the task.
- MockProcess::GlobalCleanup();
- msg_loop_.Run();
+ mock_process_.reset();
}
MessageLoop msg_loop_;
MockRenderThread render_thread_;
-
+ scoped_ptr<MockProcess> mock_process_;
scoped_refptr<RenderView> view_;
};
diff --git a/chrome/renderer/render_widget.cc b/chrome/renderer/render_widget.cc
index 7782fd5..9d1d3a3 100644
--- a/chrome/renderer/render_widget.cc
+++ b/chrome/renderer/render_widget.cc
@@ -98,21 +98,21 @@ RenderWidget::RenderWidget(RenderThreadBase* render_thread, bool activatable)
ime_control_updated_(false),
ime_control_busy_(false),
activatable_(activatable) {
- RenderProcess::AddRefProcess();
+ RenderProcess::current()->AddRefProcess();
DCHECK(render_thread_);
}
RenderWidget::~RenderWidget() {
DCHECK(!webwidget_) << "Leaking our WebWidget!";
if (current_paint_buf_) {
- RenderProcess::ReleaseTransportDIB(current_paint_buf_);
+ RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_);
current_paint_buf_ = NULL;
}
if (current_scroll_buf_) {
- RenderProcess::ReleaseTransportDIB(current_scroll_buf_);
+ RenderProcess::current()->ReleaseTransportDIB(current_scroll_buf_);
current_scroll_buf_ = NULL;
}
- RenderProcess::ReleaseProcess();
+ RenderProcess::current()->ReleaseProcess();
}
/*static*/
@@ -298,7 +298,7 @@ void RenderWidget::OnPaintRectAck() {
// If we sent a PaintRect message with a zero-sized bitmap, then
// we should have no current paint buf.
if (current_paint_buf_) {
- RenderProcess::ReleaseTransportDIB(current_paint_buf_);
+ RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_);
current_paint_buf_ = NULL;
}
@@ -310,7 +310,7 @@ void RenderWidget::OnScrollRectAck() {
DCHECK(scroll_reply_pending());
if (current_scroll_buf_) {
- RenderProcess::ReleaseTransportDIB(current_scroll_buf_);
+ RenderProcess::current()->ReleaseTransportDIB(current_scroll_buf_);
current_scroll_buf_ = NULL;
}
@@ -403,7 +403,7 @@ void RenderWidget::DoDeferredPaint() {
// Compute a buffer for painting and cache it.
skia::PlatformCanvas* canvas =
- RenderProcess::GetDrawingCanvas(&current_paint_buf_, damaged_rect);
+ RenderProcess::current()->GetDrawingCanvas(&current_paint_buf_, damaged_rect);
if (!canvas) {
NOTREACHED();
return;
@@ -480,7 +480,7 @@ void RenderWidget::DoDeferredScroll() {
damaged_rect = scroll_rect_.Intersect(damaged_rect);
skia::PlatformCanvas* canvas =
- RenderProcess::GetDrawingCanvas(&current_scroll_buf_, damaged_rect);
+ RenderProcess::current()->GetDrawingCanvas(&current_scroll_buf_, damaged_rect);
if (!canvas) {
NOTREACHED();
return;
diff --git a/chrome/renderer/render_widget.h b/chrome/renderer/render_widget.h
index b0c4b11..edcc5af 100644
--- a/chrome/renderer/render_widget.h
+++ b/chrome/renderer/render_widget.h
@@ -32,7 +32,7 @@ class RenderWidget : public IPC::Channel::Listener,
public:
// Creates a new RenderWidget. The opener_id is the routing ID of the
// RenderView that this widget lives inside. The render_thread is any
- // RenderThreadBase implementation, mostly commonly g_render_thread.
+ // RenderThreadBase implementation, mostly commonly RenderThread::current().
static RenderWidget* Create(int32 opener_id,
RenderThreadBase* render_thread,
bool activatable);
diff --git a/chrome/renderer/render_widget_unittest.cc b/chrome/renderer/render_widget_unittest.cc
index 6c2b24f..6937a64 100644
--- a/chrome/renderer/render_widget_unittest.cc
+++ b/chrome/renderer/render_widget_unittest.cc
@@ -28,20 +28,17 @@ class RenderWidgetTest : public testing::Test {
private:
// testing::Test
virtual void SetUp() {
- MockProcess::GlobalInit();
-
+ mock_process_.reset(new MockProcess());
render_thread_.set_routing_id(kRouteId);
widget_ = RenderWidget::Create(kOpenerId, &render_thread_, true);
ASSERT_TRUE(widget_);
}
virtual void TearDown() {
widget_ = NULL;
-
- // There is a delayed task that the child process posts to terminate the
- // message loop so we need to spin the message loop to delete the task.
- MockProcess::GlobalCleanup();
- msg_loop_.Run();
+ mock_process_.reset();
}
+
+ scoped_ptr<MockProcess> mock_process_;
};
} // namespace
diff --git a/chrome/renderer/renderer_glue.cc b/chrome/renderer/renderer_glue.cc
index a65f326..7ccf018 100644
--- a/chrome/renderer/renderer_glue.cc
+++ b/chrome/renderer/renderer_glue.cc
@@ -134,14 +134,14 @@ ScopedClipboardWriterGlue::~ScopedClipboardWriterGlue() {
#if defined(OS_WIN)
if (shared_buf_) {
- g_render_thread->Send(
+ RenderThread::current()->Send(
new ViewHostMsg_ClipboardWriteObjectsSync(objects_));
delete shared_buf_;
return;
}
#endif
- g_render_thread->Send(
+ RenderThread::current()->Send(
new ViewHostMsg_ClipboardWriteObjectsAsync(objects_));
}
@@ -183,7 +183,7 @@ bool GetMimeTypeFromExtension(const FilePath::StringType &ext,
// The sandbox restricts our access to the registry, so we need to proxy
// these calls over to the browser process.
DCHECK(mime_type->empty());
- g_render_thread->Send(
+ RenderThread::current()->Send(
new ViewHostMsg_GetMimeTypeFromExtension(ext, mime_type));
return !mime_type->empty();
}
@@ -196,7 +196,7 @@ bool GetMimeTypeFromFile(const FilePath &file_path,
// The sandbox restricts our access to the registry, so we need to proxy
// these calls over to the browser process.
DCHECK(mime_type->empty());
- g_render_thread->Send(
+ RenderThread::current()->Send(
new ViewHostMsg_GetMimeTypeFromFile(file_path, mime_type));
return !mime_type->empty();
}
@@ -209,7 +209,7 @@ bool GetPreferredExtensionForMimeType(const std::string& mime_type,
// The sandbox restricts our access to the registry, so we need to proxy
// these calls over to the browser process.
DCHECK(ext->empty());
- g_render_thread->Send(
+ RenderThread::current()->Send(
new ViewHostMsg_GetPreferredExtensionForMimeType(mime_type, ext));
return !ext->empty();
}
@@ -246,21 +246,21 @@ bool ClipboardIsFormatAvailable(Clipboard::FormatType format) {
bool ClipboardIsFormatAvailable(unsigned int format) {
bool result;
- g_render_thread->Send(
+ RenderThread::current()->Send(
new ViewHostMsg_ClipboardIsFormatAvailable(format, &result));
return result;
}
void ClipboardReadText(std::wstring* result) {
- g_render_thread->Send(new ViewHostMsg_ClipboardReadText(result));
+ RenderThread::current()->Send(new ViewHostMsg_ClipboardReadText(result));
}
void ClipboardReadAsciiText(std::string* result) {
- g_render_thread->Send(new ViewHostMsg_ClipboardReadAsciiText(result));
+ RenderThread::current()->Send(new ViewHostMsg_ClipboardReadAsciiText(result));
}
void ClipboardReadHTML(std::wstring* markup, GURL* url) {
- g_render_thread->Send(new ViewHostMsg_ClipboardReadHTML(markup, url));
+ RenderThread::current()->Send(new ViewHostMsg_ClipboardReadHTML(markup, url));
}
GURL GetInspectorURL() {
@@ -271,9 +271,8 @@ std::string GetUIResourceProtocol() {
return "chrome";
}
-bool GetPlugins(bool refresh,
- std::vector<WebPluginInfo>* plugins) {
- return g_render_thread->Send(
+bool GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) {
+ return RenderThread::current()->Send(
new ViewHostMsg_GetPlugins(refresh, plugins));
}
@@ -281,33 +280,24 @@ bool GetPlugins(bool refresh,
bool EnsureFontLoaded(HFONT font) {
LOGFONT logfont;
GetObject(font, sizeof(LOGFONT), &logfont);
- return g_render_thread->Send(new ViewHostMsg_LoadFont(logfont));
+ return RenderThread::current()->Send(new ViewHostMsg_LoadFont(logfont));
}
#endif
webkit_glue::ScreenInfo GetScreenInfo(gfx::NativeViewId window) {
webkit_glue::ScreenInfo results;
- g_render_thread->Send(
+ RenderThread::current()->Send(
new ViewHostMsg_GetScreenInfo(window, &results));
return results;
}
uint64 VisitedLinkHash(const char* canonical_url, size_t length) {
- return g_render_thread->visited_link_slave()->ComputeURLFingerprint(
+ return RenderThread::current()->visited_link_slave()->ComputeURLFingerprint(
canonical_url, length);
}
bool IsLinkVisited(uint64 link_hash) {
- return g_render_thread->visited_link_slave()->IsVisited(link_hash);
-}
-
-int ResolveProxyFromRenderThread(const GURL& url, std::string* proxy_result) {
- // Send a synchronous IPC from renderer process to the browser process to
- // resolve the proxy. (includes --single-process case).
- int net_error;
- bool ipc_ok = g_render_thread->Send(
- new ViewHostMsg_ResolveProxy(url, &net_error, proxy_result));
- return ipc_ok ? net_error : net::ERR_UNEXPECTED;
+ return RenderThread::current()->visited_link_slave()->IsVisited(link_hash);
}
#ifndef USING_SIMPLE_RESOURCE_LOADER_BRIDGE
@@ -354,12 +344,12 @@ ResourceLoaderBridge* ResourceLoaderBridge::Create(
void SetCookie(const GURL& url, const GURL& policy_url,
const std::string& cookie) {
- g_render_thread->Send(new ViewHostMsg_SetCookie(url, policy_url, cookie));
+ RenderThread::current()->Send(new ViewHostMsg_SetCookie(url, policy_url, cookie));
}
std::string GetCookies(const GURL& url, const GURL& policy_url) {
std::string cookies;
- g_render_thread->Send(new ViewHostMsg_GetCookies(url, policy_url, &cookies));
+ RenderThread::current()->Send(new ViewHostMsg_GetCookies(url, policy_url, &cookies));
return cookies;
}
@@ -367,8 +357,8 @@ void NotifyCacheStats() {
// Update the browser about our cache
// NOTE: Since this can be called from the plugin process, we might not have
// a RenderThread. Do nothing in that case.
- if (g_render_thread)
- g_render_thread->InformHostOfCacheStatsLater();
+ if (!IsPluginProcess())
+ RenderThread::current()->InformHostOfCacheStatsLater();
}
#endif // !USING_SIMPLE_RESOURCE_LOADER_BRIDGE
diff --git a/chrome/renderer/renderer_main.cc b/chrome/renderer/renderer_main.cc
index c376486..8ca5346 100644
--- a/chrome/renderer/renderer_main.cc
+++ b/chrome/renderer/renderer_main.cc
@@ -90,9 +90,8 @@ int RendererMain(const MainFunctionParams& parameters) {
HandleRendererErrorTestParameters(parsed_command_line);
- std::wstring channel_name =
- parsed_command_line.GetSwitchValue(switches::kProcessChannelID);
- if (RenderProcess::GlobalInit(channel_name)) {
+ {
+ RenderProcess render_process;
bool run_loop = true;
if (!no_sandbox) {
run_loop = platform.EnableSandbox();
@@ -108,8 +107,6 @@ int RendererMain(const MainFunctionParams& parameters) {
if (pool) pool->Recycle();
MessageLoop::current()->Run();
}
-
- RenderProcess::GlobalCleanup();
}
platform.PlatformUninitialize();
return 0;
diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc
index 155c19a..bc0754e 100644
--- a/chrome/renderer/webplugin_delegate_proxy.cc
+++ b/chrome/renderer/webplugin_delegate_proxy.cc
@@ -209,12 +209,12 @@ bool WebPluginDelegateProxy::Initialize(const GURL& url, char** argn,
bool load_manually) {
std::wstring channel_name;
FilePath plugin_path;
- if (!g_render_thread->Send(new ViewHostMsg_OpenChannelToPlugin(
+ if (!RenderThread::current()->Send(new ViewHostMsg_OpenChannelToPlugin(
url, mime_type_, clsid_, webkit_glue::GetWebKitLocale(),
&channel_name, &plugin_path)))
return false;
- MessageLoop* ipc_message_loop = g_render_thread->owner_loop();
+ MessageLoop* ipc_message_loop = RenderThread::current()->owner_loop();
scoped_refptr<PluginChannelHost> channel_host =
PluginChannelHost::GetPluginChannelHost(channel_name, ipc_message_loop);
if (!channel_host.get())