summaryrefslogtreecommitdiffstats
path: root/chrome/browser/in_process_webkit
diff options
context:
space:
mode:
authorjorlow@chromium.org <jorlow@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-26 20:46:06 +0000
committerjorlow@chromium.org <jorlow@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-26 20:46:06 +0000
commit3bf335afc98d4f9e85bb5a3f72974d53cb77ebeb (patch)
tree876769a0f2b23932c691d25edde4c0074ef87bbe /chrome/browser/in_process_webkit
parent4411c21f13e7da66f3c9d394f40c1f10b6d20782 (diff)
downloadchromium_src-3bf335afc98d4f9e85bb5a3f72974d53cb77ebeb.zip
chromium_src-3bf335afc98d4f9e85bb5a3f72974d53cb77ebeb.tar.gz
chromium_src-3bf335afc98d4f9e85bb5a3f72974d53cb77ebeb.tar.bz2
Create a webkit thread for use within the browser process. This patch also includes some (soon to be fleshed out in another CL) code to demonstrate how it'll be used in DOM Storage.
BUG=None TEST=None Review URL: http://codereview.chromium.org/139003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19413 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/in_process_webkit')
-rw-r--r--chrome/browser/in_process_webkit/browser_webkitclient_impl.cc78
-rw-r--r--chrome/browser/in_process_webkit/browser_webkitclient_impl.h32
-rw-r--r--chrome/browser/in_process_webkit/dom_storage_dispatcher_host.cc70
-rw-r--r--chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h58
-rw-r--r--chrome/browser/in_process_webkit/dom_storage_dispatcher_host_unittest.cc9
-rw-r--r--chrome/browser/in_process_webkit/webkit_context.cc13
-rw-r--r--chrome/browser/in_process_webkit/webkit_context.h30
-rw-r--r--chrome/browser/in_process_webkit/webkit_context_unittest.cc20
-rw-r--r--chrome/browser/in_process_webkit/webkit_thread.cc69
-rw-r--r--chrome/browser/in_process_webkit/webkit_thread.h75
-rw-r--r--chrome/browser/in_process_webkit/webkit_thread_unittest.cc17
11 files changed, 471 insertions, 0 deletions
diff --git a/chrome/browser/in_process_webkit/browser_webkitclient_impl.cc b/chrome/browser/in_process_webkit/browser_webkitclient_impl.cc
new file mode 100644
index 0000000..58d549a
--- /dev/null
+++ b/chrome/browser/in_process_webkit/browser_webkitclient_impl.cc
@@ -0,0 +1,78 @@
+// 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/browser/in_process_webkit/browser_webkitclient_impl.h"
+
+#include "base/logging.h"
+#include "webkit/api/public/WebData.h"
+#include "webkit/api/public/WebString.h"
+#include "webkit/api/public/WebURL.h"
+
+WebKit::WebClipboard* BrowserWebKitClientImpl::clipboard() {
+ NOTREACHED();
+ return NULL;
+}
+
+WebKit::WebMimeRegistry* BrowserWebKitClientImpl::mimeRegistry() {
+ NOTREACHED();
+ return NULL;
+}
+
+WebKit::WebSandboxSupport* BrowserWebKitClientImpl::sandboxSupport() {
+ NOTREACHED();
+ return NULL;
+}
+
+unsigned long long BrowserWebKitClientImpl::visitedLinkHash(
+ const char* canonical_url,
+ size_t length) {
+ NOTREACHED();
+ return 0;
+}
+
+bool BrowserWebKitClientImpl::isLinkVisited(unsigned long long link_hash) {
+ NOTREACHED();
+ return false;
+}
+
+void BrowserWebKitClientImpl::setCookies(const WebKit::WebURL& url,
+ const WebKit::WebURL& policy_url,
+ const WebKit::WebString& value) {
+ NOTREACHED();
+}
+
+WebKit::WebString BrowserWebKitClientImpl::cookies(
+ const WebKit::WebURL& url, const WebKit::WebURL& policy_url) {
+ NOTREACHED();
+ return WebKit::WebString();
+}
+
+void BrowserWebKitClientImpl::prefetchHostName(const WebKit::WebString&) {
+ NOTREACHED();
+}
+
+WebKit::WebString BrowserWebKitClientImpl::defaultLocale() {
+ NOTREACHED();
+ return WebKit::WebString();
+}
+
+WebKit::WebThemeEngine* BrowserWebKitClientImpl::themeEngine() {
+ NOTREACHED();
+ return NULL;
+}
+
+WebKit::WebURLLoader* BrowserWebKitClientImpl::createURLLoader() {
+ NOTREACHED();
+ return NULL;
+}
+
+void BrowserWebKitClientImpl::getPluginList(bool refresh,
+ WebKit::WebPluginListBuilder* builder) {
+ NOTREACHED();
+}
+
+WebKit::WebData BrowserWebKitClientImpl::loadResource(const char* name) {
+ NOTREACHED();
+ return WebKit::WebData();
+}
diff --git a/chrome/browser/in_process_webkit/browser_webkitclient_impl.h b/chrome/browser/in_process_webkit/browser_webkitclient_impl.h
new file mode 100644
index 0000000..52ee5e2
--- /dev/null
+++ b/chrome/browser/in_process_webkit/browser_webkitclient_impl.h
@@ -0,0 +1,32 @@
+// 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_BROWSER_IN_PROCESS_WEBKIT_WEBKIT_CLIENT_IMPL_H_
+#define CHROME_BROWSER_IN_PROCESS_WEBKIT_WEBKIT_CLIENT_IMPL_H_
+
+#include "webkit/glue/webkitclient_impl.h"
+
+class BrowserWebKitClientImpl : public webkit_glue::WebKitClientImpl {
+ public:
+ // WebKitClient methods:
+ virtual WebKit::WebClipboard* clipboard();
+ virtual WebKit::WebMimeRegistry* mimeRegistry();
+ virtual WebKit::WebSandboxSupport* sandboxSupport();
+ virtual unsigned long long visitedLinkHash(const char* canonicalURL,
+ size_t length);
+ virtual bool isLinkVisited(unsigned long long linkHash);
+ virtual void setCookies(const WebKit::WebURL& url,
+ const WebKit::WebURL& policy_url,
+ const WebKit::WebString& value);
+ virtual WebKit::WebString cookies(const WebKit::WebURL& url,
+ const WebKit::WebURL& policy_url);
+ virtual void prefetchHostName(const WebKit::WebString&);
+ virtual WebKit::WebString defaultLocale();
+ virtual WebKit::WebThemeEngine* themeEngine();
+ virtual WebKit::WebURLLoader* createURLLoader();
+ virtual void getPluginList(bool refresh, WebKit::WebPluginListBuilder*);
+ virtual WebKit::WebData loadResource(const char* name);
+};
+
+#endif // CHROME_BROWSER_IN_PROCESS_WEBKIT_WEBKIT_CLIENT_IMPL_H_
diff --git a/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.cc b/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.cc
new file mode 100644
index 0000000..cbbf9ff
--- /dev/null
+++ b/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.cc
@@ -0,0 +1,70 @@
+// 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/browser/in_process_webkit/dom_storage_dispatcher_host.h"
+
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/in_process_webkit/webkit_context.h"
+#include "chrome/browser/in_process_webkit/webkit_thread.h"
+
+DOMStorageDispatcherHost::DOMStorageDispatcherHost(
+ IPC::Message::Sender* message_sender,
+ WebKitContext* webkit_context,
+ WebKitThread* webkit_thread)
+ : webkit_context_(webkit_context),
+ webkit_thread_(webkit_thread),
+ message_sender_(message_sender) {
+ DCHECK(webkit_context_.get());
+ DCHECK(webkit_thread_.get());
+ DCHECK(message_sender_);
+}
+
+DOMStorageDispatcherHost::~DOMStorageDispatcherHost() {
+ DCHECK(!message_sender_);
+}
+
+void DOMStorageDispatcherHost::Shutdown() {
+ DCHECK(IsOnIOThread());
+ AutoLock lock(message_sender_lock_);
+ message_sender_ = NULL;
+}
+
+bool DOMStorageDispatcherHost::OnMessageReceived(const IPC::Message& msg) {
+ // TODO(jorlow): Implement DOM Storage's message handler...and the rest
+ // of DOM Storage. :-)
+ return false;
+}
+
+void DOMStorageDispatcherHost::Send(IPC::Message* message) {
+ if (IsOnIOThread()) {
+ if (message_sender_)
+ message_sender_->Send(message);
+ else
+ delete message;
+ }
+
+ // If message_sender_ is NULL, the IO thread has either gone away
+ // or will do so soon. By holding this lock until we finish posting to the
+ // thread, we block the IO thread from completely shutting down benieth us.
+ AutoLock lock(message_sender_lock_);
+ if (!message_sender_) {
+ delete message;
+ return;
+ }
+
+ MessageLoop* io_loop = ChromeThread::GetMessageLoop(ChromeThread::IO);
+ CancelableTask* task = NewRunnableMethod(this,
+ &DOMStorageDispatcherHost::Send,
+ message);
+ io_loop->PostTask(FROM_HERE, task);
+}
+
+bool DOMStorageDispatcherHost::IsOnIOThread() const {
+ MessageLoop* io_loop = ChromeThread::GetMessageLoop(ChromeThread::IO);
+ return MessageLoop::current() == io_loop;
+}
+
+bool DOMStorageDispatcherHost::IsOnWebKitThread() const {
+ return MessageLoop::current() == webkit_thread_->GetMessageLoop();
+}
diff --git a/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h b/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h
new file mode 100644
index 0000000..a7b815f
--- /dev/null
+++ b/chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h
@@ -0,0 +1,58 @@
+// 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_BROWSER_IN_PROCESS_WEBKIT_DOM_STORAGE_DISPATCHER_HOST_H_
+#define CHROME_BROWSER_IN_PROCESS_WEBKIT_DOM_STORAGE_DISPATCHER_HOST_H_
+
+#include "base/ref_counted.h"
+#include "base/thread.h"
+#include "chrome/common/ipc_message.h"
+
+class WebKitContext;
+class WebKitThread;
+
+// This class handles the logistics of DOM Storage within the browser process.
+// It mostly ferries information between IPCs and the WebKit implementations,
+// but it also handles some special cases like when renderer processes die.
+// THIS CLASS MUST NOT BE DESTROYED ON THE WEBKIT THREAD (for now).
+class DOMStorageDispatcherHost :
+ public base::RefCountedThreadSafe<DOMStorageDispatcherHost> {
+ public:
+ // Only call the constructor from the UI thread.
+ DOMStorageDispatcherHost(IPC::Message::Sender* message_sender,
+ WebKitContext*, WebKitThread*);
+
+ // Only call Shutdown from the IO thread. Shutdown warns us that we're going
+ // to go away soon and tells us not to send anything else to the IO thread.
+ void Shutdown();
+
+ // Only call from IO thread.
+ bool OnMessageReceived(const IPC::Message& message);
+
+ // Send a message to the renderer process associated with our
+ // message_sender_ via the IO thread. May be called from any thread.
+ void Send(IPC::Message* message);
+
+ private:
+ friend class base::RefCountedThreadSafe<DOMStorageDispatcherHost>;
+ ~DOMStorageDispatcherHost();
+
+ // Obviously can be called from any thread.
+ bool IsOnIOThread() const;
+ bool IsOnWebKitThread() const;
+
+ // Are immutable and are always valid throughout the lifetime of the object.
+ scoped_refptr<WebKitContext> webkit_context_;
+ scoped_refptr<WebKitThread> webkit_thread_;
+
+ // We keep the message_sender_ pointer for sending messages. All access
+ // to the message_sender_ (and the IO thread in general) should be done under
+ // this lock and only if message_sender_ is non-NULL.
+ Lock message_sender_lock_;
+ IPC::Message::Sender* message_sender_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(DOMStorageDispatcherHost);
+};
+
+#endif // CHROME_BROWSER_IN_PROCESS_WEBKIT_DOM_STORAGE_DISPATCHER_HOST_H_
diff --git a/chrome/browser/in_process_webkit/dom_storage_dispatcher_host_unittest.cc b/chrome/browser/in_process_webkit/dom_storage_dispatcher_host_unittest.cc
new file mode 100644
index 0000000..a277492
--- /dev/null
+++ b/chrome/browser/in_process_webkit/dom_storage_dispatcher_host_unittest.cc
@@ -0,0 +1,9 @@
+// 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/browser/in_process_webkit/dom_storage_dispatcher_host.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// TODO(jorlow): Write once dom_storage_dispatcher_host is more than just a
+// stub.
diff --git a/chrome/browser/in_process_webkit/webkit_context.cc b/chrome/browser/in_process_webkit/webkit_context.cc
new file mode 100644
index 0000000..e7d7d1a
--- /dev/null
+++ b/chrome/browser/in_process_webkit/webkit_context.cc
@@ -0,0 +1,13 @@
+// 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/browser/in_process_webkit/webkit_context.h"
+
+WebKitContext::WebKitContext(const FilePath& data_path, bool is_incognito)
+ : data_path_(data_path),
+ is_incognito_(is_incognito) {
+}
+
+WebKitContext::~WebKitContext() {
+}
diff --git a/chrome/browser/in_process_webkit/webkit_context.h b/chrome/browser/in_process_webkit/webkit_context.h
new file mode 100644
index 0000000..2b84224
--- /dev/null
+++ b/chrome/browser/in_process_webkit/webkit_context.h
@@ -0,0 +1,30 @@
+// 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_BROWSER_IN_PROCESS_WEBKIT_WEBKIT_CONTEXT_H_
+#define CHROME_BROWSER_IN_PROCESS_WEBKIT_WEBKIT_CONTEXT_H_
+
+#include "base/file_path.h"
+#include "base/ref_counted.h"
+
+// There's one WebKitContext per profile. Various DispatcherHost classes
+// have a pointer to the Context to store shared state.
+class WebKitContext : public base::RefCountedThreadSafe<WebKitContext> {
+ public:
+ WebKitContext(const FilePath& data_path, bool is_incognito);
+
+ const FilePath& data_path() const { return data_path_; }
+ bool is_incognito() const { return is_incognito_; }
+
+ private:
+ friend class base::RefCountedThreadSafe<WebKitContext>;
+ ~WebKitContext();
+
+ FilePath data_path_;
+ bool is_incognito_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(WebKitContext);
+};
+
+#endif // CHROME_BROWSER_IN_PROCESS_WEBKIT_WEBKIT_CONTEXT_H_
diff --git a/chrome/browser/in_process_webkit/webkit_context_unittest.cc b/chrome/browser/in_process_webkit/webkit_context_unittest.cc
new file mode 100644
index 0000000..e5f446d
--- /dev/null
+++ b/chrome/browser/in_process_webkit/webkit_context_unittest.cc
@@ -0,0 +1,20 @@
+// 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/browser/in_process_webkit/webkit_context.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(WebKitContextTest, BasicsTest1) {
+ FilePath file_path;
+ scoped_refptr<WebKitContext> context = new WebKitContext(file_path, true);
+ ASSERT_TRUE(file_path == context->data_path());
+ ASSERT_EQ(true, context->is_incognito());
+}
+
+TEST(WebKitContextTest, BasicsTest2) {
+ FilePath file_path;
+ scoped_refptr<WebKitContext> context = new WebKitContext(file_path, false);
+ ASSERT_TRUE(file_path == context->data_path());
+ ASSERT_EQ(false, context->is_incognito());
+}
diff --git a/chrome/browser/in_process_webkit/webkit_thread.cc b/chrome/browser/in_process_webkit/webkit_thread.cc
new file mode 100644
index 0000000..55772c6
--- /dev/null
+++ b/chrome/browser/in_process_webkit/webkit_thread.cc
@@ -0,0 +1,69 @@
+// 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/browser/in_process_webkit/webkit_thread.h"
+
+#include "chrome/browser/in_process_webkit/browser_webkitclient_impl.h"
+#include "webkit/api/public/WebKit.h"
+
+base::LazyInstance<Lock> WebKitThread::global_webkit_lock_(
+ base::LINKER_INITIALIZED);
+int WebKitThread::global_webkit_ref_count_ = 0;
+WebKitThread::InternalWebKitThread* WebKitThread::global_webkit_thread_ = NULL;
+
+WebKitThread::WebKitThread()
+ : cached_webkit_thread_(NULL) {
+ // The thread is started lazily by InitializeThread().
+}
+
+WebKitThread::InternalWebKitThread::InternalWebKitThread()
+ : base::Thread("WebKit"),
+ webkit_client_(NULL) {
+}
+
+void WebKitThread::InternalWebKitThread::Init() {
+ DCHECK(!webkit_client_);
+ webkit_client_ = new BrowserWebKitClientImpl;
+ DCHECK(webkit_client_);
+ WebKit::initialize(webkit_client_);
+ // Don't do anything heavyweight here since this can block the IO thread from
+ // executing (since InitializeThread() is often called on the IO thread).
+}
+
+void WebKitThread::InternalWebKitThread::CleanUp() {
+ DCHECK(webkit_client_);
+ WebKit::shutdown();
+ delete webkit_client_;
+ webkit_client_ = NULL;
+}
+
+WebKitThread::~WebKitThread() {
+ AutoLock lock(global_webkit_lock_.Get());
+ if (cached_webkit_thread_) {
+ DCHECK(global_webkit_ref_count_ > 0);
+ if (--global_webkit_ref_count_ == 0) {
+ // TODO(jorlow): Make this safe.
+ DCHECK(MessageLoop::current() != global_webkit_thread_->message_loop());
+ global_webkit_thread_->Stop();
+ delete global_webkit_thread_;
+ global_webkit_thread_ = NULL;
+ }
+ }
+}
+
+void WebKitThread::InitializeThread() {
+ AutoLock lock(global_webkit_lock_.Get());
+ if (!cached_webkit_thread_) {
+ if (!global_webkit_thread_) {
+ global_webkit_thread_ = new InternalWebKitThread;
+ DCHECK(global_webkit_thread_);
+ bool started = global_webkit_thread_->Start();
+ DCHECK(started);
+ }
+ ++global_webkit_ref_count_;
+ // The cached version can be accessed outside of global_webkit_lock_.
+ cached_webkit_thread_ = global_webkit_thread_;
+ }
+ DCHECK(cached_webkit_thread_->IsRunning());
+}
diff --git a/chrome/browser/in_process_webkit/webkit_thread.h b/chrome/browser/in_process_webkit/webkit_thread.h
new file mode 100644
index 0000000..518fa66
--- /dev/null
+++ b/chrome/browser/in_process_webkit/webkit_thread.h
@@ -0,0 +1,75 @@
+// 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_BROWSER_IN_PROCESS_WEBKIT_WEBKIT_THREAD_H_
+#define CHROME_BROWSER_IN_PROCESS_WEBKIT_WEBKIT_THREAD_H_
+
+#include "base/lazy_instance.h"
+#include "base/lock.h"
+#include "base/logging.h"
+#include "base/ref_counted.h"
+#include "base/thread.h"
+
+class BrowserWebKitClientImpl;
+
+// This is an object that represents WebKit's "main" thread within the browser
+// process. You can create as many instances of this class as you'd like;
+// they'll all point to the same thread and you're guaranteed they'll
+// initialize in a thread-safe way, though WebKitThread instances should
+// probably be shared when it's easy to do so. The first time you call
+// GetMessageLoop() or EnsureWebKitInitialized() the thread will be created
+// and WebKit initialized. When the last instance of WebKitThread is
+// destroyed, WebKit is shut down and the thread is stopped.
+// THIS CLASS MUST NOT BE DEREFED TO 0 ON THE WEBKIT THREAD (for now).
+class WebKitThread : public base::RefCountedThreadSafe<WebKitThread> {
+ public:
+ WebKitThread();
+
+ MessageLoop* GetMessageLoop() {
+ if (!cached_webkit_thread_)
+ InitializeThread();
+ return cached_webkit_thread_->message_loop();
+ }
+
+ void EnsureWebKitInitialized() {
+ if (!cached_webkit_thread_)
+ InitializeThread();
+ }
+
+ private:
+ // Must be private so that we can carefully control its lifetime.
+ class InternalWebKitThread : public base::Thread {
+ public:
+ InternalWebKitThread();
+ virtual ~InternalWebKitThread() { }
+ // Does the actual initialization and shutdown of WebKit. Called at the
+ // beginning and end of the thread's lifetime.
+ virtual void Init();
+ virtual void CleanUp();
+
+ private:
+ BrowserWebKitClientImpl* webkit_client_;
+ };
+
+ friend class base::RefCountedThreadSafe<WebKitThread>;
+ ~WebKitThread();
+
+ void InitializeThread();
+
+ // If this is set, then this object has incremented the global WebKit ref
+ // count and will shutdown the thread if it sees the ref count go to 0.
+ // It's assumed that once this is non-NULL, the pointer will be valid until
+ // destruction.
+ InternalWebKitThread* cached_webkit_thread_;
+
+ // If there are multiple WebKitThread object (should only be possible in
+ // unittests at the moment), make sure they all share one real thread.
+ static base::LazyInstance<Lock> global_webkit_lock_;
+ static int global_webkit_ref_count_;
+ static InternalWebKitThread* global_webkit_thread_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebKitThread);
+};
+
+#endif // CHROME_BROWSER_IN_PROCESS_WEBKIT_WEBKIT_THREAD_H_
diff --git a/chrome/browser/in_process_webkit/webkit_thread_unittest.cc b/chrome/browser/in_process_webkit/webkit_thread_unittest.cc
new file mode 100644
index 0000000..f66a26c
--- /dev/null
+++ b/chrome/browser/in_process_webkit/webkit_thread_unittest.cc
@@ -0,0 +1,17 @@
+// 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/browser/in_process_webkit/webkit_thread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// This is important because if there are 2 different message loops, we must
+// have 2 different WebKit threads which would be very bad.
+TEST(WebKitThreadTest, TwoThreadsShareMessageLoopTest) {
+ scoped_refptr<WebKitThread> thread_a = new WebKitThread;
+ scoped_refptr<WebKitThread> thread_b = new WebKitThread;
+ MessageLoop* loop_a = thread_a->GetMessageLoop();
+ MessageLoop* loop_b = thread_b->GetMessageLoop();
+ ASSERT_FALSE(loop_a == NULL);
+ ASSERT_EQ(loop_a, loop_b);
+}