Bug 516515 - Don't initialize XPCOM in plugin processes, r=cjones
authorBenjamin Smedberg <benjamin@smedbergs.us>
Wed, 03 Feb 2010 17:17:09 -0500
changeset 37884 62cc92f9dced0b4e4d82a8e4406586759a20c8b7
parent 37883 4f2520c904e5827eb8115649a81c1579bdd11c05
child 37885 ebe4e14ee63e1739aa2d00dddc90d8bcf9d92b93
push idunknown
push userunknown
push dateunknown
reviewerscjones
bugs516515
milestone1.9.3a1pre
Bug 516515 - Don't initialize XPCOM in plugin processes, r=cjones
dom/plugins/ChildAsyncCall.cpp
dom/plugins/ChildAsyncCall.h
dom/plugins/ChildTimer.cpp
dom/plugins/ChildTimer.h
dom/plugins/PluginInstanceChild.cpp
dom/plugins/PluginInstanceChild.h
dom/plugins/PluginMessageUtils.h
dom/plugins/PluginModuleChild.cpp
dom/plugins/PluginProcessParent.cpp
dom/plugins/PluginThreadChild.cpp
dom/plugins/PluginThreadChild.h
ipc/chromium/Makefile.in
ipc/chromium/src/base/message_loop.cc
ipc/chromium/src/base/message_loop.h
ipc/chromium/src/chrome/common/child_process_host.cc
ipc/glue/AsyncChannel.cpp
ipc/glue/BrowserProcessSubThread.cpp
ipc/glue/BrowserProcessSubThread.h
ipc/glue/GeckoChildProcessHost.cpp
ipc/glue/GeckoThread.cpp
ipc/glue/GeckoThread.h
ipc/glue/Makefile.in
ipc/glue/MozillaChildThread.cpp
ipc/glue/MozillaChildThread.h
ipc/glue/RPCChannel.cpp
ipc/glue/SyncChannel.cpp
ipc/ipdl/test/cxx/IPDLUnitTestThreadChild.cpp
ipc/ipdl/test/cxx/IPDLUnitTestThreadChild.h
ipc/ipdl/test/cxx/IPDLUnitTests.h
toolkit/xre/nsEmbedFunctions.cpp
xpcom/base/Makefile.in
xpcom/base/nsTraceRefcntImpl.cpp
xpcom/build/nsXPCOMPrivate.h
xpcom/build/nsXPComInit.cpp
xpcom/glue/BlockingResourceBase.h
--- a/dom/plugins/ChildAsyncCall.cpp
+++ b/dom/plugins/ChildAsyncCall.cpp
@@ -55,20 +55,19 @@ ChildAsyncCall::ChildAsyncCall(PluginIns
 void
 ChildAsyncCall::Cancel()
 {
   mInstance = NULL;
   mFunc = NULL;
   mData = NULL;
 }
 
-NS_IMETHODIMP
+void
 ChildAsyncCall::Run()
 {
   if (mFunc) {
     mInstance->mPendingAsyncCalls.RemoveElement(this);
     mFunc(mData);
   }
-  return NS_OK;
 }
 
 } // namespace plugins
 } // namespace mozilla
--- a/dom/plugins/ChildAsyncCall.h
+++ b/dom/plugins/ChildAsyncCall.h
@@ -37,33 +37,33 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef mozilla_plugins_ChildAsyncCall_h
 #define mozilla_plugins_ChildAsyncCall_h
 
 #include "PluginMessageUtils.h"
-#include "nsThreadUtils.h"
+#include "base/task.h"
 
 namespace mozilla {
 namespace plugins {
 
 typedef void (*PluginThreadCallback)(void*);
 
 class PluginInstanceChild;
 
-class ChildAsyncCall : public nsRunnable
+class ChildAsyncCall : public CancelableTask
 {
 public:
   ChildAsyncCall(PluginInstanceChild* instance,
                  PluginThreadCallback aFunc, void* aUserData);
 
-  void Cancel();
-  NS_IMETHOD Run();
+  NS_OVERRIDE void Run();
+  NS_OVERRIDE void Cancel();
 
 private:
   PluginInstanceChild* mInstance;
   PluginThreadCallback mFunc;
   void* mData;
 };
 
 } // namespace plugins
--- a/dom/plugins/ChildTimer.cpp
+++ b/dom/plugins/ChildTimer.cpp
@@ -46,44 +46,28 @@ namespace mozilla {
 namespace plugins {
 
 ChildTimer::ChildTimer(PluginInstanceChild* instance,
                        uint32_t interval,
                        bool repeat,
                        TimerFunc func)
   : mInstance(instance)
   , mFunc(func)
-  , mID(0)
+  , mRepeating(repeat)
+  , mID(gNextTimerID++)
 {
-  mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
-  if (!mTimer)
-    return;
-
-  nsresult rv = mTimer->InitWithFuncCallback(Callback, this, interval,
-                                             repeat ? nsITimer::TYPE_REPEATING_SLACK : nsITimer::TYPE_ONE_SHOT);
-  if (NS_FAILED(rv)) {
-    mTimer = NULL;
-    return;
-  }
-
-  mID = gNextTimerID++;
-}
-
-void
-ChildTimer::Destroy()
-{
-  mTimer->Cancel();
-  mTimer = NULL;
-  delete this;
+  mTimer.Start(base::TimeDelta::FromMilliseconds(interval),
+               this, &ChildTimer::Run);
 }
 
 uint32_t
 ChildTimer::gNextTimerID = 1;
 
 void
-ChildTimer::Callback(nsITimer* aTimer, void* aClosure)
+ChildTimer::Run()
 {
-  ChildTimer* self = static_cast<ChildTimer*>(aClosure);
-  self->mFunc(self->mInstance->GetNPP(), self->mID);
+  if (!mRepeating)
+    mTimer.Stop();
+  mFunc(mInstance->GetNPP(), mID);
 }
 
 } // namespace plugins
 } // namespace mozilla
--- a/dom/plugins/ChildTimer.h
+++ b/dom/plugins/ChildTimer.h
@@ -38,18 +38,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef mozilla_plugins_ChildTimer_h
 #define mozilla_plugins_ChildTimer_h
 
 #include "PluginMessageUtils.h"
 #include "npapi.h"
-#include "nsITimer.h"
-#include "nsCOMPtr.h"
+#include "base/timer.h"
 
 namespace mozilla {
 namespace plugins {
 
 class PluginInstanceChild;
 typedef void (*TimerFunc)(NPP npp, uint32_t timerID);
 
 class ChildTimer
@@ -57,41 +56,36 @@ class ChildTimer
 public:
   /**
    * If initialization failed, ID() will return 0.
    */
   ChildTimer(PluginInstanceChild* instance,
              uint32_t interval,
              bool repeat,
              TimerFunc func);
-  ~ChildTimer() {
-    NS_ASSERTION(!mTimer, "Timer should already be cancelled");
-  }
+  ~ChildTimer() { }
 
   uint32_t ID() const { return mID; }
 
-  /**
-   * Called by the instance, cancels the timer and deletes this object.
-   */
-  void Destroy();
-
   class IDComparator
   {
   public:
     PRBool Equals(ChildTimer* t, uint32_t id) const {
       return t->ID() == id;
     }
   };
 
 private:
   PluginInstanceChild* mInstance;
   TimerFunc mFunc;
+  bool mRepeating;
   uint32_t mID;
-  nsCOMPtr<nsITimer> mTimer;
+  base::RepeatingTimer<ChildTimer> mTimer;
+
+  void Run();
 
   static uint32_t gNextTimerID;
-  static void Callback(nsITimer* aTimer, void* aClosure);
 };
 
 } // namespace plugins
 } // namespace mozilla
 
 #endif // mozilla_plugins_ChildTimer_h
--- a/dom/plugins/PluginInstanceChild.cpp
+++ b/dom/plugins/PluginInstanceChild.cpp
@@ -1139,34 +1139,27 @@ PluginInstanceChild::ScheduleTimer(uint3
 }
 
 void
 PluginInstanceChild::UnscheduleTimer(uint32_t id)
 {
     if (0 == id)
         return;
 
-    PRUint32 i = mTimers.IndexOf(id, 0, ChildTimer::IDComparator());
-    if (nsTArray<ChildTimer*>::NoIndex == i)
-        return;
-
-    mTimers.ElementAt(i)->Destroy();
-    mTimers.RemoveElementAt(i);
+    mTimers.RemoveElement(id, ChildTimer::IDComparator());
 }
 
 bool
 PluginInstanceChild::AnswerNPP_Destroy(NPError* aResult)
 {
     for (PRUint32 i = 0; i < mPendingAsyncCalls.Length(); ++i)
         mPendingAsyncCalls[i]->Cancel();
     mPendingAsyncCalls.TruncateLength(0);
 
-    for (PRUint32 i = 0; i < mTimers.Length(); ++i)
-        mTimers[i]->Destroy();
-    mTimers.TruncateLength(0);
+    mTimers.Clear();
 
     PluginModuleChild* module = PluginModuleChild::current();
     bool retval = module->PluginInstanceDestroyed(this, aResult);
 
 #if defined(OS_WIN)
     SharedSurfaceRelease();
 #endif
 
--- a/dom/plugins/PluginInstanceChild.h
+++ b/dom/plugins/PluginInstanceChild.h
@@ -210,17 +210,17 @@ private:
 #elif defined(OS_WIN)
     HWND mPluginWindowHWND;
     WNDPROC mPluginWndProc;
     HWND mPluginParentHWND;
 #endif
 
     friend class ChildAsyncCall;
     nsTArray<ChildAsyncCall*> mPendingAsyncCalls;
-    nsTArray<ChildTimer*> mTimers;
+    nsTArray<nsAutoPtr<ChildTimer> > mTimers;
 
 #if defined(OS_WIN)
 private:
     // Shared dib rendering management for windowless plugins.
     bool SharedSurfaceSetWindow(const NPRemoteWindow& aWindow, NPError* rv);
     int16_t SharedSurfacePaint(NPEvent& evcopy);
     void SharedSurfaceRelease();
     bool AlphaExtractCacheSetup();
--- a/dom/plugins/PluginMessageUtils.h
+++ b/dom/plugins/PluginMessageUtils.h
@@ -35,16 +35,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef DOM_PLUGINS_PLUGINMESSAGEUTILS_H
 #define DOM_PLUGINS_PLUGINMESSAGEUTILS_H
 
 #include "IPC/IPCMessageUtils.h"
+#include "base/message_loop.h"
 
 #include "npapi.h"
 #include "npruntime.h"
 #include "npfunctions.h"
 #include "nsAutoPtr.h"
 #include "nsStringGlue.h"
 #include "nsTArray.h"
 #include "nsThreadUtils.h"
@@ -192,17 +193,18 @@ NPNVariableToString(NPNVariable aVar)
     default: return "???";
     }
 }
 #undef VARSTR
 
 
 inline void AssertPluginThread()
 {
-  NS_ASSERTION(NS_IsMainThread(), "should be on the plugin's main thread!");
+  NS_ASSERTION(MessageLoopForUI::current(),
+               "should be on the plugin's main thread!");
 }
 
 void DeferNPObjectLastRelease(const NPNetscapeFuncs* f, NPObject* o);
 void DeferNPVariantLastRelease(const NPNetscapeFuncs* f, NPVariant* v);
 
 // in NPAPI, char* == NULL is sometimes meaningful.  the following is
 // helper code for dealing with nullable nsCString's
 inline nsCString
--- a/dom/plugins/PluginModuleChild.cpp
+++ b/dom/plugins/PluginModuleChild.cpp
@@ -50,16 +50,17 @@
 #include "nsCOMPtr.h"
 #include "nsPluginsDir.h"
 #include "nsXULAppAPI.h"
 
 #include "mozilla/plugins/PluginInstanceChild.h"
 #include "mozilla/plugins/StreamNotifyChild.h"
 #include "mozilla/plugins/BrowserStreamChild.h"
 #include "mozilla/plugins/PluginStreamChild.h"
+#include "mozilla/plugins/PluginThreadChild.h"
 
 #include "nsNPAPIPlugin.h"
 
 using mozilla::ipc::NPRemoteIdentifier;
 
 using namespace mozilla::plugins;
 
 namespace {
@@ -1248,18 +1249,19 @@ void NP_CALLBACK
 _pluginthreadasynccall(NPP aNPP,
                        PluginThreadCallback aFunc,
                        void* aUserData)
 {
     PLUGIN_LOG_DEBUG_FUNCTION;
     if (!aFunc)
         return;
 
-    nsCOMPtr<nsIRunnable> e(new ChildAsyncCall(InstCast(aNPP), aFunc, aUserData));
-    NS_DispatchToMainThread(e);
+    PluginThreadChild::current()->message_loop()
+        ->PostTask(FROM_HERE, new ChildAsyncCall(InstCast(aNPP), aFunc,
+                                                 aUserData));
 }
 
 NPError NP_CALLBACK
 _getvalueforurl(NPP npp, NPNURLVariable variable, const char *url,
                 char **value, uint32_t *len)
 {
     PLUGIN_LOG_DEBUG_FUNCTION;
     AssertPluginThread();
--- a/dom/plugins/PluginProcessParent.cpp
+++ b/dom/plugins/PluginProcessParent.cpp
@@ -35,17 +35,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/plugins/PluginProcessParent.h"
 
 #include "base/string_util.h"
-#include "mozilla/ipc/GeckoThread.h"
+#include "mozilla/ipc/BrowserProcessSubThread.h"
 
 using mozilla::ipc::BrowserProcessSubThread;
 using mozilla::ipc::GeckoChildProcessHost;
 using mozilla::plugins::PluginProcessParent;
 
 template<>
 struct RunnableMethodTraits<PluginProcessParent>
 {
--- a/dom/plugins/PluginThreadChild.cpp
+++ b/dom/plugins/PluginThreadChild.cpp
@@ -41,35 +41,39 @@
 
 #include "prlink.h"
 
 #include "base/command_line.h"
 #include "base/string_util.h"
 #include "chrome/common/child_process.h"
 #include "chrome/common/chrome_switches.h"
 
-using mozilla::ipc::GeckoThread;
+using mozilla::ipc::MozillaChildThread;
 
 namespace mozilla {
 namespace plugins {
 
 PluginThreadChild::PluginThreadChild(ProcessHandle aParentHandle) :
-    GeckoThread(aParentHandle),
-    mPlugin()
+    MozillaChildThread(aParentHandle, MessageLoop::TYPE_UI)
 {
+    NS_ASSERTION(!gInstance, "Two PluginThreadChild?");
+    gInstance = this;
 }
 
 PluginThreadChild::~PluginThreadChild()
 {
+    gInstance = NULL;
 }
 
+PluginThreadChild* PluginThreadChild::gInstance;
+
 void
 PluginThreadChild::Init()
 {
-    GeckoThread::Init();
+    MozillaChildThread::Init();
 
     std::string pluginFilename;
 
 #if defined(OS_POSIX)
     // NB: need to be very careful in ensuring that the first arg
     // (after the binary name) here is indeed the plugin module path.
     // Keep in sync with dom/plugins/PluginModuleParent.
     std::vector<std::string> values = CommandLine::ForCurrentProcess()->argv();
@@ -92,13 +96,13 @@ PluginThreadChild::Init()
     mPlugin.Init(pluginFilename,
                  GetParentProcessHandle(), owner_loop(), channel());
 }
 
 void
 PluginThreadChild::CleanUp()
 {
     mPlugin.CleanUp();
-    GeckoThread::CleanUp();
+    MozillaChildThread::CleanUp();
 }
 
 } // namespace plugins
 } // namespace mozilla
--- a/dom/plugins/PluginThreadChild.h
+++ b/dom/plugins/PluginThreadChild.h
@@ -37,42 +37,44 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef dom_plugins_PluginThreadChild_h
 #define dom_plugins_PluginThreadChild_h 1
 
 #include "base/basictypes.h"
 
-#include "chrome/common/child_thread.h"
+#include "mozilla/ipc/MozillaChildThread.h"
 #include "base/file_path.h"
+#include "base/process.h"
 
-#include "mozilla/ipc/GeckoThread.h"
 #include "mozilla/plugins/PluginModuleChild.h"
 
 namespace mozilla {
 namespace plugins {
 //-----------------------------------------------------------------------------
 
 // The PluginThreadChild class represents a background thread where plugin instances
 // live.
-class PluginThreadChild : public mozilla::ipc::GeckoThread {
+class PluginThreadChild : public mozilla::ipc::MozillaChildThread {
 public:
     PluginThreadChild(ProcessHandle aParentHandle);
     ~PluginThreadChild();
 
+    static PluginThreadChild* current() {
+        return gInstance;
+    }
+
 private:
+    static PluginThreadChild* gInstance;
+
     // Thread implementation:
     virtual void Init();
     virtual void CleanUp();
 
-    // FIXME/cjones: this is kinda broken; this thread is generic,
-    // not NPAPI-specific, but there's not really another good
-    // place to store this reference.  and there's no need to make
-    // a generic |Plugin| class yet
     PluginModuleChild mPlugin;
     IPC::Channel* mChannel;
 
     DISALLOW_EVIL_CONSTRUCTORS(PluginThreadChild);
 };
 
 }  // namespace plugins
 }  // namespace mozilla
--- a/ipc/chromium/Makefile.in
+++ b/ipc/chromium/Makefile.in
@@ -241,16 +241,17 @@ ifdef OS_LINUX # {
 
 CPPSRCS += \
   atomicops_internals_x86_gcc.cc \
   base_paths_linux.cc \
   data_pack.cc \
   file_util_linux.cc \
   file_version_info_linux.cc \
   idle_timer_none.cc \
+  message_pump_glib.cc \
   process_util_linux.cc \
   time_posix.cc \
   $(NULL)
 
 endif # } OS_LINUX
 
 # libevent
 
--- a/ipc/chromium/src/base/message_loop.cc
+++ b/ipc/chromium/src/base/message_loop.cc
@@ -14,17 +14,17 @@
 #include "base/thread_local.h"
 
 #if defined(OS_MACOSX)
 #include "base/message_pump_mac.h"
 #endif
 #if defined(OS_POSIX)
 #include "base/message_pump_libevent.h"
 #endif
-#if defined(OS_LINUX) && !defined(CHROMIUM_MOZILLA_BUILD)
+#if defined(OS_LINUX)
 #include "base/message_pump_glib.h"
 #endif
 
 #ifdef CHROMIUM_MOZILLA_BUILD
 #include "MessagePump.h"
 #endif
 
 using base::Time;
@@ -84,17 +84,17 @@ MessageLoop::MessageLoop(Type type)
       nestable_tasks_allowed_(true),
       exception_restoration_(false),
       state_(NULL),
       next_sequence_num_(0) {
   DCHECK(!current()) << "should only have one message loop per thread";
   lazy_tls_ptr.Pointer()->Set(this);
 
 #ifdef CHROMIUM_MOZILLA_BUILD
-  if (type_ == TYPE_UI) {
+  if (type_ == TYPE_MOZILLA_UI) {
     pump_ = new mozilla::ipc::MessagePump();
     return;
   }
   if (type_ == TYPE_MOZILLA_CHILD) {
     pump_ = new mozilla::ipc::MessagePumpForChildProcess();
     return;
   }
 #endif
@@ -107,17 +107,17 @@ MessageLoop::MessageLoop(Type type)
   } else {
     DCHECK(type_ == TYPE_UI);
     pump_ = new base::MessagePumpForUI();
   }
 #elif defined(OS_POSIX)
   if (type_ == TYPE_UI) {
 #if defined(OS_MACOSX)
     pump_ = base::MessagePumpMac::Create();
-#elif defined(OS_LINUX) && !defined(CHROMIUM_MOZILLA_BUILD)
+#elif defined(OS_LINUX)
     pump_ = new base::MessagePumpForUI();
 #endif  // OS_LINUX
   } else if (type_ == TYPE_IO) {
     pump_ = new base::MessagePumpLibevent();
   } else {
     pump_ = new base::MessagePumpDefault();
   }
 #endif  // OS_POSIX
--- a/ipc/chromium/src/base/message_loop.h
+++ b/ipc/chromium/src/base/message_loop.h
@@ -191,22 +191,31 @@ public:
   // TYPE_UI
   //   This type of ML also supports native UI events (e.g., Windows messages).
   //   See also MessageLoopForUI.
   //
   // TYPE_IO
   //   This type of ML also supports asynchronous IO.  See also
   //   MessageLoopForIO.
   //
+  // TYPE_MOZILLA_CHILD
+  //   This type of ML is used in Mozilla child processes which initialize
+  //   XPCOM and use the gecko event loop.
+  //
+  // TYPE_MOZILLA_UI
+  //   This type of ML is used in Mozilla parent processes which initialize
+  //   XPCOM and use the gecko event loop.
+  //
   enum Type {
     TYPE_DEFAULT,
     TYPE_UI,
     TYPE_IO
 #ifdef CHROMIUM_MOZILLA_BUILD
     , TYPE_MOZILLA_CHILD
+    , TYPE_MOZILLA_UI
 #endif
   };
 
   // Normally, it is not necessary to instantiate a MessageLoop.  Instead, it
   // is typical to make use of the current thread's MessageLoop instance.
   explicit MessageLoop(Type type = TYPE_DEFAULT);
   ~MessageLoop();
 
@@ -416,25 +425,27 @@ public:
 // MessageLoopForUI extends MessageLoop with methods that are particular to a
 // MessageLoop instantiated with TYPE_UI.
 //
 // This class is typically used like so:
 //   MessageLoopForUI::current()->...call some method...
 //
 class MessageLoopForUI : public MessageLoop {
  public:
-  MessageLoopForUI() : MessageLoop(TYPE_UI) {
+  MessageLoopForUI(Type type=TYPE_UI) : MessageLoop(type) {
   }
 
+#ifndef CHROMIUM_MOZILLA_BUILD
   // Returns the MessageLoopForUI of the current thread.
   static MessageLoopForUI* current() {
     MessageLoop* loop = MessageLoop::current();
     DCHECK_EQ(MessageLoop::TYPE_UI, loop->type());
     return static_cast<MessageLoopForUI*>(loop);
   }
+#endif
 
 #if defined(OS_WIN)
   typedef base::MessagePumpWin::Dispatcher Dispatcher;
   typedef base::MessagePumpWin::Observer Observer;
 
   // Please see MessagePumpWin for definitions of these methods.
   void Run(Dispatcher* dispatcher);
   void AddObserver(Observer* observer);
--- a/ipc/chromium/src/chrome/common/child_process_host.cc
+++ b/ipc/chromium/src/chrome/common/child_process_host.cc
@@ -6,17 +6,17 @@
 
 #include "base/compiler_specific.h"
 #include "base/logging.h"
 #include "base/message_loop.h"
 #include "base/process_util.h"
 #include "base/singleton.h"
 #include "base/waitable_event.h"
 #ifdef CHROMIUM_MOZILLA_BUILD
-#include "mozilla/ipc/GeckoThread.h"
+#include "mozilla/ipc/BrowserProcessSubThread.h"
 typedef mozilla::ipc::BrowserProcessSubThread ChromeThread;
 #else
 #include "chrome/browser/chrome_thread.h"
 #endif
 #include "chrome/common/ipc_logging.h"
 #include "chrome/common/notification_service.h"
 #include "chrome/common/notification_type.h"
 #ifndef CHROMIUM_MOZILLA_BUILD
--- a/ipc/glue/AsyncChannel.cpp
+++ b/ipc/glue/AsyncChannel.cpp
@@ -33,17 +33,17 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/ipc/AsyncChannel.h"
-#include "mozilla/ipc/GeckoThread.h"
+#include "mozilla/ipc/BrowserProcessSubThread.h"
 #include "mozilla/ipc/ProtocolUtils.h"
 
 #include "nsDebug.h"
 #include "nsTraceRefcnt.h"
 #include "nsXULAppAPI.h"
 
 using mozilla::MutexAutoLock;
 
new file mode 100644
--- /dev/null
+++ b/ipc/glue/BrowserProcessSubThread.cpp
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=8 et :
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Plugin App.
+ *
+ * The Initial Developer of the Original Code is
+ *   Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "mozilla/ipc/BrowserProcessSubThread.h"
+#include "chrome/common/notification_service.h"
+
+#if defined(OS_WIN)
+#include <objbase.h>
+#endif
+
+namespace mozilla {
+namespace ipc {
+
+//
+// BrowserProcessSubThread
+//
+
+// Friendly names for the well-known threads.
+static const char* kBrowserThreadNames[BrowserProcessSubThread::ID_COUNT] = {
+  "Gecko_IOThread",  // IO
+//  "Chrome_FileThread",  // FILE
+//  "Chrome_DBThread",  // DB
+//  "Chrome_HistoryThread",  // HISTORY
+#if defined(OS_LINUX)
+  "Gecko_Background_X11Thread",  // BACKGROUND_X11
+#endif
+};
+
+Lock BrowserProcessSubThread::sLock;
+BrowserProcessSubThread* BrowserProcessSubThread::sBrowserThreads[ID_COUNT] = {
+  NULL,  // IO
+//  NULL,  // FILE
+//  NULL,  // DB
+//  NULL,  // HISTORY
+#if defined(OS_LINUX)
+  NULL,  // BACKGROUND_X11
+#endif
+};
+
+BrowserProcessSubThread::BrowserProcessSubThread(ID aId) :
+  base::Thread(kBrowserThreadNames[aId]),
+  mIdentifier(aId),
+  mNotificationService(NULL)
+{
+  AutoLock lock(sLock);
+  DCHECK(aId >= 0 && aId < ID_COUNT);
+  DCHECK(sBrowserThreads[aId] == NULL);
+  sBrowserThreads[aId] = this;
+}
+
+BrowserProcessSubThread::~BrowserProcessSubThread()
+{
+  Stop();
+  {AutoLock lock(sLock);
+    sBrowserThreads[mIdentifier] = NULL;
+  }
+
+}
+
+void
+BrowserProcessSubThread::Init()
+{
+#if defined(OS_WIN)
+  // Initializes the COM library on the current thread.
+  CoInitialize(NULL);
+#endif
+  mNotificationService = new NotificationService();
+}
+
+void
+BrowserProcessSubThread::CleanUp()
+{
+  delete mNotificationService;
+  mNotificationService = NULL;
+
+#if defined(OS_WIN)
+  // Closes the COM library on the current thread. CoInitialize must
+  // be balanced by a corresponding call to CoUninitialize.
+  CoUninitialize();
+#endif
+}
+
+// static
+MessageLoop*
+BrowserProcessSubThread::GetMessageLoop(ID aId)
+{
+  AutoLock lock(sLock);
+  DCHECK(aId >= 0 && aId < ID_COUNT);
+
+  if (sBrowserThreads[aId])
+    return sBrowserThreads[aId]->message_loop();
+
+  return NULL;
+}
+
+} // namespace ipc
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/ipc/glue/BrowserProcessSubThread.h
@@ -0,0 +1,115 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=8 et :
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Plugin App.
+ *
+ * The Initial Developer of the Original Code is
+ *   Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_ipc_BrowserProcessSubThread_h
+#define mozilla_ipc_BrowserProcessSubThread_h
+
+#include "base/thread.h"
+#include "base/lock.h"
+
+#include "nsDebug.h"
+
+class NotificationService;
+
+namespace mozilla {
+namespace ipc {
+
+// Copied from browser_process_impl.cc, modified slightly.
+class BrowserProcessSubThread : public base::Thread
+{
+public:
+  // An enumeration of the well-known threads.
+  enum ID {
+      IO,
+      //FILE,
+      //DB,
+      //HISTORY,
+#if defined(OS_LINUX)
+      // This thread has a second connection to the X server and is used
+      // to process UI requests when routing the request to the UI
+      // thread would risk deadlock.
+      BACKGROUND_X11,
+#endif
+
+      // This identifier does not represent a thread.  Instead it counts
+      // the number of well-known threads.  Insert new well-known
+      // threads before this identifier.
+      ID_COUNT
+  };
+
+  explicit BrowserProcessSubThread(ID aId);
+  ~BrowserProcessSubThread();
+
+  static MessageLoop* GetMessageLoop(ID identifier);
+
+protected:
+  virtual void Init();
+  virtual void CleanUp();
+
+private:
+  // The identifier of this thread.  Only one thread can exist with a given
+  // identifier at a given time.
+  ID mIdentifier;
+
+  NotificationService* mNotificationService;
+
+  // This lock protects |browser_threads_|.  Do not read or modify that array
+  // without holding this lock.  Do not block while holding this lock.
+
+  // FIXME/cjones: XPCOM doesn't like static vars, so can't use 
+  // mozilla::Mutex
+  static Lock sLock;
+
+  // An array of the ChromeThread objects.  This array is protected by |lock_|.
+  // The threads are not owned by this array.  Typically, the threads are owned
+  // on the UI thread by the g_browser_process object.  ChromeThreads remove
+  // themselves from this array upon destruction.
+  static BrowserProcessSubThread* sBrowserThreads[ID_COUNT];
+};
+
+inline void AssertIOThread()
+{
+  NS_ASSERTION(MessageLoop::TYPE_IO == MessageLoop::current()->type(),
+	       "should be on the IO thread!");
+}
+
+} // namespace ipc
+} // namespace mozilla
+
+#endif // mozilla_ipc_BrowserProcessSubThread_h
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -46,17 +46,17 @@
 
 #include "prprf.h"
 
 #if defined(OS_LINUX)
 #  define XP_LINUX 1
 #endif
 #include "nsExceptionHandler.h"
 
-#include "mozilla/ipc/GeckoThread.h"
+#include "mozilla/ipc/BrowserProcessSubThread.h"
 
 using mozilla::MonitorAutoEnter;
 using mozilla::ipc::GeckoChildProcessHost;
 
 template<>
 struct RunnableMethodTraits<GeckoChildProcessHost>
 {
     static void RetainCallee(GeckoChildProcessHost* obj) { }
deleted file mode 100644
--- a/ipc/glue/GeckoThread.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Plugin App.
- *
- * The Initial Developer of the Original Code is
- *   Ben Turner <bent.mozilla@gmail.com>.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "mozilla/ipc/GeckoThread.h"
-
-#include "chrome/common/notification_service.h"
-
-#include "nsXPCOM.h"
-
-#if defined(OS_WIN)
-#include <objbase.h>
-#endif
-
-using mozilla::ipc::GeckoThread;
-using mozilla::ipc::BrowserProcessSubThread;
-
-void
-GeckoThread::OnControlMessageReceived(const IPC::Message& aMessage) {
-  /*
-  IPC_BEGIN_MESSAGE_MAP(GeckoThread, aMessage)
-  IPC_END_MESSAGE_MAP()
-  */
-}
-
-void
-GeckoThread::Init()
-{
-  ChildThread::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);
-
-  NS_LogInit();
-  mXREEmbed.Start();
-}
-
-void
-GeckoThread::CleanUp()
-{
-  mXREEmbed.Stop();
-  NS_LogTerm();
-}
-
-//
-// BrowserProcessSubThread
-//
-
-// Friendly names for the well-known threads.
-static const char* kBrowserThreadNames[BrowserProcessSubThread::ID_COUNT] = {
-  "Gecko_IOThread",  // IO
-//  "Chrome_FileThread",  // FILE
-//  "Chrome_DBThread",  // DB
-//  "Chrome_HistoryThread",  // HISTORY
-#if defined(OS_LINUX)
-  "Gecko_Background_X11Thread",  // BACKGROUND_X11
-#endif
-};
-
-Lock BrowserProcessSubThread::sLock;
-BrowserProcessSubThread* BrowserProcessSubThread::sBrowserThreads[ID_COUNT] = {
-  NULL,  // IO
-//  NULL,  // FILE
-//  NULL,  // DB
-//  NULL,  // HISTORY
-#if defined(OS_LINUX)
-  NULL,  // BACKGROUND_X11
-#endif
-};
-
-BrowserProcessSubThread::BrowserProcessSubThread(ID aId) :
-    base::Thread(kBrowserThreadNames[aId]),
-    mIdentifier(aId),
-    mNotificationService(NULL)
-{
-    AutoLock lock(sLock);
-    DCHECK(aId >= 0 && aId < ID_COUNT);
-    DCHECK(sBrowserThreads[aId] == NULL);
-    sBrowserThreads[aId] = this;
-}
-
-BrowserProcessSubThread::~BrowserProcessSubThread()
-{
-    Stop();
-    {AutoLock lock(sLock);
-        sBrowserThreads[mIdentifier] = NULL;
-    }
-
-}
-
-void
-BrowserProcessSubThread::Init()
-{
-#if defined(OS_WIN)
-  // Initializes the COM library on the current thread.
-  CoInitialize(NULL);
-#endif
-  mNotificationService = new NotificationService();
-}
-
-void
-BrowserProcessSubThread::CleanUp()
-{
-  delete mNotificationService;
-  mNotificationService = NULL;
-
-#if defined(OS_WIN)
-  // Closes the COM library on the current thread. CoInitialize must
-  // be balanced by a corresponding call to CoUninitialize.
-  CoUninitialize();
-#endif
-}
-
-// static
-MessageLoop*
-BrowserProcessSubThread::GetMessageLoop(ID aId) {
-  AutoLock lock(sLock);
-  DCHECK(aId >= 0 && aId < ID_COUNT);
-
-  if (sBrowserThreads[aId])
-    return sBrowserThreads[aId]->message_loop();
-
-  return NULL;
-}
deleted file mode 100644
--- a/ipc/glue/GeckoThread.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Plugin App.
- *
- * The Initial Developer of the Original Code is
- *   Ben Turner <bent.mozilla@gmail.com>.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef __IPC_GLUE_GECKOTHREAD_H__
-#define __IPC_GLUE_GECKOTHREAD_H__
-
-#include "base/thread.h"
-#include "base/lock.h"
-#include "base/process.h"
-
-#include "chrome/common/child_thread.h"
-
-#include "nsDebug.h"
-
-#include "mozilla/ipc/ScopedXREEmbed.h"
-
-class NotificationService;
-
-namespace mozilla {
-namespace ipc {
-
-inline void AssertIOThread()
-{
-    NS_ASSERTION(MessageLoop::TYPE_IO == MessageLoop::current()->type(),
-                 "should be on the IO thread!");
-}
-
-class GeckoThread : public ChildThread
-{
-public:
-  typedef base::ProcessHandle ProcessHandle;
-
-  GeckoThread(ProcessHandle aParentProcessHandle)
-  : ChildThread(base::Thread::Options(
-                    MessageLoop::TYPE_MOZILLA_CHILD, // message loop type
-                    0,                               // stack size
-                    false)),                         // wait for Init()?
-    mParentProcessHandle(aParentProcessHandle)
-  { }
-
-protected:
-  virtual void OnControlMessageReceived(const IPC::Message& aMessage);
-
-  ProcessHandle GetParentProcessHandle() {
-    return mParentProcessHandle;
-  }
-
-  // Thread implementation:
-  virtual void Init();
-  virtual void CleanUp();
-
-  ScopedXREEmbed mXREEmbed;
-
-private:
-  ProcessHandle mParentProcessHandle;
-
-  DISALLOW_EVIL_CONSTRUCTORS(GeckoThread);
-};
-
-// Copied from browser_process_impl.cc, modified slightly.
-class BrowserProcessSubThread : public base::Thread
-{
-public:
-  // An enumeration of the well-known threads.
-  enum ID {
-      IO,
-      //FILE,
-      //DB,
-      //HISTORY,
-#if defined(OS_LINUX)
-      // This thread has a second connection to the X server and is used
-      // to process UI requests when routing the request to the UI
-      // thread would risk deadlock.
-      BACKGROUND_X11,
-#endif
-
-      // This identifier does not represent a thread.  Instead it counts
-      // the number of well-known threads.  Insert new well-known
-      // threads before this identifier.
-      ID_COUNT
-  };
-
-  explicit BrowserProcessSubThread(ID aId);
-  ~BrowserProcessSubThread();
-
-  static MessageLoop* GetMessageLoop(ID identifier);
-
-protected:
-  virtual void Init();
-  virtual void CleanUp();
-
-private:
-  // The identifier of this thread.  Only one thread can exist with a given
-  // identifier at a given time.
-  ID mIdentifier;
-
-  NotificationService* mNotificationService;
-
-  // This lock protects |browser_threads_|.  Do not read or modify that array
-  // without holding this lock.  Do not block while holding this lock.
-
-  // FIXME/cjones: XPCOM doesn't like static vars, so can't use 
-  // mozilla::Mutex
-  static Lock sLock;
-
-  // An array of the ChromeThread objects.  This array is protected by |lock_|.
-  // The threads are not owned by this array.  Typically, the threads are owned
-  // on the UI thread by the g_browser_process object.  ChromeThreads remove
-  // themselves from this array upon destruction.
-  static BrowserProcessSubThread* sBrowserThreads[ID_COUNT];
-};
-
-} /* namespace ipc */
-} /* namespace mozilla */
-
-#endif /* __IPC_GLUE_GECKOTHREAD_H__ */
--- a/ipc/glue/Makefile.in
+++ b/ipc/glue/Makefile.in
@@ -50,32 +50,34 @@ LIBXUL_LIBRARY = 1
 EXPORT_LIBRARY = 1
 
 EXPORTS_NAMESPACES = IPC mozilla/ipc
 
 EXPORTS_IPC = IPCMessageUtils.h
 
 EXPORTS_mozilla/ipc = \
   AsyncChannel.h \
+  BrowserProcessSubThread.h \
   GeckoChildProcessHost.h \
-  GeckoThread.h \
+  MozillaChildThread.h \
   ProtocolUtils.h \
   RPCChannel.h \
   SharedMemory.h \
   Shmem.h \
   SyncChannel.h \
   ScopedXREEmbed.h \
   $(NULL)
 
 ENABLE_CXX_EXCEPTIONS = 1
 
 CPPSRCS += \
   AsyncChannel.cpp \
+  BrowserProcessSubThread.cpp \
   GeckoChildProcessHost.cpp \
-  GeckoThread.cpp \
+  MozillaChildThread.cpp \
   MessagePump.cpp \
   RPCChannel.cpp \
   ScopedXREEmbed.cpp \
   Shmem.cpp \
   StringUtil.cpp \
   SyncChannel.cpp \
   $(NULL)
 
new file mode 100644
--- /dev/null
+++ b/ipc/glue/MozillaChildThread.cpp
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=8 et :
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Plugin App.
+ *
+ * The Initial Developer of the Original Code is
+ *   Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "mozilla/ipc/MozillaChildThread.h"
+
+#include "nsXPCOM.h"
+
+namespace mozilla {
+namespace ipc {
+
+void
+MozillaChildThread::OnControlMessageReceived(const IPC::Message& aMessage) {
+  /*
+  IPC_BEGIN_MESSAGE_MAP(MozillaChildThread, aMessage)
+  IPC_END_MESSAGE_MAP()
+  */
+}
+
+void
+MozillaChildThread::Init()
+{
+  ChildThread::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);
+
+  NS_LogInit();
+}
+
+void
+MozillaChildThread::CleanUp()
+{
+  NS_LogTerm();
+}
+
+} // namespace ipc
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/ipc/glue/MozillaChildThread.h
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=8 et :
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Plugin App.
+ *
+ * The Initial Developer of the Original Code is
+ *   Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_ipc_MozillaChildThread_h
+#define mozilla_ipc_MozillaChildThread_h
+
+#include "base/thread.h"
+#include "base/process.h"
+
+#include "chrome/common/child_thread.h"
+
+namespace mozilla {
+namespace ipc {
+
+/**
+ * A MozillaChildThread is the main thread in a child process. It will
+ * initialize XPCOM leak detectors (NS_LogInit) but it will not initialize
+ * XPCOM (see ContentProcessThread for a child which uses XPCOM).
+ */
+class MozillaChildThread : public ChildThread
+{
+public:
+  typedef base::ProcessHandle ProcessHandle;
+
+  MozillaChildThread(ProcessHandle aParentProcessHandle,
+		     MessageLoop::Type type=MessageLoop::TYPE_UI)
+  : ChildThread(base::Thread::Options(type,    // message loop type
+				      0,       // stack size
+				      false)), // wait for Init()?
+    mParentProcessHandle(aParentProcessHandle)
+  { }
+
+protected:
+  virtual void OnControlMessageReceived(const IPC::Message& aMessage);
+
+  ProcessHandle GetParentProcessHandle() {
+    return mParentProcessHandle;
+  }
+
+  // Thread implementation:
+  virtual void Init();
+  virtual void CleanUp();
+
+private:
+  ProcessHandle mParentProcessHandle;
+
+  DISALLOW_EVIL_CONSTRUCTORS(MozillaChildThread);
+};
+
+} /* namespace ipc */
+} /* namespace mozilla */
+
+#endif /* mozilla_ipc_MozillaChildThread_h */
--- a/ipc/glue/RPCChannel.cpp
+++ b/ipc/glue/RPCChannel.cpp
@@ -33,17 +33,16 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/ipc/RPCChannel.h"
-#include "mozilla/ipc/GeckoThread.h"
 
 #include "nsDebug.h"
 #include "nsTraceRefcnt.h"
 
 #define RPC_ASSERT(_cond, ...)                                      \
     do {                                                            \
         if (!(_cond))                                               \
             DebugAbort(__FILE__, __LINE__, #_cond,## __VA_ARGS__);  \
--- a/ipc/glue/SyncChannel.cpp
+++ b/ipc/glue/SyncChannel.cpp
@@ -33,17 +33,16 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/ipc/SyncChannel.h"
-#include "mozilla/ipc/GeckoThread.h"
 
 #include "nsDebug.h"
 #include "nsTraceRefcnt.h"
 
 using mozilla::MutexAutoLock;
 
 template<>
 struct RunnableMethodTraits<mozilla::ipc::SyncChannel>
--- a/ipc/ipdl/test/cxx/IPDLUnitTestThreadChild.cpp
+++ b/ipc/ipdl/test/cxx/IPDLUnitTestThreadChild.cpp
@@ -35,37 +35,31 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "IPDLUnitTestThreadChild.h"
 
 #include "IPDLUnitTests.h"
 
-using mozilla::ipc::GeckoThread;
+using mozilla::ipc::MozillaChildThread;
 
 namespace mozilla {
 namespace _ipdltest {
 
 IPDLUnitTestThreadChild::IPDLUnitTestThreadChild(ProcessHandle aParentHandle) :
-    GeckoThread(aParentHandle)
+    MozillaChildThread(aParentHandle)
 {
 }
 
 IPDLUnitTestThreadChild::~IPDLUnitTestThreadChild()
 {
 }
 
 void
 IPDLUnitTestThreadChild::Init()
 {
-    GeckoThread::Init();
+    MozillaChildThread::Init();
     IPDLUnitTestChildInit(channel(), GetParentProcessHandle(), owner_loop());
 }
 
-void
-IPDLUnitTestThreadChild::CleanUp()
-{
-    GeckoThread::CleanUp();
-}
-
 } // namespace _ipdltest
 } // namespace mozilla
--- a/ipc/ipdl/test/cxx/IPDLUnitTestThreadChild.h
+++ b/ipc/ipdl/test/cxx/IPDLUnitTestThreadChild.h
@@ -34,28 +34,27 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef mozilla__ipdltest_IPDLUnitTestThreadChild_h
 #define mozilla__ipdltest_IPDLUnitTestThreadChild_h 1
 
-#include "mozilla/ipc/GeckoThread.h"
+#include "mozilla/ipc/MozillaChildThread.h"
 
 namespace mozilla {
 namespace _ipdltest {
 
-class IPDLUnitTestThreadChild : public mozilla::ipc::GeckoThread
+class IPDLUnitTestThreadChild : public mozilla::ipc::MozillaChildThread
 {
 public:
   IPDLUnitTestThreadChild(ProcessHandle aParentHandle);
   ~IPDLUnitTestThreadChild();
 
 protected:
   virtual void Init();
-  virtual void CleanUp();
 };
 
 } // namespace _ipdltest
 } // namespace mozilla
 
 #endif // ifndef mozilla__ipdltest_IPDLUnitTestThreadChild_h
--- a/ipc/ipdl/test/cxx/IPDLUnitTests.h
+++ b/ipc/ipdl/test/cxx/IPDLUnitTests.h
@@ -38,18 +38,16 @@
 
 #ifndef mozilla__ipdltest_IPDLUnitTests_h
 #define mozilla__ipdltest_IPDLUnitTests_h 1
 
 #include "base/message_loop.h"
 #include "base/process.h"
 #include "chrome/common/ipc_channel.h"
 
-#include "mozilla/ipc/GeckoThread.h"
-
 #include "nsIAppShell.h"
 
 #include "nsCOMPtr.h"
 #include "nsDebug.h"
 #include "nsServiceManagerUtils.h" // do_GetService()
 #include "nsWidgetsCID.h"       // NS_APPSHELL_CID
 #include "nsXULAppAPI.h"
 
--- a/toolkit/xre/nsEmbedFunctions.cpp
+++ b/toolkit/xre/nsEmbedFunctions.cpp
@@ -54,16 +54,20 @@
 #include "nsILocalFile.h"
 #include "nsIToolkitChromeRegistry.h"
 #include "nsIToolkitProfile.h"
 
 #if defined(OS_LINUX)
 #  define XP_LINUX
 #endif
 
+#ifdef XP_WIN
+#include <process.h>
+#endif
+
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsAppRunner.h"
 #include "nsAutoRef.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsExceptionHandler.h"
 #include "nsStaticComponents.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
@@ -74,32 +78,31 @@
 #ifdef MOZ_IPC
 #include "base/at_exit.h"
 #include "base/command_line.h"
 #include "base/message_loop.h"
 #include "base/process_util.h"
 #include "chrome/common/child_process.h"
 
 #include "mozilla/ipc/GeckoChildProcessHost.h"
-#include "mozilla/ipc/GeckoThread.h"
+#include "mozilla/ipc/BrowserProcessSubThread.h"
 #include "ScopedXREEmbed.h"
 
 #include "mozilla/plugins/PluginThreadChild.h"
 
 #include "mozilla/Monitor.h"
 
 #ifdef MOZ_IPDL_TESTS
 #include "mozilla/_ipdltest/IPDLUnitTests.h"
 #include "mozilla/_ipdltest/IPDLUnitTestThreadChild.h"
 
 using mozilla::_ipdltest::IPDLUnitTestThreadChild;
 #endif  // ifdef MOZ_IPDL_TESTS
 
 using mozilla::ipc::GeckoChildProcessHost;
-using mozilla::ipc::GeckoThread;
 using mozilla::ipc::BrowserProcessSubThread;
 using mozilla::ipc::ScopedXREEmbed;
 
 using mozilla::plugins::PluginThreadChild;
 
 using mozilla::Monitor;
 using mozilla::MonitorAutoEnter;
 
@@ -290,16 +293,17 @@ XRE_InitChildProcess(int aArgc,
   g_thread_init(NULL);
 #endif
 
   if (PR_GetEnv("MOZ_DEBUG_CHILD_PROCESS")) {
 #ifdef OS_POSIX
       printf("\n\nCHILDCHILDCHILDCHILD\n  debug me @%d\n\n", getpid());
       sleep(30);
 #elif defined(OS_WIN)
+      printf("\n\nCHILDCHILDCHILDCHILD\n  debug me @%d\n\n", _getpid());
       Sleep(30000);
 #endif
   }
 
   // child processes launched by GeckoChildProcessHost get this magic
   // argument appended to their command lines
   const char* const parentPIDString = aArgv[aArgc-1];
   NS_ABORT_IF_FALSE(parentPIDString, "NULL parent PID");
@@ -325,17 +329,17 @@ XRE_InitChildProcess(int aArgc,
 
   MessageLoopForIO mainMessageLoop;
 
   {
     ChildThread* mainThread;
 
     switch (aProcess) {
     case GeckoProcessType_Default:
-      mainThread = new GeckoThread(parentHandle);
+      NS_RUNTIMEABORT("This makes no sense");
       break;
 
     case GeckoProcessType_Plugin:
       mainThread = new PluginThreadChild(parentHandle);
       break;
 
     case GeckoProcessType_IPDLUnitTest:
 #ifdef MOZ_IPDL_TESTS
@@ -473,18 +477,18 @@ XRE_RunAppShell()
     NS_ENSURE_TRUE(appShell, NS_ERROR_FAILURE);
 
     return appShell->Run();
 }
 
 void
 XRE_ShutdownChildProcess()
 {
-    NS_ABORT_IF_FALSE(NS_IsMainThread(), "Wrong thread!");
+  NS_ABORT_IF_FALSE(MessageLoopForUI::current(), "Wrong thread!");
 
-    MessageLoop* ioLoop = XRE_GetIOMessageLoop();
-    NS_ABORT_IF_FALSE(!!ioLoop, "Bad shutdown order");
+  MessageLoop* ioLoop = XRE_GetIOMessageLoop();
+  NS_ABORT_IF_FALSE(!!ioLoop, "Bad shutdown order");
 
-    ioLoop->PostTask(FROM_HERE, new MessageLoop::QuitTask());
+  ioLoop->PostTask(FROM_HERE, new MessageLoop::QuitTask());
 }
 
 #endif // MOZ_IPC
 
--- a/xpcom/base/Makefile.in
+++ b/xpcom/base/Makefile.in
@@ -136,8 +136,9 @@ FORCE_USE_PIC	= 1
 include $(topsrcdir)/config/rules.mk
 
 DEFINES		+= -D_IMPL_NS_COM
 
 ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT)))
 CXXFLAGS        += $(MOZ_GTK2_CFLAGS)
 endif
 
+LOCAL_INCLUDES += -I$(srcdir)/../build
--- a/xpcom/base/nsTraceRefcntImpl.cpp
+++ b/xpcom/base/nsTraceRefcntImpl.cpp
@@ -32,16 +32,17 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsTraceRefcntImpl.h"
+#include "nsXPCOMPrivate.h"
 #include "nscore.h"
 #include "nsISupports.h"
 #include "nsTArray.h"
 #include "prprf.h"
 #include "prlog.h"
 #include "plstr.h"
 #include "prlink.h"
 #include <stdlib.h>
@@ -60,16 +61,18 @@
 #include <unistd.h>
 #endif
 #endif
 
 #ifdef NS_TRACE_MALLOC
 #include "nsTraceMalloc.h"
 #endif
 
+#include "mozilla/BlockingResourceBase.h"
+
 #ifdef HAVE_LIBDL
 #include <dlfcn.h>
 #endif
 
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_COM void
 NS_MeanAndStdDev(double n, double sumOfValues, double sumOfSquaredValues,
@@ -917,32 +920,57 @@ NS_LogInit()
   if (!NS_TraceMallocHasStarted())
     NS_TraceMallocStartup(-1);  // -1 == no logging
 #endif
 }
 
 EXPORT_XPCOM_API(void)
 NS_LogTerm()
 {
+  mozilla::LogTerm();
+}
+
+namespace mozilla {
+void
+LogTerm()
+{
   NS_ASSERTION(gInitCount > 0,
                "NS_LogTerm without matching NS_LogInit");
 
   if (--gInitCount == 0) {
+#ifdef DEBUG
+    /* FIXME bug 491977: This is only going to operate on the
+     * BlockingResourceBase which is compiled into
+     * libxul/libxpcom_core.so. Anyone using external linkage will
+     * have their own copy of BlockingResourceBase statics which will
+     * not be freed by this method.
+     *
+     * It sounds like what we really want is to be able to register a
+     * callback function to call at XPCOM shutdown.  Note that with
+     * this solution, however, we need to guarantee that
+     * BlockingResourceBase::Shutdown() runs after all other shutdown
+     * functions.
+     */
+    BlockingResourceBase::Shutdown();
+#endif
+    
     if (gInitialized) {
       nsTraceRefcntImpl::DumpStatistics();
       nsTraceRefcntImpl::ResetStatistics();
     }
     nsTraceRefcntImpl::Shutdown();
 #ifdef NS_IMPL_REFCNT_LOGGING
     nsTraceRefcntImpl::SetActivityIsLegal(PR_FALSE);
     gActivityTLS = BAD_TLS_INDEX;
 #endif
   }
 }
 
+} // namespace mozilla
+
 EXPORT_XPCOM_API(void)
 NS_LogAddRef(void* aPtr, nsrefcnt aRefcnt,
              const char* aClazz, PRUint32 classSize)
 {
 #ifdef NS_IMPL_REFCNT_LOGGING
   ASSERT_ACTIVITY_IS_LEGAL;
   if (!gInitialized)
     InitTraceLog();
--- a/xpcom/build/nsXPCOMPrivate.h
+++ b/xpcom/build/nsXPCOMPrivate.h
@@ -219,16 +219,21 @@ namespace mozilla {
  *
  * @return NS_OK for success;
  *         other error codes indicate a failure during shutdown
  *
  */
 nsresult
 ShutdownXPCOM(nsIServiceManager* servMgr);
 
+/**
+ * C++ namespaced version of NS_LogTerm.
+ */
+void LogTerm();
+
 } // namespace mozilla
 
 
 // think hard before changing this
 #define XPCOM_GLUE_VERSION 1
 
 
 /* XPCOM Specific Defines
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -75,20 +75,16 @@
 #include "nsComponentManager.h"
 #include "nsCategoryManagerUtils.h"
 #include "nsIServiceManager.h"
 #include "nsGenericFactory.h"
 
 #include "nsThreadManager.h"
 #include "nsThreadPool.h"
 
-#ifdef DEBUG
-#include "BlockingResourceBase.h"
-#endif // ifdef DEBUG
-
 #include "nsIProxyObjectManager.h"
 #include "nsProxyEventPrivate.h"  // access to the impl of nsProxyObjectManager for the generic factory registration.
 
 #include "xptinfo.h"
 #include "nsIInterfaceInfoManager.h"
 #include "xptiprivate.h"
 
 #include "nsTimerImpl.h"
@@ -147,17 +143,17 @@ NS_DECL_CLASSINFO(nsStringInputStream)
 
 #include <locale.h>
 
 #ifdef MOZ_IPC
 #include "base/at_exit.h"
 #include "base/command_line.h"
 #include "base/message_loop.h"
 
-#include "mozilla/ipc/GeckoThread.h"
+#include "mozilla/ipc/BrowserProcessSubThread.h"
 
 using base::AtExitManager;
 using mozilla::ipc::BrowserProcessSubThread;
 
 namespace {
 
 static AtExitManager* sExitManager;
 static MessageLoop* sMessageLoop;
@@ -497,17 +493,17 @@ NS_InitXPCOM3(nsIServiceManager* *result
     NS_ASSERTION(!sExitManager && !sMessageLoop, "Bad logic!");
 
     if (!AtExitManager::AlreadyRegistered()) {
         sExitManager = new AtExitManager();
         NS_ENSURE_STATE(sExitManager);
     }
 
     if (!MessageLoop::current()) {
-        sMessageLoop = new MessageLoopForUI();
+        sMessageLoop = new MessageLoopForUI(MessageLoop::TYPE_MOZILLA_UI);
         NS_ENSURE_STATE(sMessageLoop);
     }
 
     if (XRE_GetProcessType() == GeckoProcessType_Default &&
         !BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)) {
         scoped_ptr<BrowserProcessSubThread> ioThread(
             new BrowserProcessSubThread(BrowserProcessSubThread::IO));
         NS_ENSURE_TRUE(ioThread.get(), NS_ERROR_OUT_OF_MEMORY);
@@ -885,32 +881,16 @@ ShutdownXPCOM(nsIServiceManager* servMgr
     ShutdownSpecialSystemDirectory();
 
     NS_PurgeAtomTable();
 
     NS_IF_RELEASE(gDebug);
 
     TimeStamp::Shutdown();
 
-#ifdef DEBUG
-    /* FIXME bug 491977: This is only going to operate on the
-     * BlockingResourceBase which is compiled into
-     * libxul/libxpcom_core.so. Anyone using external linkage will
-     * have their own copy of BlockingResourceBase statics which will
-     * not be freed by this method.
-     *
-     * It sounds like what we really want is to be able to register a
-     * callback function to call at XPCOM shutdown.  Note that with
-     * this solution, however, we need to guarantee that
-     * BlockingResourceBase::Shutdown() runs after all other shutdown
-     * functions.
-     */
-    BlockingResourceBase::Shutdown();
-#endif
-    
     NS_LogTerm();
 
 #ifdef MOZ_IPC
     if (sIOThread) {
         delete sIOThread;
         sIOThread = nsnull;
     }
     if (sMessageLoop) {
--- a/xpcom/glue/BlockingResourceBase.h
+++ b/xpcom/glue/BlockingResourceBase.h
@@ -50,16 +50,17 @@
 
 #ifdef DEBUG
 #include "prinit.h"
 #include "prthread.h"
 
 #include "nsStringGlue.h"
 
 #include "mozilla/DeadlockDetector.h"
+#include "nsXPCOM.h"
 #endif
 
 //
 // This header is not meant to be included by client code.
 //
 
 namespace mozilla {
 
@@ -350,17 +351,17 @@ private:
      */
     static void Shutdown() {
         delete sDeadlockDetector;
         sDeadlockDetector = 0;
     }
 
 #  ifdef MOZILLA_INTERNAL_API
     // so it can call BlockingResourceBase::Shutdown()
-    friend nsresult ShutdownXPCOM(nsIServiceManager*);
+    friend void LogTerm();
 #  endif  // ifdef MOZILLA_INTERNAL_API
 
 #else  // non-DEBUG implementation
 
     BlockingResourceBase(const char* aName, BlockingResourceType aType)
     {
     }