Bug 1669256 - Part 1: Remove AbstractEventQueue and de-templatize ThreadEventQueue. r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D92709
This commit is contained in:
Bas Schouten 2020-10-09 17:56:34 +00:00
Родитель 71009c41fa
Коммит 25a1b0f61f
22 изменённых файлов: 128 добавлений и 237 удалений

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

@ -15,8 +15,8 @@
# include "Logging.h"
#endif
using namespace mozilla;
using namespace mozilla::a11y;
namespace mozilla {
namespace a11y {
// Defines the number of selection add/remove events in the queue when they
// aren't packed into single selection within event.
@ -330,3 +330,6 @@ void EventQueue::ProcessEventQueue() {
if (!mDocument) return;
}
}
} // namespace a11y
} // namespace mozilla

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

@ -6,7 +6,7 @@
#include "TimeoutExecutor.h"
#include "mozilla/AbstractEventQueue.h"
#include "mozilla/EventQueue.h"
#include "mozilla/dom/TimeoutManager.h"
#include "nsComponentManagerUtils.h"
#include "nsIEventTarget.h"

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

@ -406,8 +406,7 @@ void StorageDBThread::SetDefaultPriority() {
void StorageDBThread::ThreadFunc(void* aArg) {
{
auto queue =
MakeRefPtr<ThreadEventQueue<EventQueue>>(MakeUnique<EventQueue>());
auto queue = MakeRefPtr<ThreadEventQueue>(MakeUnique<EventQueue>());
Unused << nsThreadManager::get().CreateCurrentThread(
queue, nsThread::NOT_MAIN_THREAD);
}

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

@ -3842,8 +3842,7 @@ already_AddRefed<nsIEventTarget> WorkerPrivate::CreateNewSyncLoop(
}
}
auto queue =
static_cast<ThreadEventQueue<EventQueue>*>(mThread->EventQueue());
auto queue = static_cast<ThreadEventQueue*>(mThread->EventQueue());
nsCOMPtr<nsISerialEventTarget> realEventTarget = queue->PushEventQueue();
MOZ_ASSERT(realEventTarget);
@ -3966,8 +3965,7 @@ bool WorkerPrivate::DestroySyncLoop(uint32_t aLoopIndex) {
bool result = loopInfo->mResult;
auto queue =
static_cast<ThreadEventQueue<EventQueue>*>(mThread->EventQueue());
auto queue = static_cast<ThreadEventQueue*>(mThread->EventQueue());
queue->PopEventQueue(nestedEventTarget);
// Are we making a 1 -> 0 transition here?

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

@ -66,9 +66,9 @@ class WorkerThread::Observer final : public nsIThreadObserver {
};
WorkerThread::WorkerThread(ConstructorKey)
: nsThread(MakeNotNull<ThreadEventQueue<mozilla::EventQueue>*>(
MakeUnique<mozilla::EventQueue>()),
nsThread::NOT_MAIN_THREAD, kWorkerStackSize),
: nsThread(
MakeNotNull<ThreadEventQueue*>(MakeUnique<mozilla::EventQueue>()),
nsThread::NOT_MAIN_THREAD, kWorkerStackSize),
mLock("WorkerThread::mLock"),
mWorkerPrivateCondVar(mLock, "WorkerThread::mWorkerPrivateCondVar"),
mWorkerPrivate(nullptr),

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

@ -249,9 +249,9 @@ class WorkletThread::TerminateRunnable final : public Runnable {
};
WorkletThread::WorkletThread(WorkletImpl* aWorkletImpl)
: nsThread(MakeNotNull<ThreadEventQueue<mozilla::EventQueue>*>(
MakeUnique<mozilla::EventQueue>()),
nsThread::NOT_MAIN_THREAD, kWorkletStackSize),
: nsThread(
MakeNotNull<ThreadEventQueue*>(MakeUnique<mozilla::EventQueue>()),
nsThread::NOT_MAIN_THREAD, kWorkletStackSize),
mWorkletImpl(aWorkletImpl),
mExitLoop(false),
mIsTerminating(false) {

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

@ -154,9 +154,8 @@ void Thread::ThreadMain() {
auto loopType = startup_data_->options.message_loop_type;
if (loopType == MessageLoop::TYPE_MOZILLA_NONMAINTHREAD ||
loopType == MessageLoop::TYPE_MOZILLA_NONMAINUITHREAD) {
auto queue =
mozilla::MakeRefPtr<mozilla::ThreadEventQueue<mozilla::EventQueue>>(
mozilla::MakeUnique<mozilla::EventQueue>());
auto queue = mozilla::MakeRefPtr<mozilla::ThreadEventQueue>(
mozilla::MakeUnique<mozilla::EventQueue>());
xpcomThread = nsThreadManager::get().CreateCurrentThread(
queue, nsThread::NOT_MAIN_THREAD);
} else {

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

@ -426,8 +426,8 @@ void CacheIOThread::ThreadFunc() {
MOZ_ASSERT(mBlockingIOWatcher);
mBlockingIOWatcher->InitThread();
auto queue = MakeRefPtr<ThreadEventQueue<mozilla::EventQueue>>(
MakeUnique<mozilla::EventQueue>());
auto queue =
MakeRefPtr<ThreadEventQueue>(MakeUnique<mozilla::EventQueue>());
nsCOMPtr<nsIThread> xpcomThread =
nsThreadManager::get().CreateCurrentThread(queue,
nsThread::NOT_MAIN_THREAD);

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

@ -8,7 +8,7 @@
#include "ContentBlockingNotifier.h"
#include "AntiTrackingUtils.h"
#include "mozilla/AbstractEventQueue.h"
#include "mozilla/EventQueue.h"
#include "mozilla/StaticPrefs_privacy.h"
#include "mozilla/dom/BrowserChild.h"
#include "mozilla/dom/BrowsingContext.h"

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

@ -53,9 +53,9 @@ class AndroidUiThread : public nsThread {
public:
NS_INLINE_DECL_REFCOUNTING_INHERITED(AndroidUiThread, nsThread)
AndroidUiThread()
: nsThread(MakeNotNull<ThreadEventQueue<mozilla::EventQueue>*>(
MakeUnique<mozilla::EventQueue>()),
nsThread::NOT_MAIN_THREAD, 0) {}
: nsThread(
MakeNotNull<ThreadEventQueue*>(MakeUnique<mozilla::EventQueue>()),
nsThread::NOT_MAIN_THREAD, 0) {}
nsresult Dispatch(already_AddRefed<nsIRunnable> aEvent,
uint32_t aFlags) override;

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

@ -1,105 +0,0 @@
/* -*- 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_AbstractEventQueue_h
#define mozilla_AbstractEventQueue_h
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/Mutex.h"
class nsIRunnable;
namespace mozilla {
enum class EventQueuePriority {
Idle,
DeferredTimers,
InputLow,
Normal,
MediumHigh,
InputHigh,
High,
Count
};
// AbstractEventQueue is an abstract base class for all our unsynchronized event
// queue implementations:
// - EventQueue: A queue of runnables. Used for non-main threads.
// - PrioritizedEventQueue: Contains a queue for each priority level.
// Has heuristics to decide which queue to pop from. Events are
// pushed into the queue corresponding to their priority.
// Used for the main thread.
//
// Since AbstractEventQueue implementations are unsynchronized, they should be
// wrapped in an outer SynchronizedEventQueue implementation (like
// ThreadEventQueue).
//
// Subclasses should also define a `static const bool SupportsPrioritization`
// member to indicate whether the subclass cares about runnable priorities
// implemented through nsIRunnablePriority.
class AbstractEventQueue {
public:
// Add an event to the end of the queue. Implementors are free to use
// aPriority however they wish. If the runnable supports
// nsIRunnablePriority and the implementing class supports
// prioritization, aPriority represents the result of calling
// nsIRunnablePriority::GetPriority(). *aDelay is time the event has
// already been delayed (used when moving an event from one queue to
// another)
virtual void PutEvent(already_AddRefed<nsIRunnable>&& aEvent,
EventQueuePriority aPriority,
const MutexAutoLock& aProofOfLock,
mozilla::TimeDuration* aDelay = nullptr) = 0;
// Get an event from the front of the queue. aPriority is an out param. If the
// implementation supports priorities, then this should be the same priority
// that the event was pushed with. aPriority may be null. This should return
// null if the queue is non-empty but the event in front is not ready to run.
// *aLastEventDelay is the time the event spent in queues before being
// retrieved.
virtual already_AddRefed<nsIRunnable> GetEvent(
EventQueuePriority* aPriority, const MutexAutoLock& aProofOfLock,
mozilla::TimeDuration* aLastEventDelay = nullptr) = 0;
// Returns true if the queue is empty. Implies !HasReadyEvent().
virtual bool IsEmpty(const MutexAutoLock& aProofOfLock) = 0;
// Returns true if the queue is non-empty and if the event in front is ready
// to run. Implies !IsEmpty(). This should return true iff GetEvent returns a
// non-null value.
virtual bool HasReadyEvent(const MutexAutoLock& aProofOfLock) = 0;
virtual bool HasPendingHighPriorityEvents(
const MutexAutoLock& aProofOfLock) = 0;
// Returns the number of events in the queue.
virtual size_t Count(const MutexAutoLock& aProofOfLock) const = 0;
virtual void EnableInputEventPrioritization(
const MutexAutoLock& aProofOfLock) = 0;
virtual void FlushInputEventPrioritization(
const MutexAutoLock& aProofOfLock) = 0;
virtual void SuspendInputEventPrioritization(
const MutexAutoLock& aProofOfLock) = 0;
virtual void ResumeInputEventPrioritization(
const MutexAutoLock& aProofOfLock) = 0;
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
virtual size_t SizeOfExcludingThis(
mozilla::MallocSizeOf aMallocSizeOf) const = 0;
virtual ~AbstractEventQueue() = default;
};
} // namespace mozilla
#endif // mozilla_AbstractEventQueue_h

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

@ -14,10 +14,6 @@
using namespace mozilla;
using namespace mozilla::detail;
template <size_t ItemsPerPage>
EventQueueInternal<ItemsPerPage>::EventQueueInternal(
EventQueuePriority aPriority) {}
template <size_t ItemsPerPage>
void EventQueueInternal<ItemsPerPage>::PutEvent(
already_AddRefed<nsIRunnable>&& aEvent, EventQueuePriority aPriority,
@ -122,4 +118,8 @@ size_t EventQueueInternal<ItemsPerPage>::Count(
namespace mozilla {
template class EventQueueSized<16>; // Used by ThreadEventQueue
template class EventQueueSized<64>; // Used by ThrottledEventQueue
namespace detail {
template class EventQueueInternal<16>; // Used by ThreadEventQueue
template class EventQueueInternal<64>; // Used by ThrottledEventQueue
} // namespace detail
} // namespace mozilla

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

@ -7,7 +7,7 @@
#ifndef mozilla_EventQueue_h
#define mozilla_EventQueue_h
#include "mozilla/AbstractEventQueue.h"
#include "mozilla/Mutex.h"
#include "mozilla/Queue.h"
#include "nsCOMPtr.h"
@ -15,24 +15,53 @@ class nsIRunnable;
namespace mozilla {
enum class EventQueuePriority {
Idle,
DeferredTimers,
InputLow,
Normal,
MediumHigh,
InputHigh,
High,
Count
};
class IdlePeriodState;
namespace detail {
// EventQueue is our unsynchronized event queue implementation. It is a queue
// of runnables used for non-main thread, as well as optionally providing
// forwarding to TaskController.
//
// Since EventQueue is unsynchronized, it should be wrapped in an outer
// SynchronizedEventQueue implementation (like ThreadEventQueue).
template <size_t ItemsPerPage>
class EventQueueInternal : public AbstractEventQueue {
class EventQueueInternal {
public:
static const bool SupportsPrioritization = false;
explicit EventQueueInternal(bool aForwardToTC) : mForwardToTC(aForwardToTC) {}
explicit EventQueueInternal(EventQueuePriority aPriority);
// Add an event to the end of the queue. Implementors are free to use
// aPriority however they wish. If the runnable supports
// nsIRunnablePriority and the implementing class supports
// prioritization, aPriority represents the result of calling
// nsIRunnablePriority::GetPriority(). *aDelay is time the event has
// already been delayed (used when moving an event from one queue to
// another)
void PutEvent(already_AddRefed<nsIRunnable>&& aEvent,
EventQueuePriority aPriority, const MutexAutoLock& aProofOfLock,
mozilla::TimeDuration* aDelay = nullptr) final;
mozilla::TimeDuration* aDelay = nullptr);
// Get an event from the front of the queue. aPriority is an out param. If the
// implementation supports priorities, then this should be the same priority
// that the event was pushed with. aPriority may be null. This should return
// null if the queue is non-empty but the event in front is not ready to run.
// *aLastEventDelay is the time the event spent in queues before being
// retrieved.
already_AddRefed<nsIRunnable> GetEvent(
EventQueuePriority* aPriority, const MutexAutoLock& aProofOfLock,
mozilla::TimeDuration* aLastEventDelay = nullptr) final;
mozilla::TimeDuration* aLastEventDelay = nullptr);
already_AddRefed<nsIRunnable> GetEvent(EventQueuePriority* aPriority,
const MutexAutoLock& aProofOfLock,
TimeDuration* aLastEventDelay,
@ -43,14 +72,20 @@ class EventQueueInternal : public AbstractEventQueue {
void DidRunEvent(const MutexAutoLock& aProofOfLock) {}
bool IsEmpty(const MutexAutoLock& aProofOfLock) final;
bool HasReadyEvent(const MutexAutoLock& aProofOfLock) final;
bool HasPendingHighPriorityEvents(const MutexAutoLock& aProofOfLock) final {
// Returns true if the queue is empty. Implies !HasReadyEvent().
bool IsEmpty(const MutexAutoLock& aProofOfLock);
// Returns true if the queue is non-empty and if the event in front is ready
// to run. Implies !IsEmpty(). This should return true iff GetEvent returns a
// non-null value.
bool HasReadyEvent(const MutexAutoLock& aProofOfLock);
bool HasPendingHighPriorityEvents(const MutexAutoLock& aProofOfLock) {
// EventQueueInternal doesn't support any prioritization.
return false;
}
size_t Count(const MutexAutoLock& aProofOfLock) const final;
// Returns the number of events in the queue.
size_t Count(const MutexAutoLock& aProofOfLock) const;
// For some reason, if we put this in the .cpp file the linker can't find it
already_AddRefed<nsIRunnable> PeekEvent(const MutexAutoLock& aProofOfLock) {
if (mQueue.IsEmpty()) {
@ -61,12 +96,13 @@ class EventQueueInternal : public AbstractEventQueue {
return result.forget();
}
void EnableInputEventPrioritization(const MutexAutoLock& aProofOfLock) final {
}
void FlushInputEventPrioritization(const MutexAutoLock& aProofOfLock) final {}
void SuspendInputEventPrioritization(
const MutexAutoLock& aProofOfLock) final {}
void ResumeInputEventPrioritization(const MutexAutoLock& aProofOfLock) final {
void EnableInputEventPrioritization(const MutexAutoLock& aProofOfLock) {}
void FlushInputEventPrioritization(const MutexAutoLock& aProofOfLock) {}
void SuspendInputEventPrioritization(const MutexAutoLock& aProofOfLock) {}
void ResumeInputEventPrioritization(const MutexAutoLock& aProofOfLock) {}
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
IdlePeriodState* GetIdlePeriodState() const { return nullptr; }
@ -75,8 +111,7 @@ class EventQueueInternal : public AbstractEventQueue {
return false;
}
size_t SizeOfExcludingThis(
mozilla::MallocSizeOf aMallocSizeOf) const override {
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
size_t size = mQueue.ShallowSizeOfExcludingThis(aMallocSizeOf);
#ifdef MOZ_GECKO_PROFILER
size += mDispatchTimes.ShallowSizeOfExcludingThis(aMallocSizeOf);
@ -102,8 +137,6 @@ class EventQueue final : public mozilla::detail::EventQueueInternal<16> {
public:
explicit EventQueue(bool aForwardToTC = false)
: mozilla::detail::EventQueueInternal<16>(aForwardToTC) {}
explicit EventQueue(EventQueuePriority aPriority)
: mozilla::detail::EventQueueInternal<16>(aPriority){};
};
template <size_t ItemsPerPage = 16>
@ -112,8 +145,6 @@ class EventQueueSized final
public:
explicit EventQueueSized(bool aForwardToTC = false)
: mozilla::detail::EventQueueInternal<ItemsPerPage>(aForwardToTC) {}
explicit EventQueueSized(EventQueuePriority aPriority)
: mozilla::detail::EventQueueInternal<ItemsPerPage>(aPriority){};
};
} // namespace mozilla

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

@ -7,7 +7,7 @@
#ifndef mozilla_SchedulerGroup_h
#define mozilla_SchedulerGroup_h
#include "mozilla/AbstractEventQueue.h"
#include "mozilla/EventQueue.h"
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/LinkedList.h"
#include "mozilla/Queue.h"

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

@ -8,7 +8,7 @@
#define mozilla_SynchronizedEventQueue_h
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/AbstractEventQueue.h"
#include "mozilla/EventQueue.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Mutex.h"
#include "nsIThreadInternal.h"

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

@ -10,7 +10,7 @@
#include "nsThreadUtils.h"
#include <algorithm>
#include <initializer_list>
#include "mozilla/AbstractEventQueue.h"
#include "mozilla/EventQueue.h"
#include "mozilla/BackgroundHangMonitor.h"
#include "mozilla/InputTaskManager.h"
#include "mozilla/StaticMutex.h"

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

@ -17,8 +17,7 @@
using namespace mozilla;
template <class InnerQueueT>
class ThreadEventQueue<InnerQueueT>::NestedSink : public ThreadTargetSink {
class ThreadEventQueue::NestedSink : public ThreadTargetSink {
public:
NestedSink(EventQueue* aQueue, ThreadEventQueue* aOwner)
: mQueue(aQueue), mOwner(aOwner) {}
@ -46,9 +45,8 @@ class ThreadEventQueue<InnerQueueT>::NestedSink : public ThreadTargetSink {
RefPtr<ThreadEventQueue> mOwner;
};
template <class InnerQueueT>
ThreadEventQueue<InnerQueueT>::ThreadEventQueue(UniquePtr<InnerQueueT> aQueue,
bool aIsMainThread)
ThreadEventQueue::ThreadEventQueue(UniquePtr<EventQueue> aQueue,
bool aIsMainThread)
: mBaseQueue(std::move(aQueue)),
mLock("ThreadEventQueue"),
mEventsAvailable(mLock, "EventsAvail"),
@ -56,25 +54,18 @@ ThreadEventQueue<InnerQueueT>::ThreadEventQueue(UniquePtr<InnerQueueT> aQueue,
if (aIsMainThread) {
TaskController::Get()->SetConditionVariable(&mEventsAvailable);
}
static_assert(std::is_base_of<AbstractEventQueue, InnerQueueT>::value,
"InnerQueueT must be an AbstractEventQueue subclass");
}
template <class InnerQueueT>
ThreadEventQueue<InnerQueueT>::~ThreadEventQueue() {
MOZ_ASSERT(mNestedQueues.IsEmpty());
}
ThreadEventQueue::~ThreadEventQueue() { MOZ_ASSERT(mNestedQueues.IsEmpty()); }
template <class InnerQueueT>
bool ThreadEventQueue<InnerQueueT>::PutEvent(
already_AddRefed<nsIRunnable>&& aEvent, EventQueuePriority aPriority) {
bool ThreadEventQueue::PutEvent(already_AddRefed<nsIRunnable>&& aEvent,
EventQueuePriority aPriority) {
return PutEventInternal(std::move(aEvent), aPriority, nullptr);
}
template <class InnerQueueT>
bool ThreadEventQueue<InnerQueueT>::PutEventInternal(
already_AddRefed<nsIRunnable>&& aEvent, EventQueuePriority aPriority,
NestedSink* aSink) {
bool ThreadEventQueue::PutEventInternal(already_AddRefed<nsIRunnable>&& aEvent,
EventQueuePriority aPriority,
NestedSink* aSink) {
// We want to leak the reference when we fail to dispatch it, so that
// we won't release the event in a wrong thread.
LeakRefPtr<nsIRunnable> event(std::move(aEvent));
@ -135,8 +126,7 @@ bool ThreadEventQueue<InnerQueueT>::PutEventInternal(
return true;
}
template <class InnerQueueT>
already_AddRefed<nsIRunnable> ThreadEventQueue<InnerQueueT>::GetEvent(
already_AddRefed<nsIRunnable> ThreadEventQueue::GetEvent(
bool aMayWait, EventQueuePriority* aPriority,
mozilla::TimeDuration* aLastEventDelay) {
nsCOMPtr<nsIRunnable> event;
@ -230,8 +220,7 @@ already_AddRefed<nsIRunnable> ThreadEventQueue<InnerQueueT>::GetEvent(
return event.forget();
}
template <class InnerQueueT>
void ThreadEventQueue<InnerQueueT>::DidRunEvent() {
void ThreadEventQueue::DidRunEvent() {
MutexAutoLock lock(mLock);
if (mNestedQueues.IsEmpty()) {
mBaseQueue->DidRunEvent(lock);
@ -242,8 +231,7 @@ void ThreadEventQueue<InnerQueueT>::DidRunEvent() {
}
}
template <class InnerQueueT>
bool ThreadEventQueue<InnerQueueT>::HasPendingEvent() {
bool ThreadEventQueue::HasPendingEvent() {
MutexAutoLock lock(mLock);
// We always get events from the topmost queue when there are nested queues.
@ -254,8 +242,7 @@ bool ThreadEventQueue<InnerQueueT>::HasPendingEvent() {
}
}
template <class InnerQueueT>
bool ThreadEventQueue<InnerQueueT>::HasPendingHighPriorityEvents() {
bool ThreadEventQueue::HasPendingHighPriorityEvents() {
MutexAutoLock lock(mLock);
// We always get events from the topmost queue when there are nested queues.
@ -267,8 +254,7 @@ bool ThreadEventQueue<InnerQueueT>::HasPendingHighPriorityEvents() {
}
}
template <class InnerQueueT>
bool ThreadEventQueue<InnerQueueT>::ShutdownIfNoPendingEvents() {
bool ThreadEventQueue::ShutdownIfNoPendingEvents() {
MutexAutoLock lock(mLock);
if (mNestedQueues.IsEmpty() && mBaseQueue->IsEmpty(lock)) {
mEventsAreDoomed = true;
@ -277,33 +263,27 @@ bool ThreadEventQueue<InnerQueueT>::ShutdownIfNoPendingEvents() {
return false;
}
template <class InnerQueueT>
void ThreadEventQueue<InnerQueueT>::EnableInputEventPrioritization() {
void ThreadEventQueue::EnableInputEventPrioritization() {
MutexAutoLock lock(mLock);
mBaseQueue->EnableInputEventPrioritization(lock);
}
template <class InnerQueueT>
void ThreadEventQueue<InnerQueueT>::FlushInputEventPrioritization() {
void ThreadEventQueue::FlushInputEventPrioritization() {
MutexAutoLock lock(mLock);
mBaseQueue->FlushInputEventPrioritization(lock);
}
template <class InnerQueueT>
void ThreadEventQueue<InnerQueueT>::SuspendInputEventPrioritization() {
void ThreadEventQueue::SuspendInputEventPrioritization() {
MutexAutoLock lock(mLock);
mBaseQueue->SuspendInputEventPrioritization(lock);
}
template <class InnerQueueT>
void ThreadEventQueue<InnerQueueT>::ResumeInputEventPrioritization() {
void ThreadEventQueue::ResumeInputEventPrioritization() {
MutexAutoLock lock(mLock);
mBaseQueue->ResumeInputEventPrioritization(lock);
}
template <class InnerQueueT>
already_AddRefed<nsISerialEventTarget>
ThreadEventQueue<InnerQueueT>::PushEventQueue() {
already_AddRefed<nsISerialEventTarget> ThreadEventQueue::PushEventQueue() {
auto queue = MakeUnique<EventQueue>();
RefPtr<NestedSink> sink = new NestedSink(queue.get(), this);
RefPtr<ThreadEventTarget> eventTarget =
@ -315,8 +295,7 @@ ThreadEventQueue<InnerQueueT>::PushEventQueue() {
return eventTarget.forget();
}
template <class InnerQueueT>
void ThreadEventQueue<InnerQueueT>::PopEventQueue(nsIEventTarget* aTarget) {
void ThreadEventQueue::PopEventQueue(nsIEventTarget* aTarget) {
MutexAutoLock lock(mLock);
MOZ_ASSERT(!mNestedQueues.IsEmpty());
@ -328,11 +307,10 @@ void ThreadEventQueue<InnerQueueT>::PopEventQueue(nsIEventTarget* aTarget) {
// Disconnect the event target that will be popped.
item.mEventTarget->Disconnect(lock);
AbstractEventQueue* prevQueue =
EventQueue* prevQueue =
mNestedQueues.Length() == 1
? static_cast<AbstractEventQueue*>(mBaseQueue.get())
: static_cast<AbstractEventQueue*>(
mNestedQueues[mNestedQueues.Length() - 2].mQueue.get());
? mBaseQueue.get()
: mNestedQueues[mNestedQueues.Length() - 2].mQueue.get();
// Move events from the old queue to the new one.
nsCOMPtr<nsIRunnable> event;
@ -346,8 +324,7 @@ void ThreadEventQueue<InnerQueueT>::PopEventQueue(nsIEventTarget* aTarget) {
mNestedQueues.RemoveLastElement();
}
template <class InnerQueueT>
size_t ThreadEventQueue<InnerQueueT>::SizeOfExcludingThis(
size_t ThreadEventQueue::SizeOfExcludingThis(
mozilla::MallocSizeOf aMallocSizeOf) const {
size_t n = 0;
@ -361,21 +338,16 @@ size_t ThreadEventQueue<InnerQueueT>::SizeOfExcludingThis(
return SynchronizedEventQueue::SizeOfExcludingThis(aMallocSizeOf) + n;
}
template <class InnerQueueT>
already_AddRefed<nsIThreadObserver>
ThreadEventQueue<InnerQueueT>::GetObserver() {
already_AddRefed<nsIThreadObserver> ThreadEventQueue::GetObserver() {
MutexAutoLock lock(mLock);
return do_AddRef(mObserver);
}
template <class InnerQueueT>
already_AddRefed<nsIThreadObserver>
ThreadEventQueue<InnerQueueT>::GetObserverOnThread() {
already_AddRefed<nsIThreadObserver> ThreadEventQueue::GetObserverOnThread() {
return do_AddRef(mObserver);
}
template <class InnerQueueT>
void ThreadEventQueue<InnerQueueT>::SetObserver(nsIThreadObserver* aObserver) {
void ThreadEventQueue::SetObserver(nsIThreadObserver* aObserver) {
MutexAutoLock lock(mLock);
mObserver = aObserver;
if (NS_IsMainThread()) {
@ -383,6 +355,6 @@ void ThreadEventQueue<InnerQueueT>::SetObserver(nsIThreadObserver* aObserver) {
}
}
namespace mozilla {
template class ThreadEventQueue<EventQueue>;
} // namespace mozilla
ThreadEventQueue::NestedQueueItem::NestedQueueItem(
UniquePtr<EventQueue> aQueue, ThreadEventTarget* aEventTarget)
: mQueue(std::move(aQueue)), mEventTarget(aEventTarget) {}

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

@ -7,7 +7,7 @@
#ifndef mozilla_ThreadEventQueue_h
#define mozilla_ThreadEventQueue_h
#include "mozilla/AbstractEventQueue.h"
#include "mozilla/EventQueue.h"
#include "mozilla/CondVar.h"
#include "mozilla/SynchronizedEventQueue.h"
#include "nsCOMPtr.h"
@ -23,14 +23,13 @@ class EventQueue;
class ThreadEventTarget;
// A ThreadEventQueue implements normal monitor-style synchronization over the
// InnerQueueT AbstractEventQueue. It also implements PushEventQueue and
// PopEventQueue for workers (see the documentation below for an explanation of
// those). All threads use a ThreadEventQueue as their event queue. InnerQueueT
// is a template parameter to avoid virtual dispatch overhead.
template <class InnerQueueT>
// EventQueue. It also implements PushEventQueue and PopEventQueue for workers
// (see the documentation below for an explanation of those). All threads use a
// ThreadEventQueue as their event queue. Although for the main thread this
// simply forwards events to the TaskController.
class ThreadEventQueue final : public SynchronizedEventQueue {
public:
explicit ThreadEventQueue(UniquePtr<InnerQueueT> aQueue,
explicit ThreadEventQueue(UniquePtr<EventQueue> aQueue,
bool aIsMainThread = false);
bool PutEvent(already_AddRefed<nsIRunnable>&& aEvent,
@ -72,15 +71,14 @@ class ThreadEventQueue final : public SynchronizedEventQueue {
bool PutEventInternal(already_AddRefed<nsIRunnable>&& aEvent,
EventQueuePriority aPriority, NestedSink* aQueue);
UniquePtr<InnerQueueT> mBaseQueue;
UniquePtr<EventQueue> mBaseQueue;
struct NestedQueueItem {
UniquePtr<EventQueue> mQueue;
RefPtr<ThreadEventTarget> mEventTarget;
NestedQueueItem(UniquePtr<EventQueue> aQueue,
ThreadEventTarget* aEventTarget)
: mQueue(std::move(aQueue)), mEventTarget(aEventTarget) {}
ThreadEventTarget* aEventTarget);
};
nsTArray<NestedQueueItem> mNestedQueues;
@ -93,8 +91,6 @@ class ThreadEventQueue final : public SynchronizedEventQueue {
bool mIsMainThread;
};
extern template class ThreadEventQueue<EventQueue>;
}; // namespace mozilla
} // namespace mozilla
#endif // mozilla_ThreadEventQueue_h

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

@ -41,7 +41,6 @@ EXPORTS += [
]
EXPORTS.mozilla += [
'AbstractEventQueue.h',
'AbstractThread.h',
'BlockingResourceBase.h',
'CondVar.h',

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

@ -32,7 +32,6 @@
namespace mozilla {
class CycleCollectedJSContext;
class EventQueue;
template <typename>
class ThreadEventQueue;
class ThreadEventTarget;
} // namespace mozilla

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

@ -382,8 +382,8 @@ nsresult nsThreadManager::Init() {
// construct main thread.
UniquePtr<EventQueue> queue = MakeUnique<EventQueue>(true);
RefPtr<ThreadEventQueue<EventQueue>> synchronizedQueue =
new ThreadEventQueue<EventQueue>(std::move(queue), true);
RefPtr<ThreadEventQueue> synchronizedQueue =
new ThreadEventQueue(std::move(queue), true);
mMainThread =
new nsThread(WrapNotNull(synchronizedQueue), nsThread::MAIN_THREAD, 0);
@ -629,8 +629,8 @@ nsThreadManager::NewNamedThread(const nsACString& aName, uint32_t aStackSize,
return NS_ERROR_NOT_INITIALIZED;
}
RefPtr<ThreadEventQueue<EventQueue>> queue =
new ThreadEventQueue<EventQueue>(MakeUnique<EventQueue>());
RefPtr<ThreadEventQueue> queue =
new ThreadEventQueue(MakeUnique<EventQueue>());
RefPtr<nsThread> thr =
new nsThread(WrapNotNull(queue), nsThread::NOT_MAIN_THREAD, aStackSize);
nsresult rv =

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

@ -11,7 +11,7 @@
#include <utility>
#include "MainThreadUtils.h"
#include "mozilla/AbstractEventQueue.h"
#include "mozilla/EventQueue.h"
#include "mozilla/AbstractThread.h"
#include "mozilla/Atomics.h"
#include "mozilla/Likely.h"