зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
71009c41fa
Коммит
25a1b0f61f
|
@ -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"
|
||||
|
|
Загрузка…
Ссылка в новой задаче