Bug 1396155 - Allow LabeledEventQueue to be used outside the Scheduler (r=froydnj)

MozReview-Commit-ID: 4yEX39HXh9W
This commit is contained in:
Bill McCloskey 2017-09-01 16:39:13 -07:00
Родитель 4219e067da
Коммит 9cbaae8cfc
8 изменённых файлов: 81 добавлений и 68 удалений

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

@ -0,0 +1,53 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_MainThreadQueue_h
#define mozilla_MainThreadQueue_h
#include "mozilla/Attributes.h"
#include "mozilla/EventQueue.h"
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#include "nsThread.h"
#include "PrioritizedEventQueue.h"
namespace mozilla {
template<typename SynchronizedQueueT, typename InnerQueueT>
inline already_AddRefed<nsThread>
CreateMainThread(nsIIdlePeriod* aIdlePeriod, SynchronizedQueueT** aSynchronizedQueue = nullptr)
{
using MainThreadQueueT = PrioritizedEventQueue<InnerQueueT>;
auto queue = MakeUnique<MainThreadQueueT>(
MakeUnique<InnerQueueT>(),
MakeUnique<InnerQueueT>(),
MakeUnique<InnerQueueT>(),
MakeUnique<InnerQueueT>(),
do_AddRef(aIdlePeriod));
MainThreadQueueT* prioritized = queue.get();
RefPtr<SynchronizedQueueT> synchronizedQueue = new SynchronizedQueueT(Move(queue));
prioritized->SetMutexRef(synchronizedQueue->MutexRef());
// Setup "main" thread
RefPtr<nsThread> mainThread = new nsThread(WrapNotNull(synchronizedQueue), nsThread::MAIN_THREAD, 0);
#ifndef RELEASE_OR_BETA
prioritized->SetNextIdleDeadlineRef(mainThread->NextIdleDeadlineRef());
#endif
if (aSynchronizedQueue) {
synchronizedQueue.forget(aSynchronizedQueue);
}
return mainThread.forget();
}
} // namespace mozilla
#endif // mozilla_MainThreadQueue_h

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

@ -342,4 +342,5 @@ ResumeInputEventPrioritization(const MutexAutoLock& aProofOfLock)
namespace mozilla {
template class PrioritizedEventQueue<EventQueue>;
template class PrioritizedEventQueue<LabeledEventQueue>;
}

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

@ -125,6 +125,7 @@ private:
class EventQueue;
extern template class PrioritizedEventQueue<EventQueue>;
extern template class PrioritizedEventQueue<LabeledEventQueue>;
} // namespace mozilla

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

@ -9,6 +9,7 @@
#include "jsfriendapi.h"
#include "LabeledEventQueue.h"
#include "LeakRefPtr.h"
#include "MainThreadQueue.h"
#include "mozilla/CooperativeThreadPool.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/ipc/BackgroundChild.h"
@ -91,9 +92,6 @@ class mozilla::SchedulerImpl
public:
explicit SchedulerImpl(SchedulerEventQueue* aQueue);
static already_AddRefed<SchedulerEventQueue>
CreateQueue(nsIIdlePeriod* aIdlePeriod, nsThread** aThread);
void Start();
void Shutdown();
@ -442,49 +440,6 @@ SchedulerImpl::SwitcherThread(void* aData)
static_cast<SchedulerImpl*>(aData)->Switcher();
}
/* static */ already_AddRefed<SchedulerEventQueue>
SchedulerImpl::CreateQueue(nsIIdlePeriod* aIdlePeriod, nsThread** aThread)
{
UniquePtr<AbstractEventQueue> queue;
RefPtr<nsThread> mainThread;
if (sPrefUseMultipleQueues) {
using MainThreadQueueT = PrioritizedEventQueue<LabeledEventQueue>;
queue = MakeUnique<MainThreadQueueT>(
MakeUnique<LabeledEventQueue>(),
MakeUnique<LabeledEventQueue>(),
MakeUnique<LabeledEventQueue>(),
MakeUnique<LabeledEventQueue>(),
do_AddRef(aIdlePeriod));
} else {
using MainThreadQueueT = PrioritizedEventQueue<EventQueue>;
queue = MakeUnique<MainThreadQueueT>(
MakeUnique<EventQueue>(),
MakeUnique<EventQueue>(),
MakeUnique<EventQueue>(),
MakeUnique<EventQueue>(),
do_AddRef(aIdlePeriod));
}
auto prioritized = static_cast<PrioritizedEventQueue<AbstractEventQueue>*>(queue.get());
RefPtr<SchedulerEventQueue> synchronizedQueue = new SchedulerEventQueue(Move(queue));
prioritized->SetMutexRef(synchronizedQueue->MutexRef());
// Setup "main" thread
mainThread = new nsThread(WrapNotNull(synchronizedQueue), nsThread::MAIN_THREAD, 0);
#ifndef RELEASE_OR_BETA
prioritized->SetNextIdleDeadlineRef(mainThread->NextIdleDeadlineRef());
#endif
mainThread.forget(aThread);
return synchronizedQueue.forget();
}
void
SchedulerImpl::Start()
{
@ -738,8 +693,14 @@ Scheduler::Init(nsIIdlePeriod* aIdlePeriod)
{
MOZ_ASSERT(!sScheduler);
RefPtr<SchedulerEventQueue> queue;
RefPtr<nsThread> mainThread;
RefPtr<SchedulerEventQueue> queue = SchedulerImpl::CreateQueue(aIdlePeriod, getter_AddRefs(mainThread));
if (Scheduler::UseMultipleQueues()) {
mainThread = CreateMainThread<SchedulerEventQueue, LabeledEventQueue>(aIdlePeriod, getter_AddRefs(queue));
} else {
mainThread = CreateMainThread<SchedulerEventQueue, EventQueue>(aIdlePeriod, getter_AddRefs(queue));
}
sScheduler = MakeUnique<SchedulerImpl>(queue);
return mainThread.forget();
}
@ -806,6 +767,12 @@ Scheduler::IsSchedulerEnabled()
return SchedulerImpl::sPrefScheduler;
}
/* static */ bool
Scheduler::UseMultipleQueues()
{
return SchedulerImpl::sPrefUseMultipleQueues;
}
/* static */ bool
Scheduler::IsCooperativeThread()
{

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

@ -62,6 +62,7 @@ public:
static void SetPrefs(const char* aPrefs);
static bool IsSchedulerEnabled();
static bool UseMultipleQueues();
static bool IsCooperativeThread();

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

@ -269,4 +269,5 @@ ThreadEventQueue<InnerQueueT>::SetObserver(nsIThreadObserver* aObserver)
namespace mozilla {
template class ThreadEventQueue<EventQueue>;
template class ThreadEventQueue<PrioritizedEventQueue<EventQueue>>;
template class ThreadEventQueue<PrioritizedEventQueue<LabeledEventQueue>>;
}

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

@ -24,6 +24,8 @@ class EventQueue;
template<typename InnerQueueT>
class PrioritizedEventQueue;
class LabeledEventQueue;
class ThreadEventTarget;
// A ThreadEventQueue implements normal monitor-style synchronization over the
@ -115,6 +117,7 @@ private:
extern template class ThreadEventQueue<EventQueue>;
extern template class ThreadEventQueue<PrioritizedEventQueue<EventQueue>>;
extern template class ThreadEventQueue<PrioritizedEventQueue<LabeledEventQueue>>;
}; // namespace mozilla

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

@ -10,6 +10,8 @@
#include "nsIClassInfoImpl.h"
#include "nsTArray.h"
#include "nsAutoPtr.h"
#include "LabeledEventQueue.h"
#include "MainThreadQueue.h"
#include "mozilla/AbstractThread.h"
#include "mozilla/EventQueue.h"
#include "mozilla/Preferences.h"
@ -134,27 +136,11 @@ nsThreadManager::Init()
mMainThread = Scheduler::Init(idlePeriod);
startScheduler = true;
} else {
using MainThreadQueueT = PrioritizedEventQueue<EventQueue>;
auto prioritized = MakeUnique<MainThreadQueueT>(MakeUnique<EventQueue>(),
MakeUnique<EventQueue>(),
MakeUnique<EventQueue>(),
MakeUnique<EventQueue>(),
idlePeriod.forget());
// Save a copy temporarily so we can set some state on it.
MainThreadQueueT* prioritizedRef = prioritized.get();
RefPtr<ThreadEventQueue<MainThreadQueueT>> queue =
new ThreadEventQueue<MainThreadQueueT>(Move(prioritized));
prioritizedRef->SetMutexRef(queue->MutexRef());
// Setup "main" thread
mMainThread = new nsThread(WrapNotNull(queue), nsThread::MAIN_THREAD, 0);
#ifndef RELEASE_OR_BETA
prioritizedRef->SetNextIdleDeadlineRef(mMainThread->NextIdleDeadlineRef());
#endif
if (XRE_IsContentProcess() && Scheduler::UseMultipleQueues()) {
mMainThread = CreateMainThread<ThreadEventQueue<PrioritizedEventQueue<LabeledEventQueue>>, LabeledEventQueue>(idlePeriod);
} else {
mMainThread = CreateMainThread<ThreadEventQueue<PrioritizedEventQueue<EventQueue>>, EventQueue>(idlePeriod);
}
}
nsresult rv = mMainThread->InitCurrentThread();