diff --git a/dom/plugins/ChildAsyncCall.cpp b/dom/plugins/ChildAsyncCall.cpp index 0f4dc5a378a..574ccdd7e94 100644 --- a/dom/plugins/ChildAsyncCall.cpp +++ b/dom/plugins/ChildAsyncCall.cpp @@ -60,14 +60,13 @@ ChildAsyncCall::Cancel() mData = NULL; } -NS_IMETHODIMP +void ChildAsyncCall::Run() { if (mFunc) { mInstance->mPendingAsyncCalls.RemoveElement(this); mFunc(mData); } - return NS_OK; } } // namespace plugins diff --git a/dom/plugins/ChildAsyncCall.h b/dom/plugins/ChildAsyncCall.h index 23fd568fd85..e4346f69196 100644 --- a/dom/plugins/ChildAsyncCall.h +++ b/dom/plugins/ChildAsyncCall.h @@ -42,7 +42,7 @@ #define mozilla_plugins_ChildAsyncCall_h #include "PluginMessageUtils.h" -#include "nsThreadUtils.h" +#include "base/task.h" namespace mozilla { namespace plugins { @@ -51,14 +51,14 @@ 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; diff --git a/dom/plugins/ChildTimer.cpp b/dom/plugins/ChildTimer.cpp index 991b2f4b1ff..abdee788237 100644 --- a/dom/plugins/ChildTimer.cpp +++ b/dom/plugins/ChildTimer.cpp @@ -51,38 +51,22 @@ ChildTimer::ChildTimer(PluginInstanceChild* instance, 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(aClosure); - self->mFunc(self->mInstance->GetNPP(), self->mID); + if (!mRepeating) + mTimer.Stop(); + mFunc(mInstance->GetNPP(), mID); } } // namespace plugins diff --git a/dom/plugins/ChildTimer.h b/dom/plugins/ChildTimer.h index 0891567d8eb..542b3a4ed0c 100644 --- a/dom/plugins/ChildTimer.h +++ b/dom/plugins/ChildTimer.h @@ -43,8 +43,7 @@ #include "PluginMessageUtils.h" #include "npapi.h" -#include "nsITimer.h" -#include "nsCOMPtr.h" +#include "base/timer.h" namespace mozilla { namespace plugins { @@ -62,17 +61,10 @@ public: 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: @@ -84,11 +76,13 @@ public: private: PluginInstanceChild* mInstance; TimerFunc mFunc; + bool mRepeating; uint32_t mID; - nsCOMPtr mTimer; + base::RepeatingTimer mTimer; + + void Run(); static uint32_t gNextTimerID; - static void Callback(nsITimer* aTimer, void* aClosure); }; } // namespace plugins diff --git a/dom/plugins/PluginInstanceChild.cpp b/dom/plugins/PluginInstanceChild.cpp index 49d13a04504..1bd582c6c20 100644 --- a/dom/plugins/PluginInstanceChild.cpp +++ b/dom/plugins/PluginInstanceChild.cpp @@ -1144,12 +1144,7 @@ PluginInstanceChild::UnscheduleTimer(uint32_t id) if (0 == id) return; - PRUint32 i = mTimers.IndexOf(id, 0, ChildTimer::IDComparator()); - if (nsTArray::NoIndex == i) - return; - - mTimers.ElementAt(i)->Destroy(); - mTimers.RemoveElementAt(i); + mTimers.RemoveElement(id, ChildTimer::IDComparator()); } bool @@ -1159,9 +1154,7 @@ PluginInstanceChild::AnswerNPP_Destroy(NPError* aResult) 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); diff --git a/dom/plugins/PluginInstanceChild.h b/dom/plugins/PluginInstanceChild.h index 8ce9fdf0386..7764fab1578 100644 --- a/dom/plugins/PluginInstanceChild.h +++ b/dom/plugins/PluginInstanceChild.h @@ -215,7 +215,7 @@ private: friend class ChildAsyncCall; nsTArray mPendingAsyncCalls; - nsTArray mTimers; + nsTArray > mTimers; #if defined(OS_WIN) private: diff --git a/dom/plugins/PluginMessageUtils.h b/dom/plugins/PluginMessageUtils.h index 01870d086b2..9f6bdaec02e 100644 --- a/dom/plugins/PluginMessageUtils.h +++ b/dom/plugins/PluginMessageUtils.h @@ -40,6 +40,7 @@ #define DOM_PLUGINS_PLUGINMESSAGEUTILS_H #include "IPC/IPCMessageUtils.h" +#include "base/message_loop.h" #include "npapi.h" #include "npruntime.h" @@ -197,7 +198,8 @@ NPNVariableToString(NPNVariable aVar) 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); diff --git a/dom/plugins/PluginModuleChild.cpp b/dom/plugins/PluginModuleChild.cpp index 79ee1d2ef2d..af96f7a3e40 100644 --- a/dom/plugins/PluginModuleChild.cpp +++ b/dom/plugins/PluginModuleChild.cpp @@ -55,6 +55,7 @@ #include "mozilla/plugins/StreamNotifyChild.h" #include "mozilla/plugins/BrowserStreamChild.h" #include "mozilla/plugins/PluginStreamChild.h" +#include "mozilla/plugins/PluginThreadChild.h" #include "nsNPAPIPlugin.h" @@ -1253,8 +1254,9 @@ _pluginthreadasynccall(NPP aNPP, if (!aFunc) return; - nsCOMPtr 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 diff --git a/dom/plugins/PluginProcessParent.cpp b/dom/plugins/PluginProcessParent.cpp index f48d20d95cb..ec5cba042bc 100644 --- a/dom/plugins/PluginProcessParent.cpp +++ b/dom/plugins/PluginProcessParent.cpp @@ -40,7 +40,7 @@ #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; diff --git a/dom/plugins/PluginThreadChild.cpp b/dom/plugins/PluginThreadChild.cpp index b5f16a99f5d..965dfe34faf 100644 --- a/dom/plugins/PluginThreadChild.cpp +++ b/dom/plugins/PluginThreadChild.cpp @@ -46,25 +46,29 @@ #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; @@ -97,7 +101,7 @@ void PluginThreadChild::CleanUp() { mPlugin.CleanUp(); - GeckoThread::CleanUp(); + MozillaChildThread::CleanUp(); } } // namespace plugins diff --git a/dom/plugins/PluginThreadChild.h b/dom/plugins/PluginThreadChild.h index 66b6e7ae8f5..0b5504df56d 100644 --- a/dom/plugins/PluginThreadChild.h +++ b/dom/plugins/PluginThreadChild.h @@ -42,10 +42,10 @@ #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 { @@ -54,20 +54,22 @@ 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; diff --git a/ipc/chromium/Makefile.in b/ipc/chromium/Makefile.in index 1bf4d509a0f..0be39c2d001 100644 --- a/ipc/chromium/Makefile.in +++ b/ipc/chromium/Makefile.in @@ -246,6 +246,7 @@ CPPSRCS += \ 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) diff --git a/ipc/chromium/src/base/message_loop.cc b/ipc/chromium/src/base/message_loop.cc index 79e364f0f77..f01501ef9b9 100644 --- a/ipc/chromium/src/base/message_loop.cc +++ b/ipc/chromium/src/base/message_loop.cc @@ -19,7 +19,7 @@ #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 @@ -89,7 +89,7 @@ MessageLoop::MessageLoop(Type type) 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; } @@ -112,7 +112,7 @@ MessageLoop::MessageLoop(Type type) 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) { diff --git a/ipc/chromium/src/base/message_loop.h b/ipc/chromium/src/base/message_loop.h index e8d8f284bd1..8f4004d1ef1 100644 --- a/ipc/chromium/src/base/message_loop.h +++ b/ipc/chromium/src/base/message_loop.h @@ -196,12 +196,21 @@ public: // 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 }; @@ -421,15 +430,17 @@ public: // 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(loop); } +#endif #if defined(OS_WIN) typedef base::MessagePumpWin::Dispatcher Dispatcher; diff --git a/ipc/chromium/src/chrome/common/child_process_host.cc b/ipc/chromium/src/chrome/common/child_process_host.cc index 88527e4f1c6..dde7e669d83 100644 --- a/ipc/chromium/src/chrome/common/child_process_host.cc +++ b/ipc/chromium/src/chrome/common/child_process_host.cc @@ -11,7 +11,7 @@ #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" diff --git a/ipc/glue/AsyncChannel.cpp b/ipc/glue/AsyncChannel.cpp index c67acc617cb..3e2db715710 100644 --- a/ipc/glue/AsyncChannel.cpp +++ b/ipc/glue/AsyncChannel.cpp @@ -38,7 +38,7 @@ * ***** 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" diff --git a/ipc/glue/GeckoThread.cpp b/ipc/glue/BrowserProcessSubThread.cpp similarity index 75% rename from ipc/glue/GeckoThread.cpp rename to ipc/glue/BrowserProcessSubThread.cpp index 42b76f42eff..e51db3c46a2 100644 --- a/ipc/glue/GeckoThread.cpp +++ b/ipc/glue/BrowserProcessSubThread.cpp @@ -1,3 +1,6 @@ +/* -*- 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 * @@ -34,46 +37,15 @@ * * ***** END LICENSE BLOCK ***** */ -#include "mozilla/ipc/GeckoThread.h" - +#include "mozilla/ipc/BrowserProcessSubThread.h" #include "chrome/common/notification_service.h" -#include "nsXPCOM.h" - #if defined(OS_WIN) #include #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(); -} +namespace mozilla { +namespace ipc { // // BrowserProcessSubThread @@ -102,22 +74,22 @@ BrowserProcessSubThread* BrowserProcessSubThread::sBrowserThreads[ID_COUNT] = { }; BrowserProcessSubThread::BrowserProcessSubThread(ID aId) : - base::Thread(kBrowserThreadNames[aId]), - mIdentifier(aId), - mNotificationService(NULL) + base::Thread(kBrowserThreadNames[aId]), + mIdentifier(aId), + mNotificationService(NULL) { - AutoLock lock(sLock); - DCHECK(aId >= 0 && aId < ID_COUNT); - DCHECK(sBrowserThreads[aId] == NULL); - sBrowserThreads[aId] = this; + 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; - } + Stop(); + {AutoLock lock(sLock); + sBrowserThreads[mIdentifier] = NULL; + } } @@ -146,7 +118,8 @@ BrowserProcessSubThread::CleanUp() // static MessageLoop* -BrowserProcessSubThread::GetMessageLoop(ID aId) { +BrowserProcessSubThread::GetMessageLoop(ID aId) +{ AutoLock lock(sLock); DCHECK(aId >= 0 && aId < ID_COUNT); @@ -155,3 +128,6 @@ BrowserProcessSubThread::GetMessageLoop(ID aId) { return NULL; } + +} // namespace ipc +} // namespace mozilla diff --git a/ipc/glue/GeckoThread.h b/ipc/glue/BrowserProcessSubThread.h similarity index 74% rename from ipc/glue/GeckoThread.h rename to ipc/glue/BrowserProcessSubThread.h index 0d2feda9840..68c89732f31 100644 --- a/ipc/glue/GeckoThread.h +++ b/ipc/glue/BrowserProcessSubThread.h @@ -1,3 +1,6 @@ +/* -*- 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 * @@ -34,62 +37,19 @@ * * ***** END LICENSE BLOCK ***** */ -#ifndef __IPC_GLUE_GECKOTHREAD_H__ -#define __IPC_GLUE_GECKOTHREAD_H__ +#ifndef mozilla_ipc_BrowserProcessSubThread_h +#define mozilla_ipc_BrowserProcessSubThread_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 { @@ -143,7 +103,13 @@ private: static BrowserProcessSubThread* sBrowserThreads[ID_COUNT]; }; -} /* namespace ipc */ -} /* namespace mozilla */ +inline void AssertIOThread() +{ + NS_ASSERTION(MessageLoop::TYPE_IO == MessageLoop::current()->type(), + "should be on the IO thread!"); +} -#endif /* __IPC_GLUE_GECKOTHREAD_H__ */ +} // namespace ipc +} // namespace mozilla + +#endif // mozilla_ipc_BrowserProcessSubThread_h diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp index 6a2f7013f49..502e4317755 100644 --- a/ipc/glue/GeckoChildProcessHost.cpp +++ b/ipc/glue/GeckoChildProcessHost.cpp @@ -51,7 +51,7 @@ #endif #include "nsExceptionHandler.h" -#include "mozilla/ipc/GeckoThread.h" +#include "mozilla/ipc/BrowserProcessSubThread.h" using mozilla::MonitorAutoEnter; using mozilla::ipc::GeckoChildProcessHost; diff --git a/ipc/glue/Makefile.in b/ipc/glue/Makefile.in index 7a33e50a690..fc7cea2248b 100644 --- a/ipc/glue/Makefile.in +++ b/ipc/glue/Makefile.in @@ -55,8 +55,9 @@ EXPORTS_IPC = IPCMessageUtils.h EXPORTS_mozilla/ipc = \ AsyncChannel.h \ + BrowserProcessSubThread.h \ GeckoChildProcessHost.h \ - GeckoThread.h \ + MozillaChildThread.h \ ProtocolUtils.h \ RPCChannel.h \ SharedMemory.h \ @@ -69,8 +70,9 @@ ENABLE_CXX_EXCEPTIONS = 1 CPPSRCS += \ AsyncChannel.cpp \ + BrowserProcessSubThread.cpp \ GeckoChildProcessHost.cpp \ - GeckoThread.cpp \ + MozillaChildThread.cpp \ MessagePump.cpp \ RPCChannel.cpp \ ScopedXREEmbed.cpp \ diff --git a/ipc/glue/MozillaChildThread.cpp b/ipc/glue/MozillaChildThread.cpp new file mode 100644 index 00000000000..b598000f796 --- /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 . + * 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 diff --git a/ipc/glue/MozillaChildThread.h b/ipc/glue/MozillaChildThread.h new file mode 100644 index 00000000000..ae50f3975fc --- /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 . + * 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 */ diff --git a/ipc/glue/RPCChannel.cpp b/ipc/glue/RPCChannel.cpp index 2510a392e44..db7b59bab3f 100644 --- a/ipc/glue/RPCChannel.cpp +++ b/ipc/glue/RPCChannel.cpp @@ -38,7 +38,6 @@ * ***** END LICENSE BLOCK ***** */ #include "mozilla/ipc/RPCChannel.h" -#include "mozilla/ipc/GeckoThread.h" #include "nsDebug.h" #include "nsTraceRefcnt.h" diff --git a/ipc/glue/SyncChannel.cpp b/ipc/glue/SyncChannel.cpp index b67bbca793f..50ce0c5352d 100644 --- a/ipc/glue/SyncChannel.cpp +++ b/ipc/glue/SyncChannel.cpp @@ -38,7 +38,6 @@ * ***** END LICENSE BLOCK ***** */ #include "mozilla/ipc/SyncChannel.h" -#include "mozilla/ipc/GeckoThread.h" #include "nsDebug.h" #include "nsTraceRefcnt.h" diff --git a/ipc/ipdl/test/cxx/IPDLUnitTestThreadChild.cpp b/ipc/ipdl/test/cxx/IPDLUnitTestThreadChild.cpp index 7e03ba45a9b..e959a87f9fa 100644 --- a/ipc/ipdl/test/cxx/IPDLUnitTestThreadChild.cpp +++ b/ipc/ipdl/test/cxx/IPDLUnitTestThreadChild.cpp @@ -40,13 +40,13 @@ #include "IPDLUnitTests.h" -using mozilla::ipc::GeckoThread; +using mozilla::ipc::MozillaChildThread; namespace mozilla { namespace _ipdltest { IPDLUnitTestThreadChild::IPDLUnitTestThreadChild(ProcessHandle aParentHandle) : - GeckoThread(aParentHandle) + MozillaChildThread(aParentHandle) { } @@ -57,15 +57,9 @@ IPDLUnitTestThreadChild::~IPDLUnitTestThreadChild() void IPDLUnitTestThreadChild::Init() { - GeckoThread::Init(); + MozillaChildThread::Init(); IPDLUnitTestChildInit(channel(), GetParentProcessHandle(), owner_loop()); } -void -IPDLUnitTestThreadChild::CleanUp() -{ - GeckoThread::CleanUp(); -} - } // namespace _ipdltest } // namespace mozilla diff --git a/ipc/ipdl/test/cxx/IPDLUnitTestThreadChild.h b/ipc/ipdl/test/cxx/IPDLUnitTestThreadChild.h index f75b9db584f..8c6aa7521c3 100644 --- a/ipc/ipdl/test/cxx/IPDLUnitTestThreadChild.h +++ b/ipc/ipdl/test/cxx/IPDLUnitTestThreadChild.h @@ -39,12 +39,12 @@ #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); @@ -52,7 +52,6 @@ public: protected: virtual void Init(); - virtual void CleanUp(); }; } // namespace _ipdltest diff --git a/ipc/ipdl/test/cxx/IPDLUnitTests.h b/ipc/ipdl/test/cxx/IPDLUnitTests.h index e08b7051495..b0443d1f277 100644 --- a/ipc/ipdl/test/cxx/IPDLUnitTests.h +++ b/ipc/ipdl/test/cxx/IPDLUnitTests.h @@ -43,8 +43,6 @@ #include "base/process.h" #include "chrome/common/ipc_channel.h" -#include "mozilla/ipc/GeckoThread.h" - #include "nsIAppShell.h" #include "nsCOMPtr.h" diff --git a/toolkit/xre/nsEmbedFunctions.cpp b/toolkit/xre/nsEmbedFunctions.cpp index da48c676113..4d572c55f66 100644 --- a/toolkit/xre/nsEmbedFunctions.cpp +++ b/toolkit/xre/nsEmbedFunctions.cpp @@ -59,6 +59,10 @@ # define XP_LINUX #endif +#ifdef XP_WIN +#include +#endif + #include "nsAppDirectoryServiceDefs.h" #include "nsAppRunner.h" #include "nsAutoRef.h" @@ -79,7 +83,7 @@ #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" @@ -94,7 +98,6 @@ 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; @@ -295,6 +298,7 @@ XRE_InitChildProcess(int aArgc, 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 } @@ -330,7 +334,7 @@ XRE_InitChildProcess(int aArgc, switch (aProcess) { case GeckoProcessType_Default: - mainThread = new GeckoThread(parentHandle); + NS_RUNTIMEABORT("This makes no sense"); break; case GeckoProcessType_Plugin: @@ -478,12 +482,12 @@ XRE_RunAppShell() 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 diff --git a/xpcom/base/Makefile.in b/xpcom/base/Makefile.in index 70e4b908a00..104387cf43a 100644 --- a/xpcom/base/Makefile.in +++ b/xpcom/base/Makefile.in @@ -141,3 +141,4 @@ ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT))) CXXFLAGS += $(MOZ_GTK2_CFLAGS) endif +LOCAL_INCLUDES += -I$(srcdir)/../build diff --git a/xpcom/base/nsTraceRefcntImpl.cpp b/xpcom/base/nsTraceRefcntImpl.cpp index db3a834c551..d56b6d75a99 100644 --- a/xpcom/base/nsTraceRefcntImpl.cpp +++ b/xpcom/base/nsTraceRefcntImpl.cpp @@ -37,6 +37,7 @@ * ***** END LICENSE BLOCK ***** */ #include "nsTraceRefcntImpl.h" +#include "nsXPCOMPrivate.h" #include "nscore.h" #include "nsISupports.h" #include "nsTArray.h" @@ -65,6 +66,8 @@ #include "nsTraceMalloc.h" #endif +#include "mozilla/BlockingResourceBase.h" + #ifdef HAVE_LIBDL #include #endif @@ -921,11 +924,34 @@ NS_LogInit() 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(); @@ -938,6 +964,8 @@ NS_LogTerm() } } +} // namespace mozilla + EXPORT_XPCOM_API(void) NS_LogAddRef(void* aPtr, nsrefcnt aRefcnt, const char* aClazz, PRUint32 classSize) diff --git a/xpcom/build/nsXPCOMPrivate.h b/xpcom/build/nsXPCOMPrivate.h index 64e00dea109..d6675c64bf0 100644 --- a/xpcom/build/nsXPCOMPrivate.h +++ b/xpcom/build/nsXPCOMPrivate.h @@ -224,6 +224,11 @@ namespace mozilla { nsresult ShutdownXPCOM(nsIServiceManager* servMgr); +/** + * C++ namespaced version of NS_LogTerm. + */ +void LogTerm(); + } // namespace mozilla diff --git a/xpcom/build/nsXPComInit.cpp b/xpcom/build/nsXPComInit.cpp index 3debc29782c..e68a837c347 100644 --- a/xpcom/build/nsXPComInit.cpp +++ b/xpcom/build/nsXPComInit.cpp @@ -80,10 +80,6 @@ #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. @@ -152,7 +148,7 @@ NS_DECL_CLASSINFO(nsStringInputStream) #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; @@ -502,7 +498,7 @@ NS_InitXPCOM3(nsIServiceManager* *result, } if (!MessageLoop::current()) { - sMessageLoop = new MessageLoopForUI(); + sMessageLoop = new MessageLoopForUI(MessageLoop::TYPE_MOZILLA_UI); NS_ENSURE_STATE(sMessageLoop); } @@ -890,22 +886,6 @@ ShutdownXPCOM(nsIServiceManager* servMgr) 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 diff --git a/xpcom/glue/BlockingResourceBase.h b/xpcom/glue/BlockingResourceBase.h index a3860a7a354..8291591d9c7 100644 --- a/xpcom/glue/BlockingResourceBase.h +++ b/xpcom/glue/BlockingResourceBase.h @@ -55,6 +55,7 @@ #include "nsStringGlue.h" #include "mozilla/DeadlockDetector.h" +#include "nsXPCOM.h" #endif // @@ -355,7 +356,7 @@ private: # 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