Bug 516515 - Don't initialize XPCOM in plugin processes, r=cjones

--HG--
extra : rebase_source : cab356b862a66fb7f5955b1f936944f2395bba3c
This commit is contained in:
Benjamin Smedberg 2010-02-03 17:17:09 -05:00
Родитель 8ad3329b5e
Коммит 32cca8830e
33 изменённых файлов: 324 добавлений и 217 удалений

Просмотреть файл

@ -60,14 +60,13 @@ ChildAsyncCall::Cancel()
mData = NULL; mData = NULL;
} }
NS_IMETHODIMP void
ChildAsyncCall::Run() ChildAsyncCall::Run()
{ {
if (mFunc) { if (mFunc) {
mInstance->mPendingAsyncCalls.RemoveElement(this); mInstance->mPendingAsyncCalls.RemoveElement(this);
mFunc(mData); mFunc(mData);
} }
return NS_OK;
} }
} // namespace plugins } // namespace plugins

Просмотреть файл

@ -42,7 +42,7 @@
#define mozilla_plugins_ChildAsyncCall_h #define mozilla_plugins_ChildAsyncCall_h
#include "PluginMessageUtils.h" #include "PluginMessageUtils.h"
#include "nsThreadUtils.h" #include "base/task.h"
namespace mozilla { namespace mozilla {
namespace plugins { namespace plugins {
@ -51,14 +51,14 @@ typedef void (*PluginThreadCallback)(void*);
class PluginInstanceChild; class PluginInstanceChild;
class ChildAsyncCall : public nsRunnable class ChildAsyncCall : public CancelableTask
{ {
public: public:
ChildAsyncCall(PluginInstanceChild* instance, ChildAsyncCall(PluginInstanceChild* instance,
PluginThreadCallback aFunc, void* aUserData); PluginThreadCallback aFunc, void* aUserData);
void Cancel(); NS_OVERRIDE void Run();
NS_IMETHOD Run(); NS_OVERRIDE void Cancel();
private: private:
PluginInstanceChild* mInstance; PluginInstanceChild* mInstance;

Просмотреть файл

@ -51,38 +51,22 @@ ChildTimer::ChildTimer(PluginInstanceChild* instance,
TimerFunc func) TimerFunc func)
: mInstance(instance) : mInstance(instance)
, mFunc(func) , mFunc(func)
, mID(0) , mRepeating(repeat)
, mID(gNextTimerID++)
{ {
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID); mTimer.Start(base::TimeDelta::FromMilliseconds(interval),
if (!mTimer) this, &ChildTimer::Run);
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;
} }
uint32_t uint32_t
ChildTimer::gNextTimerID = 1; ChildTimer::gNextTimerID = 1;
void void
ChildTimer::Callback(nsITimer* aTimer, void* aClosure) ChildTimer::Run()
{ {
ChildTimer* self = static_cast<ChildTimer*>(aClosure); if (!mRepeating)
self->mFunc(self->mInstance->GetNPP(), self->mID); mTimer.Stop();
mFunc(mInstance->GetNPP(), mID);
} }
} // namespace plugins } // namespace plugins

Просмотреть файл

@ -43,8 +43,7 @@
#include "PluginMessageUtils.h" #include "PluginMessageUtils.h"
#include "npapi.h" #include "npapi.h"
#include "nsITimer.h" #include "base/timer.h"
#include "nsCOMPtr.h"
namespace mozilla { namespace mozilla {
namespace plugins { namespace plugins {
@ -62,17 +61,10 @@ public:
uint32_t interval, uint32_t interval,
bool repeat, bool repeat,
TimerFunc func); TimerFunc func);
~ChildTimer() { ~ChildTimer() { }
NS_ASSERTION(!mTimer, "Timer should already be cancelled");
}
uint32_t ID() const { return mID; } uint32_t ID() const { return mID; }
/**
* Called by the instance, cancels the timer and deletes this object.
*/
void Destroy();
class IDComparator class IDComparator
{ {
public: public:
@ -84,11 +76,13 @@ public:
private: private:
PluginInstanceChild* mInstance; PluginInstanceChild* mInstance;
TimerFunc mFunc; TimerFunc mFunc;
bool mRepeating;
uint32_t mID; uint32_t mID;
nsCOMPtr<nsITimer> mTimer; base::RepeatingTimer<ChildTimer> mTimer;
void Run();
static uint32_t gNextTimerID; static uint32_t gNextTimerID;
static void Callback(nsITimer* aTimer, void* aClosure);
}; };
} // namespace plugins } // namespace plugins

Просмотреть файл

@ -1144,12 +1144,7 @@ PluginInstanceChild::UnscheduleTimer(uint32_t id)
if (0 == id) if (0 == id)
return; return;
PRUint32 i = mTimers.IndexOf(id, 0, ChildTimer::IDComparator()); mTimers.RemoveElement(id, ChildTimer::IDComparator());
if (nsTArray<ChildTimer*>::NoIndex == i)
return;
mTimers.ElementAt(i)->Destroy();
mTimers.RemoveElementAt(i);
} }
bool bool
@ -1159,9 +1154,7 @@ PluginInstanceChild::AnswerNPP_Destroy(NPError* aResult)
mPendingAsyncCalls[i]->Cancel(); mPendingAsyncCalls[i]->Cancel();
mPendingAsyncCalls.TruncateLength(0); mPendingAsyncCalls.TruncateLength(0);
for (PRUint32 i = 0; i < mTimers.Length(); ++i) mTimers.Clear();
mTimers[i]->Destroy();
mTimers.TruncateLength(0);
PluginModuleChild* module = PluginModuleChild::current(); PluginModuleChild* module = PluginModuleChild::current();
bool retval = module->PluginInstanceDestroyed(this, aResult); bool retval = module->PluginInstanceDestroyed(this, aResult);

Просмотреть файл

@ -215,7 +215,7 @@ private:
friend class ChildAsyncCall; friend class ChildAsyncCall;
nsTArray<ChildAsyncCall*> mPendingAsyncCalls; nsTArray<ChildAsyncCall*> mPendingAsyncCalls;
nsTArray<ChildTimer*> mTimers; nsTArray<nsAutoPtr<ChildTimer> > mTimers;
#if defined(OS_WIN) #if defined(OS_WIN)
private: private:

Просмотреть файл

@ -40,6 +40,7 @@
#define DOM_PLUGINS_PLUGINMESSAGEUTILS_H #define DOM_PLUGINS_PLUGINMESSAGEUTILS_H
#include "IPC/IPCMessageUtils.h" #include "IPC/IPCMessageUtils.h"
#include "base/message_loop.h"
#include "npapi.h" #include "npapi.h"
#include "npruntime.h" #include "npruntime.h"
@ -197,7 +198,8 @@ NPNVariableToString(NPNVariable aVar)
inline void AssertPluginThread() 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 DeferNPObjectLastRelease(const NPNetscapeFuncs* f, NPObject* o);

Просмотреть файл

@ -55,6 +55,7 @@
#include "mozilla/plugins/StreamNotifyChild.h" #include "mozilla/plugins/StreamNotifyChild.h"
#include "mozilla/plugins/BrowserStreamChild.h" #include "mozilla/plugins/BrowserStreamChild.h"
#include "mozilla/plugins/PluginStreamChild.h" #include "mozilla/plugins/PluginStreamChild.h"
#include "mozilla/plugins/PluginThreadChild.h"
#include "nsNPAPIPlugin.h" #include "nsNPAPIPlugin.h"
@ -1253,8 +1254,9 @@ _pluginthreadasynccall(NPP aNPP,
if (!aFunc) if (!aFunc)
return; return;
nsCOMPtr<nsIRunnable> e(new ChildAsyncCall(InstCast(aNPP), aFunc, aUserData)); PluginThreadChild::current()->message_loop()
NS_DispatchToMainThread(e); ->PostTask(FROM_HERE, new ChildAsyncCall(InstCast(aNPP), aFunc,
aUserData));
} }
NPError NP_CALLBACK NPError NP_CALLBACK

Просмотреть файл

@ -40,7 +40,7 @@
#include "mozilla/plugins/PluginProcessParent.h" #include "mozilla/plugins/PluginProcessParent.h"
#include "base/string_util.h" #include "base/string_util.h"
#include "mozilla/ipc/GeckoThread.h" #include "mozilla/ipc/BrowserProcessSubThread.h"
using mozilla::ipc::BrowserProcessSubThread; using mozilla::ipc::BrowserProcessSubThread;
using mozilla::ipc::GeckoChildProcessHost; using mozilla::ipc::GeckoChildProcessHost;

Просмотреть файл

@ -46,25 +46,29 @@
#include "chrome/common/child_process.h" #include "chrome/common/child_process.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
using mozilla::ipc::GeckoThread; using mozilla::ipc::MozillaChildThread;
namespace mozilla { namespace mozilla {
namespace plugins { namespace plugins {
PluginThreadChild::PluginThreadChild(ProcessHandle aParentHandle) : PluginThreadChild::PluginThreadChild(ProcessHandle aParentHandle) :
GeckoThread(aParentHandle), MozillaChildThread(aParentHandle, MessageLoop::TYPE_UI)
mPlugin()
{ {
NS_ASSERTION(!gInstance, "Two PluginThreadChild?");
gInstance = this;
} }
PluginThreadChild::~PluginThreadChild() PluginThreadChild::~PluginThreadChild()
{ {
gInstance = NULL;
} }
PluginThreadChild* PluginThreadChild::gInstance;
void void
PluginThreadChild::Init() PluginThreadChild::Init()
{ {
GeckoThread::Init(); MozillaChildThread::Init();
std::string pluginFilename; std::string pluginFilename;
@ -97,7 +101,7 @@ void
PluginThreadChild::CleanUp() PluginThreadChild::CleanUp()
{ {
mPlugin.CleanUp(); mPlugin.CleanUp();
GeckoThread::CleanUp(); MozillaChildThread::CleanUp();
} }
} // namespace plugins } // namespace plugins

Просмотреть файл

@ -42,10 +42,10 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "chrome/common/child_thread.h" #include "mozilla/ipc/MozillaChildThread.h"
#include "base/file_path.h" #include "base/file_path.h"
#include "base/process.h"
#include "mozilla/ipc/GeckoThread.h"
#include "mozilla/plugins/PluginModuleChild.h" #include "mozilla/plugins/PluginModuleChild.h"
namespace mozilla { namespace mozilla {
@ -54,20 +54,22 @@ namespace plugins {
// The PluginThreadChild class represents a background thread where plugin instances // The PluginThreadChild class represents a background thread where plugin instances
// live. // live.
class PluginThreadChild : public mozilla::ipc::GeckoThread { class PluginThreadChild : public mozilla::ipc::MozillaChildThread {
public: public:
PluginThreadChild(ProcessHandle aParentHandle); PluginThreadChild(ProcessHandle aParentHandle);
~PluginThreadChild(); ~PluginThreadChild();
static PluginThreadChild* current() {
return gInstance;
}
private: private:
static PluginThreadChild* gInstance;
// Thread implementation: // Thread implementation:
virtual void Init(); virtual void Init();
virtual void CleanUp(); 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; PluginModuleChild mPlugin;
IPC::Channel* mChannel; IPC::Channel* mChannel;

Просмотреть файл

@ -246,6 +246,7 @@ CPPSRCS += \
file_util_linux.cc \ file_util_linux.cc \
file_version_info_linux.cc \ file_version_info_linux.cc \
idle_timer_none.cc \ idle_timer_none.cc \
message_pump_glib.cc \
process_util_linux.cc \ process_util_linux.cc \
time_posix.cc \ time_posix.cc \
$(NULL) $(NULL)

Просмотреть файл

@ -19,7 +19,7 @@
#if defined(OS_POSIX) #if defined(OS_POSIX)
#include "base/message_pump_libevent.h" #include "base/message_pump_libevent.h"
#endif #endif
#if defined(OS_LINUX) && !defined(CHROMIUM_MOZILLA_BUILD) #if defined(OS_LINUX)
#include "base/message_pump_glib.h" #include "base/message_pump_glib.h"
#endif #endif
@ -89,7 +89,7 @@ MessageLoop::MessageLoop(Type type)
lazy_tls_ptr.Pointer()->Set(this); lazy_tls_ptr.Pointer()->Set(this);
#ifdef CHROMIUM_MOZILLA_BUILD #ifdef CHROMIUM_MOZILLA_BUILD
if (type_ == TYPE_UI) { if (type_ == TYPE_MOZILLA_UI) {
pump_ = new mozilla::ipc::MessagePump(); pump_ = new mozilla::ipc::MessagePump();
return; return;
} }
@ -112,7 +112,7 @@ MessageLoop::MessageLoop(Type type)
if (type_ == TYPE_UI) { if (type_ == TYPE_UI) {
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
pump_ = base::MessagePumpMac::Create(); pump_ = base::MessagePumpMac::Create();
#elif defined(OS_LINUX) && !defined(CHROMIUM_MOZILLA_BUILD) #elif defined(OS_LINUX)
pump_ = new base::MessagePumpForUI(); pump_ = new base::MessagePumpForUI();
#endif // OS_LINUX #endif // OS_LINUX
} else if (type_ == TYPE_IO) { } else if (type_ == TYPE_IO) {

Просмотреть файл

@ -196,12 +196,21 @@ public:
// This type of ML also supports asynchronous IO. See also // This type of ML also supports asynchronous IO. See also
// MessageLoopForIO. // 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 { enum Type {
TYPE_DEFAULT, TYPE_DEFAULT,
TYPE_UI, TYPE_UI,
TYPE_IO TYPE_IO
#ifdef CHROMIUM_MOZILLA_BUILD #ifdef CHROMIUM_MOZILLA_BUILD
, TYPE_MOZILLA_CHILD , TYPE_MOZILLA_CHILD
, TYPE_MOZILLA_UI
#endif #endif
}; };
@ -421,15 +430,17 @@ public:
// //
class MessageLoopForUI : public MessageLoop { class MessageLoopForUI : public MessageLoop {
public: public:
MessageLoopForUI() : MessageLoop(TYPE_UI) { MessageLoopForUI(Type type=TYPE_UI) : MessageLoop(type) {
} }
#ifndef CHROMIUM_MOZILLA_BUILD
// Returns the MessageLoopForUI of the current thread. // Returns the MessageLoopForUI of the current thread.
static MessageLoopForUI* current() { static MessageLoopForUI* current() {
MessageLoop* loop = MessageLoop::current(); MessageLoop* loop = MessageLoop::current();
DCHECK_EQ(MessageLoop::TYPE_UI, loop->type()); DCHECK_EQ(MessageLoop::TYPE_UI, loop->type());
return static_cast<MessageLoopForUI*>(loop); return static_cast<MessageLoopForUI*>(loop);
} }
#endif
#if defined(OS_WIN) #if defined(OS_WIN)
typedef base::MessagePumpWin::Dispatcher Dispatcher; typedef base::MessagePumpWin::Dispatcher Dispatcher;

Просмотреть файл

@ -11,7 +11,7 @@
#include "base/singleton.h" #include "base/singleton.h"
#include "base/waitable_event.h" #include "base/waitable_event.h"
#ifdef CHROMIUM_MOZILLA_BUILD #ifdef CHROMIUM_MOZILLA_BUILD
#include "mozilla/ipc/GeckoThread.h" #include "mozilla/ipc/BrowserProcessSubThread.h"
typedef mozilla::ipc::BrowserProcessSubThread ChromeThread; typedef mozilla::ipc::BrowserProcessSubThread ChromeThread;
#else #else
#include "chrome/browser/chrome_thread.h" #include "chrome/browser/chrome_thread.h"

Просмотреть файл

@ -38,7 +38,7 @@
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include "mozilla/ipc/AsyncChannel.h" #include "mozilla/ipc/AsyncChannel.h"
#include "mozilla/ipc/GeckoThread.h" #include "mozilla/ipc/BrowserProcessSubThread.h"
#include "mozilla/ipc/ProtocolUtils.h" #include "mozilla/ipc/ProtocolUtils.h"
#include "nsDebug.h" #include "nsDebug.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 ***** /* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
* *
@ -34,46 +37,15 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include "mozilla/ipc/GeckoThread.h" #include "mozilla/ipc/BrowserProcessSubThread.h"
#include "chrome/common/notification_service.h" #include "chrome/common/notification_service.h"
#include "nsXPCOM.h"
#if defined(OS_WIN) #if defined(OS_WIN)
#include <objbase.h> #include <objbase.h>
#endif #endif
using mozilla::ipc::GeckoThread; namespace mozilla {
using mozilla::ipc::BrowserProcessSubThread; namespace ipc {
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 // BrowserProcessSubThread
@ -146,7 +118,8 @@ BrowserProcessSubThread::CleanUp()
// static // static
MessageLoop* MessageLoop*
BrowserProcessSubThread::GetMessageLoop(ID aId) { BrowserProcessSubThread::GetMessageLoop(ID aId)
{
AutoLock lock(sLock); AutoLock lock(sLock);
DCHECK(aId >= 0 && aId < ID_COUNT); DCHECK(aId >= 0 && aId < ID_COUNT);
@ -155,3 +128,6 @@ BrowserProcessSubThread::GetMessageLoop(ID aId) {
return NULL; return NULL;
} }
} // namespace ipc
} // namespace mozilla

Просмотреть файл

@ -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 ***** /* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
* *
@ -34,62 +37,19 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#ifndef __IPC_GLUE_GECKOTHREAD_H__ #ifndef mozilla_ipc_BrowserProcessSubThread_h
#define __IPC_GLUE_GECKOTHREAD_H__ #define mozilla_ipc_BrowserProcessSubThread_h
#include "base/thread.h" #include "base/thread.h"
#include "base/lock.h" #include "base/lock.h"
#include "base/process.h"
#include "chrome/common/child_thread.h"
#include "nsDebug.h" #include "nsDebug.h"
#include "mozilla/ipc/ScopedXREEmbed.h"
class NotificationService; class NotificationService;
namespace mozilla { namespace mozilla {
namespace ipc { 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. // Copied from browser_process_impl.cc, modified slightly.
class BrowserProcessSubThread : public base::Thread class BrowserProcessSubThread : public base::Thread
{ {
@ -143,7 +103,13 @@ private:
static BrowserProcessSubThread* sBrowserThreads[ID_COUNT]; static BrowserProcessSubThread* sBrowserThreads[ID_COUNT];
}; };
} /* namespace ipc */ inline void AssertIOThread()
} /* namespace mozilla */ {
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

Просмотреть файл

@ -51,7 +51,7 @@
#endif #endif
#include "nsExceptionHandler.h" #include "nsExceptionHandler.h"
#include "mozilla/ipc/GeckoThread.h" #include "mozilla/ipc/BrowserProcessSubThread.h"
using mozilla::MonitorAutoEnter; using mozilla::MonitorAutoEnter;
using mozilla::ipc::GeckoChildProcessHost; using mozilla::ipc::GeckoChildProcessHost;

Просмотреть файл

@ -55,8 +55,9 @@ EXPORTS_IPC = IPCMessageUtils.h
EXPORTS_mozilla/ipc = \ EXPORTS_mozilla/ipc = \
AsyncChannel.h \ AsyncChannel.h \
BrowserProcessSubThread.h \
GeckoChildProcessHost.h \ GeckoChildProcessHost.h \
GeckoThread.h \ MozillaChildThread.h \
ProtocolUtils.h \ ProtocolUtils.h \
RPCChannel.h \ RPCChannel.h \
SharedMemory.h \ SharedMemory.h \
@ -69,8 +70,9 @@ ENABLE_CXX_EXCEPTIONS = 1
CPPSRCS += \ CPPSRCS += \
AsyncChannel.cpp \ AsyncChannel.cpp \
BrowserProcessSubThread.cpp \
GeckoChildProcessHost.cpp \ GeckoChildProcessHost.cpp \
GeckoThread.cpp \ MozillaChildThread.cpp \
MessagePump.cpp \ MessagePump.cpp \
RPCChannel.cpp \ RPCChannel.cpp \
ScopedXREEmbed.cpp \ ScopedXREEmbed.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

Просмотреть файл

@ -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 */

Просмотреть файл

@ -38,7 +38,6 @@
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include "mozilla/ipc/RPCChannel.h" #include "mozilla/ipc/RPCChannel.h"
#include "mozilla/ipc/GeckoThread.h"
#include "nsDebug.h" #include "nsDebug.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"

Просмотреть файл

@ -38,7 +38,6 @@
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include "mozilla/ipc/SyncChannel.h" #include "mozilla/ipc/SyncChannel.h"
#include "mozilla/ipc/GeckoThread.h"
#include "nsDebug.h" #include "nsDebug.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"

Просмотреть файл

@ -40,13 +40,13 @@
#include "IPDLUnitTests.h" #include "IPDLUnitTests.h"
using mozilla::ipc::GeckoThread; using mozilla::ipc::MozillaChildThread;
namespace mozilla { namespace mozilla {
namespace _ipdltest { namespace _ipdltest {
IPDLUnitTestThreadChild::IPDLUnitTestThreadChild(ProcessHandle aParentHandle) : IPDLUnitTestThreadChild::IPDLUnitTestThreadChild(ProcessHandle aParentHandle) :
GeckoThread(aParentHandle) MozillaChildThread(aParentHandle)
{ {
} }
@ -57,15 +57,9 @@ IPDLUnitTestThreadChild::~IPDLUnitTestThreadChild()
void void
IPDLUnitTestThreadChild::Init() IPDLUnitTestThreadChild::Init()
{ {
GeckoThread::Init(); MozillaChildThread::Init();
IPDLUnitTestChildInit(channel(), GetParentProcessHandle(), owner_loop()); IPDLUnitTestChildInit(channel(), GetParentProcessHandle(), owner_loop());
} }
void
IPDLUnitTestThreadChild::CleanUp()
{
GeckoThread::CleanUp();
}
} // namespace _ipdltest } // namespace _ipdltest
} // namespace mozilla } // namespace mozilla

Просмотреть файл

@ -39,12 +39,12 @@
#ifndef mozilla__ipdltest_IPDLUnitTestThreadChild_h #ifndef mozilla__ipdltest_IPDLUnitTestThreadChild_h
#define mozilla__ipdltest_IPDLUnitTestThreadChild_h 1 #define mozilla__ipdltest_IPDLUnitTestThreadChild_h 1
#include "mozilla/ipc/GeckoThread.h" #include "mozilla/ipc/MozillaChildThread.h"
namespace mozilla { namespace mozilla {
namespace _ipdltest { namespace _ipdltest {
class IPDLUnitTestThreadChild : public mozilla::ipc::GeckoThread class IPDLUnitTestThreadChild : public mozilla::ipc::MozillaChildThread
{ {
public: public:
IPDLUnitTestThreadChild(ProcessHandle aParentHandle); IPDLUnitTestThreadChild(ProcessHandle aParentHandle);
@ -52,7 +52,6 @@ public:
protected: protected:
virtual void Init(); virtual void Init();
virtual void CleanUp();
}; };
} // namespace _ipdltest } // namespace _ipdltest

Просмотреть файл

@ -43,8 +43,6 @@
#include "base/process.h" #include "base/process.h"
#include "chrome/common/ipc_channel.h" #include "chrome/common/ipc_channel.h"
#include "mozilla/ipc/GeckoThread.h"
#include "nsIAppShell.h" #include "nsIAppShell.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"

Просмотреть файл

@ -59,6 +59,10 @@
# define XP_LINUX # define XP_LINUX
#endif #endif
#ifdef XP_WIN
#include <process.h>
#endif
#include "nsAppDirectoryServiceDefs.h" #include "nsAppDirectoryServiceDefs.h"
#include "nsAppRunner.h" #include "nsAppRunner.h"
#include "nsAutoRef.h" #include "nsAutoRef.h"
@ -79,7 +83,7 @@
#include "chrome/common/child_process.h" #include "chrome/common/child_process.h"
#include "mozilla/ipc/GeckoChildProcessHost.h" #include "mozilla/ipc/GeckoChildProcessHost.h"
#include "mozilla/ipc/GeckoThread.h" #include "mozilla/ipc/BrowserProcessSubThread.h"
#include "ScopedXREEmbed.h" #include "ScopedXREEmbed.h"
#include "mozilla/plugins/PluginThreadChild.h" #include "mozilla/plugins/PluginThreadChild.h"
@ -94,7 +98,6 @@ using mozilla::_ipdltest::IPDLUnitTestThreadChild;
#endif // ifdef MOZ_IPDL_TESTS #endif // ifdef MOZ_IPDL_TESTS
using mozilla::ipc::GeckoChildProcessHost; using mozilla::ipc::GeckoChildProcessHost;
using mozilla::ipc::GeckoThread;
using mozilla::ipc::BrowserProcessSubThread; using mozilla::ipc::BrowserProcessSubThread;
using mozilla::ipc::ScopedXREEmbed; using mozilla::ipc::ScopedXREEmbed;
@ -295,6 +298,7 @@ XRE_InitChildProcess(int aArgc,
printf("\n\nCHILDCHILDCHILDCHILD\n debug me @%d\n\n", getpid()); printf("\n\nCHILDCHILDCHILDCHILD\n debug me @%d\n\n", getpid());
sleep(30); sleep(30);
#elif defined(OS_WIN) #elif defined(OS_WIN)
printf("\n\nCHILDCHILDCHILDCHILD\n debug me @%d\n\n", _getpid());
Sleep(30000); Sleep(30000);
#endif #endif
} }
@ -330,7 +334,7 @@ XRE_InitChildProcess(int aArgc,
switch (aProcess) { switch (aProcess) {
case GeckoProcessType_Default: case GeckoProcessType_Default:
mainThread = new GeckoThread(parentHandle); NS_RUNTIMEABORT("This makes no sense");
break; break;
case GeckoProcessType_Plugin: case GeckoProcessType_Plugin:
@ -478,7 +482,7 @@ XRE_RunAppShell()
void void
XRE_ShutdownChildProcess() XRE_ShutdownChildProcess()
{ {
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Wrong thread!"); NS_ABORT_IF_FALSE(MessageLoopForUI::current(), "Wrong thread!");
MessageLoop* ioLoop = XRE_GetIOMessageLoop(); MessageLoop* ioLoop = XRE_GetIOMessageLoop();
NS_ABORT_IF_FALSE(!!ioLoop, "Bad shutdown order"); NS_ABORT_IF_FALSE(!!ioLoop, "Bad shutdown order");

Просмотреть файл

@ -141,3 +141,4 @@ ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT)))
CXXFLAGS += $(MOZ_GTK2_CFLAGS) CXXFLAGS += $(MOZ_GTK2_CFLAGS)
endif endif
LOCAL_INCLUDES += -I$(srcdir)/../build

Просмотреть файл

@ -37,6 +37,7 @@
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include "nsTraceRefcntImpl.h" #include "nsTraceRefcntImpl.h"
#include "nsXPCOMPrivate.h"
#include "nscore.h" #include "nscore.h"
#include "nsISupports.h" #include "nsISupports.h"
#include "nsTArray.h" #include "nsTArray.h"
@ -65,6 +66,8 @@
#include "nsTraceMalloc.h" #include "nsTraceMalloc.h"
#endif #endif
#include "mozilla/BlockingResourceBase.h"
#ifdef HAVE_LIBDL #ifdef HAVE_LIBDL
#include <dlfcn.h> #include <dlfcn.h>
#endif #endif
@ -921,11 +924,34 @@ NS_LogInit()
EXPORT_XPCOM_API(void) EXPORT_XPCOM_API(void)
NS_LogTerm() NS_LogTerm()
{
mozilla::LogTerm();
}
namespace mozilla {
void
LogTerm()
{ {
NS_ASSERTION(gInitCount > 0, NS_ASSERTION(gInitCount > 0,
"NS_LogTerm without matching NS_LogInit"); "NS_LogTerm without matching NS_LogInit");
if (--gInitCount == 0) { 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) { if (gInitialized) {
nsTraceRefcntImpl::DumpStatistics(); nsTraceRefcntImpl::DumpStatistics();
nsTraceRefcntImpl::ResetStatistics(); nsTraceRefcntImpl::ResetStatistics();
@ -938,6 +964,8 @@ NS_LogTerm()
} }
} }
} // namespace mozilla
EXPORT_XPCOM_API(void) EXPORT_XPCOM_API(void)
NS_LogAddRef(void* aPtr, nsrefcnt aRefcnt, NS_LogAddRef(void* aPtr, nsrefcnt aRefcnt,
const char* aClazz, PRUint32 classSize) const char* aClazz, PRUint32 classSize)

Просмотреть файл

@ -224,6 +224,11 @@ namespace mozilla {
nsresult nsresult
ShutdownXPCOM(nsIServiceManager* servMgr); ShutdownXPCOM(nsIServiceManager* servMgr);
/**
* C++ namespaced version of NS_LogTerm.
*/
void LogTerm();
} // namespace mozilla } // namespace mozilla

Просмотреть файл

@ -80,10 +80,6 @@
#include "nsThreadManager.h" #include "nsThreadManager.h"
#include "nsThreadPool.h" #include "nsThreadPool.h"
#ifdef DEBUG
#include "BlockingResourceBase.h"
#endif // ifdef DEBUG
#include "nsIProxyObjectManager.h" #include "nsIProxyObjectManager.h"
#include "nsProxyEventPrivate.h" // access to the impl of nsProxyObjectManager for the generic factory registration. #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/command_line.h"
#include "base/message_loop.h" #include "base/message_loop.h"
#include "mozilla/ipc/GeckoThread.h" #include "mozilla/ipc/BrowserProcessSubThread.h"
using base::AtExitManager; using base::AtExitManager;
using mozilla::ipc::BrowserProcessSubThread; using mozilla::ipc::BrowserProcessSubThread;
@ -502,7 +498,7 @@ NS_InitXPCOM3(nsIServiceManager* *result,
} }
if (!MessageLoop::current()) { if (!MessageLoop::current()) {
sMessageLoop = new MessageLoopForUI(); sMessageLoop = new MessageLoopForUI(MessageLoop::TYPE_MOZILLA_UI);
NS_ENSURE_STATE(sMessageLoop); NS_ENSURE_STATE(sMessageLoop);
} }
@ -890,22 +886,6 @@ ShutdownXPCOM(nsIServiceManager* servMgr)
TimeStamp::Shutdown(); 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(); NS_LogTerm();
#ifdef MOZ_IPC #ifdef MOZ_IPC

Просмотреть файл

@ -55,6 +55,7 @@
#include "nsStringGlue.h" #include "nsStringGlue.h"
#include "mozilla/DeadlockDetector.h" #include "mozilla/DeadlockDetector.h"
#include "nsXPCOM.h"
#endif #endif
// //
@ -355,7 +356,7 @@ private:
# ifdef MOZILLA_INTERNAL_API # ifdef MOZILLA_INTERNAL_API
// so it can call BlockingResourceBase::Shutdown() // so it can call BlockingResourceBase::Shutdown()
friend nsresult ShutdownXPCOM(nsIServiceManager*); friend void LogTerm();
# endif // ifdef MOZILLA_INTERNAL_API # endif // ifdef MOZILLA_INTERNAL_API
#else // non-DEBUG implementation #else // non-DEBUG implementation