1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_EventQueue_h
8 #define mozilla_EventQueue_h
10 #include "mozilla/Mutex.h"
11 #include "mozilla/Queue.h"
12 #include "mozilla/TimeStamp.h"
19 enum class EventQueuePriority
{
34 class IdlePeriodState
;
38 // EventQueue is our unsynchronized event queue implementation. It is a queue
39 // of runnables used for non-main thread, as well as optionally providing
40 // forwarding to TaskController.
42 // Since EventQueue is unsynchronized, it should be wrapped in an outer
43 // SynchronizedEventQueue implementation (like ThreadEventQueue).
44 template <size_t ItemsPerPage
>
45 class EventQueueInternal
{
47 explicit EventQueueInternal(bool aForwardToTC
) : mForwardToTC(aForwardToTC
) {}
49 // Add an event to the end of the queue. Implementors are free to use
50 // aPriority however they wish. If the runnable supports
51 // nsIRunnablePriority and the implementing class supports
52 // prioritization, aPriority represents the result of calling
53 // nsIRunnablePriority::GetPriority(). *aDelay is time the event has
54 // already been delayed (used when moving an event from one queue to
56 void PutEvent(already_AddRefed
<nsIRunnable
>&& aEvent
,
57 EventQueuePriority aPriority
, const MutexAutoLock
& aProofOfLock
,
58 mozilla::TimeDuration
* aDelay
= nullptr);
60 // Get an event from the front of the queue. This should return null if the
61 // queue is non-empty but the event in front is not ready to run.
62 // *aLastEventDelay is the time the event spent in queues before being
64 already_AddRefed
<nsIRunnable
> GetEvent(
65 const MutexAutoLock
& aProofOfLock
,
66 mozilla::TimeDuration
* aLastEventDelay
= nullptr);
68 // Returns true if the queue is empty. Implies !HasReadyEvent().
69 bool IsEmpty(const MutexAutoLock
& aProofOfLock
);
71 // Returns true if the queue is non-empty and if the event in front is ready
72 // to run. Implies !IsEmpty(). This should return true iff GetEvent returns a
74 bool HasReadyEvent(const MutexAutoLock
& aProofOfLock
);
76 // Returns the number of events in the queue.
77 size_t Count(const MutexAutoLock
& aProofOfLock
) const;
78 // For some reason, if we put this in the .cpp file the linker can't find it
79 already_AddRefed
<nsIRunnable
> PeekEvent(const MutexAutoLock
& aProofOfLock
) {
80 if (mQueue
.IsEmpty()) {
84 nsCOMPtr
<nsIRunnable
> result
= mQueue
.FirstElement();
85 return result
.forget();
88 void EnableInputEventPrioritization(const MutexAutoLock
& aProofOfLock
) {}
89 void FlushInputEventPrioritization(const MutexAutoLock
& aProofOfLock
) {}
90 void SuspendInputEventPrioritization(const MutexAutoLock
& aProofOfLock
) {}
91 void ResumeInputEventPrioritization(const MutexAutoLock
& aProofOfLock
) {}
93 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf
) const {
94 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf
);
97 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf
) const {
98 size_t size
= mQueue
.ShallowSizeOfExcludingThis(aMallocSizeOf
);
99 size
+= mDispatchTimes
.ShallowSizeOfExcludingThis(aMallocSizeOf
);
104 mozilla::Queue
<nsCOMPtr
<nsIRunnable
>, ItemsPerPage
> mQueue
;
105 // This queue is only populated when the profiler is turned on.
106 mozilla::Queue
<mozilla::TimeStamp
, ItemsPerPage
> mDispatchTimes
;
107 TimeDuration mLastEventDelay
;
108 // This indicates PutEvent forwards runnables to the TaskController. This
109 // should be true for the top level event queue on the main thread.
113 } // namespace detail
115 class EventQueue final
: public mozilla::detail::EventQueueInternal
<16> {
117 explicit EventQueue(bool aForwardToTC
= false)
118 : mozilla::detail::EventQueueInternal
<16>(aForwardToTC
) {}
121 template <size_t ItemsPerPage
= 16>
122 class EventQueueSized final
123 : public mozilla::detail::EventQueueInternal
<ItemsPerPage
> {
125 explicit EventQueueSized(bool aForwardToTC
= false)
126 : mozilla::detail::EventQueueInternal
<ItemsPerPage
>(aForwardToTC
) {}
129 } // namespace mozilla
131 #endif // mozilla_EventQueue_h