diff --git a/xpcom/threads/EventQueue.cpp b/xpcom/threads/EventQueue.cpp index 35371e82af1f..c5a69c56c269 100644 --- a/xpcom/threads/EventQueue.cpp +++ b/xpcom/threads/EventQueue.cpp @@ -7,7 +7,9 @@ #include "mozilla/EventQueue.h" #include "GeckoProfiler.h" +#include "InputTaskManager.h" #include "nsIRunnable.h" +#include "TaskController.h" using namespace mozilla; using namespace mozilla::detail; @@ -20,6 +22,29 @@ template void EventQueueInternal::PutEvent( already_AddRefed&& aEvent, EventQueuePriority aPriority, const MutexAutoLock& aProofOfLock, mozilla::TimeDuration* aDelay) { + nsCOMPtr event(aEvent); + + if (mForwardToTC) { + TaskController* tc = TaskController::Get(); + + TaskManager* manager = nullptr; + if (aPriority == EventQueuePriority::InputHigh) { + if (InputTaskManager::Get()->State() == + InputTaskManager::STATE_DISABLED) { + aPriority = EventQueuePriority::Normal; + } else { + manager = InputTaskManager::Get(); + } + } else if (aPriority == EventQueuePriority::DeferredTimers || + aPriority == EventQueuePriority::Idle) { + manager = TaskController::Get()->GetIdleTaskManager(); + } + + tc->DispatchRunnable(event.forget(), static_cast(aPriority), + manager); + return; + } + #ifdef MOZ_GECKO_PROFILER // Sigh, this doesn't check if this thread is being profiled if (profiler_is_active()) { @@ -31,7 +56,6 @@ void EventQueueInternal::PutEvent( } #endif - nsCOMPtr event(aEvent); mQueue.Push(std::move(event)); } diff --git a/xpcom/threads/EventQueue.h b/xpcom/threads/EventQueue.h index 130253250ca4..4ac607c9cf9a 100644 --- a/xpcom/threads/EventQueue.h +++ b/xpcom/threads/EventQueue.h @@ -24,7 +24,7 @@ class EventQueueInternal : public AbstractEventQueue { public: static const bool SupportsPrioritization = false; - EventQueueInternal() {} + explicit EventQueueInternal(bool aForwardToTC) : mForwardToTC(aForwardToTC) {} explicit EventQueueInternal(EventQueuePriority aPriority); void PutEvent(already_AddRefed&& aEvent, @@ -91,13 +91,17 @@ class EventQueueInternal : public AbstractEventQueue { mozilla::Queue mDispatchTimes; TimeDuration mLastEventDelay; #endif + // This indicates PutEvent forwards runnables to the TaskController. This + // should be true for the top level event queue on the main thread. + bool mForwardToTC; }; } // namespace detail class EventQueue final : public mozilla::detail::EventQueueInternal<16> { public: - EventQueue() : mozilla::detail::EventQueueInternal<16>() {} + explicit EventQueue(bool aForwardToTC = false) + : mozilla::detail::EventQueueInternal<16>(aForwardToTC) {} explicit EventQueue(EventQueuePriority aPriority) : mozilla::detail::EventQueueInternal<16>(aPriority){}; }; @@ -106,7 +110,8 @@ template class EventQueueSized final : public mozilla::detail::EventQueueInternal { public: - EventQueueSized() : mozilla::detail::EventQueueInternal() {} + explicit EventQueueSized(bool aForwardToTC = false) + : mozilla::detail::EventQueueInternal(aForwardToTC) {} explicit EventQueueSized(EventQueuePriority aPriority) : mozilla::detail::EventQueueInternal(aPriority){}; }; diff --git a/xpcom/threads/InputTaskManager.cpp b/xpcom/threads/InputTaskManager.cpp index 8eec0ce20eec..846497826829 100644 --- a/xpcom/threads/InputTaskManager.cpp +++ b/xpcom/threads/InputTaskManager.cpp @@ -72,14 +72,6 @@ void InputTaskManager::DidRunTask() { } // static -InputTaskManager* InputTaskManager::Get() { - MOZ_ASSERT(NS_IsMainThread()); - if (gInputTaskManager) { - return gInputTaskManager.get(); - } - - gInputTaskManager = new InputTaskManager(); - return gInputTaskManager.get(); -} +void InputTaskManager::Init() { gInputTaskManager = new InputTaskManager(); } } // namespace mozilla diff --git a/xpcom/threads/InputTaskManager.h b/xpcom/threads/InputTaskManager.h index 263ad742f104..3327840bdbc9 100644 --- a/xpcom/threads/InputTaskManager.h +++ b/xpcom/threads/InputTaskManager.h @@ -40,8 +40,9 @@ class InputTaskManager : public TaskManager { mInputHandlingStartTime = aStartTime; } - static InputTaskManager* Get(); + static InputTaskManager* Get() { return gInputTaskManager.get(); } static void Cleanup() { gInputTaskManager = nullptr; } + static void Init(); private: InputTaskManager() : mInputQueueState(STATE_DISABLED) {} diff --git a/xpcom/threads/TaskController.cpp b/xpcom/threads/TaskController.cpp index a4caa0be2143..5d7e76d0c48b 100644 --- a/xpcom/threads/TaskController.cpp +++ b/xpcom/threads/TaskController.cpp @@ -79,6 +79,7 @@ bool TaskController::Initialize() { } bool TaskController::InitializeInternal() { + InputTaskManager::Init(); mMTProcessingRunnable = NS_NewRunnableFunction( "TaskController::ExecutePendingMTTasks()", []() { TaskController::Get()->ProcessPendingMTTask(); });