Bug 1222101 - Reorder some thread code (r=jld)

This commit is contained in:
Bill McCloskey 2016-03-01 16:22:44 -08:00
parent 5ef16752e3
commit 5b8924bd94
6 changed files with 52 additions and 38 deletions

View File

@ -89,7 +89,7 @@ MessageLoop* MessageLoop::current() {
static mozilla::Atomic<int32_t> message_loop_id_seq(0);
MessageLoop::MessageLoop(Type type)
MessageLoop::MessageLoop(Type type, nsIThread* aThread)
: type_(type),
id_(++message_loop_id_seq),
nestable_tasks_allowed_(true),
@ -107,9 +107,11 @@ MessageLoop::MessageLoop(Type type)
switch (type_) {
case TYPE_MOZILLA_PARENT:
pump_ = new mozilla::ipc::MessagePump();
MOZ_RELEASE_ASSERT(!aThread);
pump_ = new mozilla::ipc::MessagePump(aThread);
return;
case TYPE_MOZILLA_CHILD:
MOZ_RELEASE_ASSERT(!aThread);
pump_ = new mozilla::ipc::MessagePumpForChildProcess();
// There is a MessageLoop Run call from XRE_InitChildProcess
// and another one from MessagePumpForChildProcess. The one
@ -119,11 +121,11 @@ MessageLoop::MessageLoop(Type type)
run_depth_base_ = 2;
return;
case TYPE_MOZILLA_NONMAINTHREAD:
pump_ = new mozilla::ipc::MessagePumpForNonMainThreads();
pump_ = new mozilla::ipc::MessagePumpForNonMainThreads(aThread);
return;
#if defined(OS_WIN)
case TYPE_MOZILLA_NONMAINUITHREAD:
pump_ = new mozilla::ipc::MessagePumpForNonMainUIThreads();
pump_ = new mozilla::ipc::MessagePumpForNonMainUIThreads(aThread);
return;
#endif
default:

View File

@ -27,6 +27,8 @@
#include "nsAutoPtr.h"
class nsIThread;
namespace mozilla {
namespace ipc {
@ -223,7 +225,7 @@ public:
// 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);
explicit MessageLoop(Type type = TYPE_DEFAULT, nsIThread* aThread = nullptr);
~MessageLoop();
// Returns the type passed to the constructor.

View File

@ -9,6 +9,7 @@
#include "base/waitable_event.h"
#include "GeckoProfiler.h"
#include "mozilla/IOInterposer.h"
#include "nsThreadUtils.h"
#ifdef MOZ_TASK_TRACER
#include "GeckoTaskTracer.h"
@ -151,7 +152,8 @@ void Thread::ThreadMain() {
mozilla::IOInterposer::RegisterCurrentThread();
// The message loop for this thread.
MessageLoop message_loop(startup_data_->options.message_loop_type);
MessageLoop message_loop(startup_data_->options.message_loop_type,
NS_GetCurrentThread());
// Complete the initialization of our Thread object.
thread_id_ = PlatformThread::CurrentId();

View File

@ -66,8 +66,8 @@ private:
} /* namespace ipc */
} /* namespace mozilla */
MessagePump::MessagePump()
: mThread(nullptr)
MessagePump::MessagePump(nsIThread* aThread)
: mThread(aThread)
{
mDoWorkEvent = new DoWorkRunnable(this);
}
@ -80,11 +80,12 @@ void
MessagePump::Run(MessagePump::Delegate* aDelegate)
{
MOZ_ASSERT(keep_running_);
MOZ_ASSERT(NS_IsMainThread(),
"Use mozilla::ipc::MessagePumpForNonMainThreads instead!");
MOZ_RELEASE_ASSERT(NS_IsMainThread(),
"Use mozilla::ipc::MessagePumpForNonMainThreads instead!");
MOZ_RELEASE_ASSERT(!mThread);
mThread = NS_GetCurrentThread();
MOZ_ASSERT(mThread);
nsIThread* thisThread = NS_GetCurrentThread();
MOZ_ASSERT(thisThread);
mDelayedWorkTimer = do_CreateInstance(kNS_TIMER_CID);
MOZ_ASSERT(mDelayedWorkTimer);
@ -94,7 +95,7 @@ MessagePump::Run(MessagePump::Delegate* aDelegate)
for (;;) {
autoReleasePool.Recycle();
bool did_work = NS_ProcessNextEvent(mThread, false) ? true : false;
bool did_work = NS_ProcessNextEvent(thisThread, false) ? true : false;
if (!keep_running_)
break;
@ -126,7 +127,7 @@ if (did_work && delayed_work_time_.is_null()
continue;
// This will either sleep or process an event.
NS_ProcessNextEvent(mThread, true);
NS_ProcessNextEvent(thisThread, true);
}
#ifdef MOZ_NUWA_PROCESS
@ -143,8 +144,7 @@ MessagePump::ScheduleWork()
// Make sure the event loop wakes up.
if (mThread) {
mThread->Dispatch(mDoWorkEvent, NS_DISPATCH_NORMAL);
}
else {
} else {
// Some things (like xpcshell) don't use the app shell and so Run hasn't
// been called. We still need to wake up the main thread.
NS_DispatchToMainThread(mDoWorkEvent);
@ -169,6 +169,11 @@ MessagePump::ScheduleDelayedWork(const base::TimeTicks& aDelayedTime)
return;
#endif
// To avoid racing on mDelayedWorkTimer, we need to be on the same thread as
// ::Run().
MOZ_RELEASE_ASSERT(NS_GetCurrentThread() == mThread ||
(!mThread && NS_IsMainThread()));
if (!mDelayedWorkTimer) {
mDelayedWorkTimer = do_CreateInstance(kNS_TIMER_CID);
if (!mDelayedWorkTimer) {
@ -299,21 +304,21 @@ void
MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate* aDelegate)
{
MOZ_ASSERT(keep_running_);
MOZ_ASSERT(!NS_IsMainThread(), "Use mozilla::ipc::MessagePump instead!");
MOZ_RELEASE_ASSERT(!NS_IsMainThread(), "Use mozilla::ipc::MessagePump instead!");
mThread = NS_GetCurrentThread();
MOZ_ASSERT(mThread);
nsIThread* thread = NS_GetCurrentThread();
MOZ_RELEASE_ASSERT(mThread == thread);
mDelayedWorkTimer = do_CreateInstance(kNS_TIMER_CID);
MOZ_ASSERT(mDelayedWorkTimer);
if (NS_FAILED(mDelayedWorkTimer->SetTarget(mThread))) {
if (NS_FAILED(mDelayedWorkTimer->SetTarget(thread))) {
MOZ_CRASH("Failed to set timer target!");
}
// Chromium event notifications to be processed will be received by this
// event loop as a DoWorkRunnables via ScheduleWork. Chromium events that
// were received before our mThread is valid, however, will not generate
// were received before our thread is valid, however, will not generate
// runnable wrappers. We must process any of these before we enter this
// loop, or we will forever have unprocessed chromium messages in our queue.
//
@ -329,7 +334,7 @@ MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate* aDelegate)
for (;;) {
autoReleasePool.Recycle();
bool didWork = NS_ProcessNextEvent(mThread, false) ? true : false;
bool didWork = NS_ProcessNextEvent(thread, false) ? true : false;
if (!keep_running_) {
break;
}
@ -358,7 +363,7 @@ MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate* aDelegate)
}
// This will either sleep or process an event.
NS_ProcessNextEvent(mThread, true);
NS_ProcessNextEvent(thread, true);
}
mDelayedWorkTimer->Cancel();
@ -372,16 +377,19 @@ NS_IMPL_QUERY_INTERFACE(MessagePumpForNonMainUIThreads, nsIThreadObserver)
#define CHECK_QUIT_STATE { if (state_->should_quit) { break; } }
void MessagePumpForNonMainUIThreads::DoRunLoop()
void
MessagePumpForNonMainUIThreads::DoRunLoop()
{
MOZ_RELEASE_ASSERT(!NS_IsMainThread(), "Use mozilla::ipc::MessagePump instead!");
// If this is a chromium thread and no nsThread is associated
// with it, this call will create a new nsThread.
mThread = NS_GetCurrentThread();
MOZ_ASSERT(mThread);
nsIThread* thread = NS_GetCurrentThread();
MOZ_ASSERT(thread);
// Set the main thread observer so we can wake up when
// xpcom events need to get processed.
nsCOMPtr<nsIThreadInternal> ti(do_QueryInterface(mThread));
nsCOMPtr<nsIThreadInternal> ti(do_QueryInterface(thread));
MOZ_ASSERT(ti);
ti->SetObserver(this);
@ -389,7 +397,7 @@ void MessagePumpForNonMainUIThreads::DoRunLoop()
for (;;) {
autoReleasePool.Recycle();
bool didWork = NS_ProcessNextEvent(mThread, false);
bool didWork = NS_ProcessNextEvent(thread, false);
didWork |= ProcessNextWindowsMessage();
CHECK_QUIT_STATE
@ -411,7 +419,7 @@ void MessagePumpForNonMainUIThreads::DoRunLoop()
CHECK_QUIT_STATE
SetInWait();
bool hasWork = NS_HasPendingEvents(mThread);
bool hasWork = NS_HasPendingEvents(thread);
if (didWork || hasWork) {
ClearInWait();
continue;

View File

@ -30,7 +30,7 @@ class MessagePump : public base::MessagePumpDefault
friend class DoWorkRunnable;
public:
MessagePump();
MessagePump(nsIThread* aThread);
// From base::MessagePump.
virtual void
@ -56,10 +56,11 @@ private:
void DoDelayedWork(base::MessagePump::Delegate* aDelegate);
protected:
nsIThread* mThread;
// mDelayedWorkTimer and mThread are set in Run() by this class or its
// subclasses.
nsCOMPtr<nsITimer> mDelayedWorkTimer;
nsIThread* mThread;
private:
// Only accessed by this class.
@ -70,7 +71,8 @@ class MessagePumpForChildProcess final: public MessagePump
{
public:
MessagePumpForChildProcess()
: mFirstRun(true)
: MessagePump(nullptr),
mFirstRun(true)
{ }
virtual void Run(base::MessagePump::Delegate* aDelegate) override;
@ -85,7 +87,8 @@ private:
class MessagePumpForNonMainThreads final : public MessagePump
{
public:
MessagePumpForNonMainThreads()
MessagePumpForNonMainThreads(nsIThread* aThread)
: MessagePump(aThread)
{ }
virtual void Run(base::MessagePump::Delegate* aDelegate) override;
@ -116,8 +119,7 @@ public:
NS_DECL_NSITHREADOBSERVER
public:
MessagePumpForNonMainUIThreads() :
mThread(nullptr),
MessagePumpForNonMainUIThreads(nsIThread* aThread) :
mInWait(false),
mWaitLock("mInWait")
{
@ -127,8 +129,6 @@ public:
virtual void DoRunLoop() override;
protected:
nsIThread* mThread;
void SetInWait() {
MutexAutoLock lock(mWaitLock);
mInWait = true;

View File

@ -390,7 +390,7 @@ nsThread::ThreadFunc(void* aArg)
{
// Scope for MessageLoop.
nsAutoPtr<MessageLoop> loop(
new MessageLoop(MessageLoop::TYPE_MOZILLA_NONMAINTHREAD));
new MessageLoop(MessageLoop::TYPE_MOZILLA_NONMAINTHREAD, self));
// Now, process incoming events...
loop->Run();