From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- xpcom/threads/EventQueue.cpp | 131 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 xpcom/threads/EventQueue.cpp (limited to 'xpcom/threads/EventQueue.cpp') diff --git a/xpcom/threads/EventQueue.cpp b/xpcom/threads/EventQueue.cpp new file mode 100644 index 0000000000..0decc3ce4c --- /dev/null +++ b/xpcom/threads/EventQueue.cpp @@ -0,0 +1,131 @@ +/* -*- 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/. */ + +#include "mozilla/EventQueue.h" + +#include "GeckoProfiler.h" +#include "InputTaskManager.h" +#include "VsyncTaskManager.h" +#include "nsIRunnable.h" +#include "TaskController.h" + +using namespace mozilla; +using namespace mozilla::detail; + +template +void EventQueueInternal::PutEvent( + already_AddRefed&& aEvent, EventQueuePriority aPriority, + const MutexAutoLock& aProofOfLock, mozilla::TimeDuration* aDelay) { + nsCOMPtr event(aEvent); + + static_assert(static_cast(nsIRunnablePriority::PRIORITY_IDLE) == + static_cast(EventQueuePriority::Idle)); + static_assert(static_cast(nsIRunnablePriority::PRIORITY_NORMAL) == + static_cast(EventQueuePriority::Normal)); + static_assert( + static_cast(nsIRunnablePriority::PRIORITY_MEDIUMHIGH) == + static_cast(EventQueuePriority::MediumHigh)); + static_assert( + static_cast(nsIRunnablePriority::PRIORITY_INPUT_HIGH) == + static_cast(EventQueuePriority::InputHigh)); + static_assert(static_cast(nsIRunnablePriority::PRIORITY_VSYNC) == + static_cast(EventQueuePriority::Vsync)); + static_assert( + static_cast(nsIRunnablePriority::PRIORITY_RENDER_BLOCKING) == + static_cast(EventQueuePriority::RenderBlocking)); + static_assert(static_cast(nsIRunnablePriority::PRIORITY_CONTROL) == + static_cast(EventQueuePriority::Control)); + + if (mForwardToTC) { + TaskController* tc = TaskController::Get(); + + TaskManager* manager = nullptr; + if (aPriority == EventQueuePriority::InputHigh) { + manager = InputTaskManager::Get(); + } else if (aPriority == EventQueuePriority::DeferredTimers || + aPriority == EventQueuePriority::Idle) { + manager = TaskController::Get()->GetIdleTaskManager(); + } else if (aPriority == EventQueuePriority::Vsync) { + manager = VsyncTaskManager::Get(); + } + + tc->DispatchRunnable(event.forget(), static_cast(aPriority), + manager); + return; + } + + if (profiler_thread_is_being_profiled(ThreadProfilingFeatures::Sampling)) { + // check to see if the profiler has been enabled since the last PutEvent + while (mDispatchTimes.Count() < mQueue.Count()) { + mDispatchTimes.Push(TimeStamp()); + } + mDispatchTimes.Push(aDelay ? TimeStamp::Now() - *aDelay : TimeStamp::Now()); + } + + mQueue.Push(std::move(event)); +} + +template +already_AddRefed EventQueueInternal::GetEvent( + const MutexAutoLock& aProofOfLock, mozilla::TimeDuration* aLastEventDelay) { + if (mQueue.IsEmpty()) { + if (aLastEventDelay) { + *aLastEventDelay = TimeDuration(); + } + return nullptr; + } + + // We always want to clear the dispatch times, even if the profiler is turned + // off, because we want to empty the (previously-collected) dispatch times, if + // any, from when the profiler was turned on. We only want to do something + // interesting with the dispatch times if the profiler is turned on, though. + if (!mDispatchTimes.IsEmpty()) { + TimeStamp dispatch_time = mDispatchTimes.Pop(); + if (profiler_is_active()) { + if (!dispatch_time.IsNull()) { + if (aLastEventDelay) { + *aLastEventDelay = TimeStamp::Now() - dispatch_time; + } + } + } + } else if (profiler_is_active()) { + if (aLastEventDelay) { + // if we just turned on the profiler, we don't have dispatch + // times for events already in the queue. + *aLastEventDelay = TimeDuration(); + } + } + + nsCOMPtr result = mQueue.Pop(); + return result.forget(); +} + +template +bool EventQueueInternal::IsEmpty( + const MutexAutoLock& aProofOfLock) { + return mQueue.IsEmpty(); +} + +template +bool EventQueueInternal::HasReadyEvent( + const MutexAutoLock& aProofOfLock) { + return !IsEmpty(aProofOfLock); +} + +template +size_t EventQueueInternal::Count( + const MutexAutoLock& aProofOfLock) const { + return mQueue.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 -- cgit v1.2.3