/src/mozilla-central/xpcom/threads/ThreadEventQueue.cpp
Line | Count | Source (jump to first uncovered line) |
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/. */ |
6 | | |
7 | | #include "mozilla/ThreadEventQueue.h" |
8 | | #include "mozilla/EventQueue.h" |
9 | | #include "LabeledEventQueue.h" |
10 | | |
11 | | #include "LeakRefPtr.h" |
12 | | #include "nsComponentManagerUtils.h" |
13 | | #include "nsIThreadInternal.h" |
14 | | #include "nsThreadUtils.h" |
15 | | #include "PrioritizedEventQueue.h" |
16 | | #include "ThreadEventTarget.h" |
17 | | |
18 | | using namespace mozilla; |
19 | | |
20 | | template<class InnerQueueT> |
21 | | class ThreadEventQueue<InnerQueueT>::NestedSink : public ThreadTargetSink |
22 | | { |
23 | | public: |
24 | | NestedSink(EventQueue* aQueue, ThreadEventQueue* aOwner) |
25 | | : mQueue(aQueue) |
26 | | , mOwner(aOwner) |
27 | 0 | { |
28 | 0 | } Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::EventQueue>::NestedSink::NestedSink(mozilla::EventQueue*, mozilla::ThreadEventQueue<mozilla::EventQueue>*) Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::NestedSink::NestedSink(mozilla::EventQueue*, mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >*) Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::NestedSink::NestedSink(mozilla::EventQueue*, mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >*) |
29 | | |
30 | | bool PutEvent(already_AddRefed<nsIRunnable>&& aEvent, |
31 | | EventPriority aPriority) final |
32 | 0 | { |
33 | 0 | return mOwner->PutEventInternal(std::move(aEvent), aPriority, this); |
34 | 0 | } Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::EventQueue>::NestedSink::PutEvent(already_AddRefed<nsIRunnable>&&, mozilla::EventPriority) Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::NestedSink::PutEvent(already_AddRefed<nsIRunnable>&&, mozilla::EventPriority) Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::NestedSink::PutEvent(already_AddRefed<nsIRunnable>&&, mozilla::EventPriority) |
35 | | |
36 | | void Disconnect(const MutexAutoLock& aProofOfLock) final |
37 | 0 | { |
38 | 0 | mQueue = nullptr; |
39 | 0 | } Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::EventQueue>::NestedSink::Disconnect(mozilla::BaseAutoLock<mozilla::Mutex&> const&) Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::NestedSink::Disconnect(mozilla::BaseAutoLock<mozilla::Mutex&> const&) Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::NestedSink::Disconnect(mozilla::BaseAutoLock<mozilla::Mutex&> const&) |
40 | | |
41 | | size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
42 | 0 | { |
43 | 0 | if (mQueue) { |
44 | 0 | return mQueue->SizeOfIncludingThis(aMallocSizeOf); |
45 | 0 | } |
46 | 0 | return 0; |
47 | 0 | } Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::EventQueue>::NestedSink::SizeOfExcludingThis(unsigned long (*)(void const*)) const Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::NestedSink::SizeOfExcludingThis(unsigned long (*)(void const*)) const Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::NestedSink::SizeOfExcludingThis(unsigned long (*)(void const*)) const |
48 | | |
49 | | private: |
50 | | friend class ThreadEventQueue; |
51 | | |
52 | | // This is a non-owning reference. It must live at least until Disconnect is |
53 | | // called to clear it out. |
54 | | EventQueue* mQueue; |
55 | | RefPtr<ThreadEventQueue> mOwner; |
56 | | }; |
57 | | |
58 | | template<class InnerQueueT> |
59 | | ThreadEventQueue<InnerQueueT>::ThreadEventQueue(UniquePtr<InnerQueueT> aQueue) |
60 | | : mBaseQueue(std::move(aQueue)) |
61 | | , mLock("ThreadEventQueue") |
62 | | , mEventsAvailable(mLock, "EventsAvail") |
63 | 46 | { |
64 | 46 | static_assert(IsBaseOf<AbstractEventQueue, InnerQueueT>::value, |
65 | 46 | "InnerQueueT must be an AbstractEventQueue subclass"); |
66 | 46 | } mozilla::ThreadEventQueue<mozilla::EventQueue>::ThreadEventQueue(mozilla::UniquePtr<mozilla::EventQueue, mozilla::DefaultDelete<mozilla::EventQueue> >) Line | Count | Source | 63 | 43 | { | 64 | 43 | static_assert(IsBaseOf<AbstractEventQueue, InnerQueueT>::value, | 65 | 43 | "InnerQueueT must be an AbstractEventQueue subclass"); | 66 | 43 | } |
mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::ThreadEventQueue(mozilla::UniquePtr<mozilla::PrioritizedEventQueue<mozilla::EventQueue>, mozilla::DefaultDelete<mozilla::PrioritizedEventQueue<mozilla::EventQueue> > >) Line | Count | Source | 63 | 3 | { | 64 | 3 | static_assert(IsBaseOf<AbstractEventQueue, InnerQueueT>::value, | 65 | 3 | "InnerQueueT must be an AbstractEventQueue subclass"); | 66 | 3 | } |
Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::ThreadEventQueue(mozilla::UniquePtr<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue>, mozilla::DefaultDelete<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> > >) |
67 | | |
68 | | template<class InnerQueueT> |
69 | | ThreadEventQueue<InnerQueueT>::~ThreadEventQueue() |
70 | 0 | { |
71 | 0 | MOZ_ASSERT(mNestedQueues.IsEmpty()); |
72 | 0 | } Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::EventQueue>::~ThreadEventQueue() Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::~ThreadEventQueue() Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::~ThreadEventQueue() |
73 | | |
74 | | template<class InnerQueueT> |
75 | | bool |
76 | | ThreadEventQueue<InnerQueueT>::PutEvent(already_AddRefed<nsIRunnable>&& aEvent, |
77 | | EventPriority aPriority) |
78 | 194 | { |
79 | 194 | return PutEventInternal(std::move(aEvent), aPriority, nullptr); |
80 | 194 | } mozilla::ThreadEventQueue<mozilla::EventQueue>::PutEvent(already_AddRefed<nsIRunnable>&&, mozilla::EventPriority) Line | Count | Source | 78 | 31 | { | 79 | 31 | return PutEventInternal(std::move(aEvent), aPriority, nullptr); | 80 | 31 | } |
mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::PutEvent(already_AddRefed<nsIRunnable>&&, mozilla::EventPriority) Line | Count | Source | 78 | 163 | { | 79 | 163 | return PutEventInternal(std::move(aEvent), aPriority, nullptr); | 80 | 163 | } |
Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::PutEvent(already_AddRefed<nsIRunnable>&&, mozilla::EventPriority) |
81 | | |
82 | | template<class InnerQueueT> |
83 | | bool |
84 | | ThreadEventQueue<InnerQueueT>::PutEventInternal(already_AddRefed<nsIRunnable>&& aEvent, |
85 | | EventPriority aPriority, |
86 | | NestedSink* aSink) |
87 | 194 | { |
88 | 194 | // We want to leak the reference when we fail to dispatch it, so that |
89 | 194 | // we won't release the event in a wrong thread. |
90 | 194 | LeakRefPtr<nsIRunnable> event(std::move(aEvent)); |
91 | 194 | nsCOMPtr<nsIThreadObserver> obs; |
92 | 194 | |
93 | 194 | { |
94 | 194 | // Check if the runnable wants to override the passed-in priority. |
95 | 194 | // Do this outside the lock, so runnables implemented in JS can QI |
96 | 194 | // (and possibly GC) outside of the lock. |
97 | 194 | if (InnerQueueT::SupportsPrioritization) { |
98 | 163 | auto* e = event.get(); // can't do_QueryInterface on LeakRefPtr. |
99 | 163 | if (nsCOMPtr<nsIRunnablePriority> runnablePrio = do_QueryInterface(e)) { |
100 | 0 | uint32_t prio = nsIRunnablePriority::PRIORITY_NORMAL; |
101 | 0 | runnablePrio->GetPriority(&prio); |
102 | 0 | if (prio == nsIRunnablePriority::PRIORITY_HIGH) { |
103 | 0 | aPriority = EventPriority::High; |
104 | 0 | } else if (prio == nsIRunnablePriority::PRIORITY_INPUT) { |
105 | 0 | aPriority = EventPriority::Input; |
106 | 0 | } |
107 | 0 | } |
108 | 163 | } |
109 | 194 | |
110 | 194 | MutexAutoLock lock(mLock); |
111 | 194 | |
112 | 194 | if (mEventsAreDoomed) { |
113 | 0 | return false; |
114 | 0 | } |
115 | 194 | |
116 | 194 | if (aSink) { |
117 | 0 | if (!aSink->mQueue) { |
118 | 0 | return false; |
119 | 0 | } |
120 | 0 | |
121 | 0 | aSink->mQueue->PutEvent(event.take(), aPriority, lock); |
122 | 194 | } else { |
123 | 194 | mBaseQueue->PutEvent(event.take(), aPriority, lock); |
124 | 194 | } |
125 | 194 | |
126 | 194 | mEventsAvailable.Notify(); |
127 | 194 | |
128 | 194 | // Make sure to grab the observer before dropping the lock, otherwise the |
129 | 194 | // event that we just placed into the queue could run and eventually delete |
130 | 194 | // this nsThread before the calling thread is scheduled again. We would then |
131 | 194 | // crash while trying to access a dead nsThread. |
132 | 194 | obs = mObserver; |
133 | 194 | } |
134 | 194 | |
135 | 194 | if (obs) { |
136 | 5 | obs->OnDispatchedEvent(); |
137 | 5 | } |
138 | 194 | |
139 | 194 | return true; |
140 | 194 | } mozilla::ThreadEventQueue<mozilla::EventQueue>::PutEventInternal(already_AddRefed<nsIRunnable>&&, mozilla::EventPriority, mozilla::ThreadEventQueue<mozilla::EventQueue>::NestedSink*) Line | Count | Source | 87 | 31 | { | 88 | 31 | // We want to leak the reference when we fail to dispatch it, so that | 89 | 31 | // we won't release the event in a wrong thread. | 90 | 31 | LeakRefPtr<nsIRunnable> event(std::move(aEvent)); | 91 | 31 | nsCOMPtr<nsIThreadObserver> obs; | 92 | 31 | | 93 | 31 | { | 94 | 31 | // Check if the runnable wants to override the passed-in priority. | 95 | 31 | // Do this outside the lock, so runnables implemented in JS can QI | 96 | 31 | // (and possibly GC) outside of the lock. | 97 | 31 | if (InnerQueueT::SupportsPrioritization) { | 98 | 0 | auto* e = event.get(); // can't do_QueryInterface on LeakRefPtr. | 99 | 0 | if (nsCOMPtr<nsIRunnablePriority> runnablePrio = do_QueryInterface(e)) { | 100 | 0 | uint32_t prio = nsIRunnablePriority::PRIORITY_NORMAL; | 101 | 0 | runnablePrio->GetPriority(&prio); | 102 | 0 | if (prio == nsIRunnablePriority::PRIORITY_HIGH) { | 103 | 0 | aPriority = EventPriority::High; | 104 | 0 | } else if (prio == nsIRunnablePriority::PRIORITY_INPUT) { | 105 | 0 | aPriority = EventPriority::Input; | 106 | 0 | } | 107 | 0 | } | 108 | 0 | } | 109 | 31 | | 110 | 31 | MutexAutoLock lock(mLock); | 111 | 31 | | 112 | 31 | if (mEventsAreDoomed) { | 113 | 0 | return false; | 114 | 0 | } | 115 | 31 | | 116 | 31 | if (aSink) { | 117 | 0 | if (!aSink->mQueue) { | 118 | 0 | return false; | 119 | 0 | } | 120 | 0 | | 121 | 0 | aSink->mQueue->PutEvent(event.take(), aPriority, lock); | 122 | 31 | } else { | 123 | 31 | mBaseQueue->PutEvent(event.take(), aPriority, lock); | 124 | 31 | } | 125 | 31 | | 126 | 31 | mEventsAvailable.Notify(); | 127 | 31 | | 128 | 31 | // Make sure to grab the observer before dropping the lock, otherwise the | 129 | 31 | // event that we just placed into the queue could run and eventually delete | 130 | 31 | // this nsThread before the calling thread is scheduled again. We would then | 131 | 31 | // crash while trying to access a dead nsThread. | 132 | 31 | obs = mObserver; | 133 | 31 | } | 134 | 31 | | 135 | 31 | if (obs) { | 136 | 5 | obs->OnDispatchedEvent(); | 137 | 5 | } | 138 | 31 | | 139 | 31 | return true; | 140 | 31 | } |
mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::PutEventInternal(already_AddRefed<nsIRunnable>&&, mozilla::EventPriority, mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::NestedSink*) Line | Count | Source | 87 | 163 | { | 88 | 163 | // We want to leak the reference when we fail to dispatch it, so that | 89 | 163 | // we won't release the event in a wrong thread. | 90 | 163 | LeakRefPtr<nsIRunnable> event(std::move(aEvent)); | 91 | 163 | nsCOMPtr<nsIThreadObserver> obs; | 92 | 163 | | 93 | 163 | { | 94 | 163 | // Check if the runnable wants to override the passed-in priority. | 95 | 163 | // Do this outside the lock, so runnables implemented in JS can QI | 96 | 163 | // (and possibly GC) outside of the lock. | 97 | 163 | if (InnerQueueT::SupportsPrioritization) { | 98 | 163 | auto* e = event.get(); // can't do_QueryInterface on LeakRefPtr. | 99 | 163 | if (nsCOMPtr<nsIRunnablePriority> runnablePrio = do_QueryInterface(e)) { | 100 | 0 | uint32_t prio = nsIRunnablePriority::PRIORITY_NORMAL; | 101 | 0 | runnablePrio->GetPriority(&prio); | 102 | 0 | if (prio == nsIRunnablePriority::PRIORITY_HIGH) { | 103 | 0 | aPriority = EventPriority::High; | 104 | 0 | } else if (prio == nsIRunnablePriority::PRIORITY_INPUT) { | 105 | 0 | aPriority = EventPriority::Input; | 106 | 0 | } | 107 | 0 | } | 108 | 163 | } | 109 | 163 | | 110 | 163 | MutexAutoLock lock(mLock); | 111 | 163 | | 112 | 163 | if (mEventsAreDoomed) { | 113 | 0 | return false; | 114 | 0 | } | 115 | 163 | | 116 | 163 | if (aSink) { | 117 | 0 | if (!aSink->mQueue) { | 118 | 0 | return false; | 119 | 0 | } | 120 | 0 | | 121 | 0 | aSink->mQueue->PutEvent(event.take(), aPriority, lock); | 122 | 163 | } else { | 123 | 163 | mBaseQueue->PutEvent(event.take(), aPriority, lock); | 124 | 163 | } | 125 | 163 | | 126 | 163 | mEventsAvailable.Notify(); | 127 | 163 | | 128 | 163 | // Make sure to grab the observer before dropping the lock, otherwise the | 129 | 163 | // event that we just placed into the queue could run and eventually delete | 130 | 163 | // this nsThread before the calling thread is scheduled again. We would then | 131 | 163 | // crash while trying to access a dead nsThread. | 132 | 163 | obs = mObserver; | 133 | 163 | } | 134 | 163 | | 135 | 163 | if (obs) { | 136 | 0 | obs->OnDispatchedEvent(); | 137 | 0 | } | 138 | 163 | | 139 | 163 | return true; | 140 | 163 | } |
Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::PutEventInternal(already_AddRefed<nsIRunnable>&&, mozilla::EventPriority, mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::NestedSink*) |
141 | | |
142 | | template<class InnerQueueT> |
143 | | already_AddRefed<nsIRunnable> |
144 | | ThreadEventQueue<InnerQueueT>::GetEvent(bool aMayWait, |
145 | | EventPriority* aPriority) |
146 | 53 | { |
147 | 53 | MutexAutoLock lock(mLock); |
148 | 53 | |
149 | 53 | nsCOMPtr<nsIRunnable> event; |
150 | 63 | for (;;) { |
151 | 63 | if (mNestedQueues.IsEmpty()) { |
152 | 63 | event = mBaseQueue->GetEvent(aPriority, lock); |
153 | 63 | } else { |
154 | 0 | // We always get events from the topmost queue when there are nested |
155 | 0 | // queues. |
156 | 0 | event = mNestedQueues.LastElement().mQueue->GetEvent(aPriority, lock); |
157 | 0 | } |
158 | 63 | |
159 | 63 | if (event || !aMayWait) { |
160 | 47 | break; |
161 | 47 | } |
162 | 16 | |
163 | 16 | AUTO_PROFILER_LABEL("ThreadEventQueue::GetEvent::Wait", IDLE); |
164 | 16 | mEventsAvailable.Wait(); |
165 | 16 | } |
166 | 53 | |
167 | 53 | return event.forget(); |
168 | 53 | } mozilla::ThreadEventQueue<mozilla::EventQueue>::GetEvent(bool, mozilla::EventPriority*) Line | Count | Source | 146 | 53 | { | 147 | 53 | MutexAutoLock lock(mLock); | 148 | 53 | | 149 | 53 | nsCOMPtr<nsIRunnable> event; | 150 | 63 | for (;;) { | 151 | 63 | if (mNestedQueues.IsEmpty()) { | 152 | 63 | event = mBaseQueue->GetEvent(aPriority, lock); | 153 | 63 | } else { | 154 | 0 | // We always get events from the topmost queue when there are nested | 155 | 0 | // queues. | 156 | 0 | event = mNestedQueues.LastElement().mQueue->GetEvent(aPriority, lock); | 157 | 0 | } | 158 | 63 | | 159 | 63 | if (event || !aMayWait) { | 160 | 47 | break; | 161 | 47 | } | 162 | 16 | | 163 | 16 | AUTO_PROFILER_LABEL("ThreadEventQueue::GetEvent::Wait", IDLE); | 164 | 16 | mEventsAvailable.Wait(); | 165 | 16 | } | 166 | 53 | | 167 | 53 | return event.forget(); | 168 | 53 | } |
Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::GetEvent(bool, mozilla::EventPriority*) Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::GetEvent(bool, mozilla::EventPriority*) |
169 | | |
170 | | template<class InnerQueueT> |
171 | | bool |
172 | | ThreadEventQueue<InnerQueueT>::HasPendingEvent() |
173 | 19 | { |
174 | 19 | MutexAutoLock lock(mLock); |
175 | 19 | |
176 | 19 | // We always get events from the topmost queue when there are nested queues. |
177 | 19 | if (mNestedQueues.IsEmpty()) { |
178 | 19 | return mBaseQueue->HasReadyEvent(lock); |
179 | 19 | } else { |
180 | 0 | return mNestedQueues.LastElement().mQueue->HasReadyEvent(lock); |
181 | 0 | } |
182 | 19 | } mozilla::ThreadEventQueue<mozilla::EventQueue>::HasPendingEvent() Line | Count | Source | 173 | 19 | { | 174 | 19 | MutexAutoLock lock(mLock); | 175 | 19 | | 176 | 19 | // We always get events from the topmost queue when there are nested queues. | 177 | 19 | if (mNestedQueues.IsEmpty()) { | 178 | 19 | return mBaseQueue->HasReadyEvent(lock); | 179 | 19 | } else { | 180 | 0 | return mNestedQueues.LastElement().mQueue->HasReadyEvent(lock); | 181 | 0 | } | 182 | 19 | } |
Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::HasPendingEvent() Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::HasPendingEvent() |
183 | | |
184 | | template<class InnerQueueT> |
185 | | bool |
186 | | ThreadEventQueue<InnerQueueT>::ShutdownIfNoPendingEvents() |
187 | 0 | { |
188 | 0 | MutexAutoLock lock(mLock); |
189 | 0 | if (mNestedQueues.IsEmpty() && mBaseQueue->IsEmpty(lock)) { |
190 | 0 | mEventsAreDoomed = true; |
191 | 0 | return true; |
192 | 0 | } |
193 | 0 | return false; |
194 | 0 | } Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::EventQueue>::ShutdownIfNoPendingEvents() Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::ShutdownIfNoPendingEvents() Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::ShutdownIfNoPendingEvents() |
195 | | |
196 | | template<class InnerQueueT> |
197 | | void |
198 | | ThreadEventQueue<InnerQueueT>::EnableInputEventPrioritization() |
199 | 0 | { |
200 | 0 | MutexAutoLock lock(mLock); |
201 | 0 | mBaseQueue->EnableInputEventPrioritization(lock); |
202 | 0 | } Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::EventQueue>::EnableInputEventPrioritization() Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::EnableInputEventPrioritization() Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::EnableInputEventPrioritization() |
203 | | |
204 | | template<class InnerQueueT> |
205 | | void |
206 | | ThreadEventQueue<InnerQueueT>::FlushInputEventPrioritization() |
207 | 0 | { |
208 | 0 | MutexAutoLock lock(mLock); |
209 | 0 | mBaseQueue->FlushInputEventPrioritization(lock); |
210 | 0 | } Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::EventQueue>::FlushInputEventPrioritization() Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::FlushInputEventPrioritization() Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::FlushInputEventPrioritization() |
211 | | |
212 | | template<class InnerQueueT> |
213 | | void |
214 | | ThreadEventQueue<InnerQueueT>::SuspendInputEventPrioritization() |
215 | 0 | { |
216 | 0 | MutexAutoLock lock(mLock); |
217 | 0 | mBaseQueue->SuspendInputEventPrioritization(lock); |
218 | 0 | } Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::EventQueue>::SuspendInputEventPrioritization() Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::SuspendInputEventPrioritization() Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::SuspendInputEventPrioritization() |
219 | | |
220 | | template<class InnerQueueT> |
221 | | void |
222 | | ThreadEventQueue<InnerQueueT>::ResumeInputEventPrioritization() |
223 | 0 | { |
224 | 0 | MutexAutoLock lock(mLock); |
225 | 0 | mBaseQueue->ResumeInputEventPrioritization(lock); |
226 | 0 | } Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::EventQueue>::ResumeInputEventPrioritization() Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::ResumeInputEventPrioritization() Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::ResumeInputEventPrioritization() |
227 | | |
228 | | template<class InnerQueueT> |
229 | | already_AddRefed<nsISerialEventTarget> |
230 | | ThreadEventQueue<InnerQueueT>::PushEventQueue() |
231 | 0 | { |
232 | 0 | auto queue = MakeUnique<EventQueue>(); |
233 | 0 | RefPtr<NestedSink> sink = new NestedSink(queue.get(), this); |
234 | 0 | RefPtr<ThreadEventTarget> eventTarget = new ThreadEventTarget(sink, NS_IsMainThread()); |
235 | 0 |
|
236 | 0 | MutexAutoLock lock(mLock); |
237 | 0 |
|
238 | 0 | mNestedQueues.AppendElement(NestedQueueItem(std::move(queue), eventTarget)); |
239 | 0 | return eventTarget.forget(); |
240 | 0 | } Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::EventQueue>::PushEventQueue() Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::PushEventQueue() Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::PushEventQueue() |
241 | | |
242 | | template<class InnerQueueT> |
243 | | void |
244 | | ThreadEventQueue<InnerQueueT>::PopEventQueue(nsIEventTarget* aTarget) |
245 | 0 | { |
246 | 0 | MutexAutoLock lock(mLock); |
247 | 0 |
|
248 | 0 | MOZ_ASSERT(!mNestedQueues.IsEmpty()); |
249 | 0 |
|
250 | 0 | NestedQueueItem& item = mNestedQueues.LastElement(); |
251 | 0 |
|
252 | 0 | MOZ_ASSERT(aTarget == item.mEventTarget); |
253 | 0 |
|
254 | 0 | // Disconnect the event target that will be popped. |
255 | 0 | item.mEventTarget->Disconnect(lock); |
256 | 0 |
|
257 | 0 | AbstractEventQueue* prevQueue = |
258 | 0 | mNestedQueues.Length() == 1 |
259 | 0 | ? static_cast<AbstractEventQueue*>(mBaseQueue.get()) |
260 | 0 | : static_cast<AbstractEventQueue*>(mNestedQueues[mNestedQueues.Length() - 2].mQueue.get()); |
261 | 0 |
|
262 | 0 | // Move events from the old queue to the new one. |
263 | 0 | nsCOMPtr<nsIRunnable> event; |
264 | 0 | EventPriority prio; |
265 | 0 | while ((event = item.mQueue->GetEvent(&prio, lock))) { |
266 | 0 | prevQueue->PutEvent(event.forget(), prio, lock); |
267 | 0 | } |
268 | 0 |
|
269 | 0 | mNestedQueues.RemoveLastElement(); |
270 | 0 | } Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::EventQueue>::PopEventQueue(nsIEventTarget*) Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::PopEventQueue(nsIEventTarget*) Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::PopEventQueue(nsIEventTarget*) |
271 | | |
272 | | template<class InnerQueueT> |
273 | | size_t |
274 | | ThreadEventQueue<InnerQueueT>::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
275 | 0 | { |
276 | 0 | size_t n = 0; |
277 | 0 |
|
278 | 0 | n += mBaseQueue->SizeOfIncludingThis(aMallocSizeOf); |
279 | 0 |
|
280 | 0 | n += mNestedQueues.ShallowSizeOfExcludingThis(aMallocSizeOf); |
281 | 0 | for (auto& queue : mNestedQueues) { |
282 | 0 | n += queue.mEventTarget->SizeOfIncludingThis(aMallocSizeOf); |
283 | 0 | } |
284 | 0 |
|
285 | 0 | return SynchronizedEventQueue::SizeOfExcludingThis(aMallocSizeOf) + n; |
286 | 0 | } Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::EventQueue>::SizeOfExcludingThis(unsigned long (*)(void const*)) const Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::SizeOfExcludingThis(unsigned long (*)(void const*)) const Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::SizeOfExcludingThis(unsigned long (*)(void const*)) const |
287 | | |
288 | | template<class InnerQueueT> |
289 | | already_AddRefed<nsIThreadObserver> |
290 | | ThreadEventQueue<InnerQueueT>::GetObserver() |
291 | 0 | { |
292 | 0 | MutexAutoLock lock(mLock); |
293 | 0 | return do_AddRef(mObserver); |
294 | 0 | } Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::EventQueue>::GetObserver() Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::GetObserver() Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::GetObserver() |
295 | | |
296 | | template<class InnerQueueT> |
297 | | already_AddRefed<nsIThreadObserver> |
298 | | ThreadEventQueue<InnerQueueT>::GetObserverOnThread() |
299 | 40 | { |
300 | 40 | return do_AddRef(mObserver); |
301 | 40 | } mozilla::ThreadEventQueue<mozilla::EventQueue>::GetObserverOnThread() Line | Count | Source | 299 | 40 | { | 300 | 40 | return do_AddRef(mObserver); | 301 | 40 | } |
Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::GetObserverOnThread() Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::GetObserverOnThread() |
302 | | |
303 | | template<class InnerQueueT> |
304 | | void |
305 | | ThreadEventQueue<InnerQueueT>::SetObserver(nsIThreadObserver* aObserver) |
306 | 3 | { |
307 | 3 | MutexAutoLock lock(mLock); |
308 | 3 | mObserver = aObserver; |
309 | 3 | } mozilla::ThreadEventQueue<mozilla::EventQueue>::SetObserver(nsIThreadObserver*) Line | Count | Source | 306 | 3 | { | 307 | 3 | MutexAutoLock lock(mLock); | 308 | 3 | mObserver = aObserver; | 309 | 3 | } |
Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::EventQueue> >::SetObserver(nsIThreadObserver*) Unexecuted instantiation: mozilla::ThreadEventQueue<mozilla::PrioritizedEventQueue<mozilla::LabeledEventQueue> >::SetObserver(nsIThreadObserver*) |
310 | | |
311 | | namespace mozilla { |
312 | | template class ThreadEventQueue<EventQueue>; |
313 | | template class ThreadEventQueue<PrioritizedEventQueue<EventQueue>>; |
314 | | template class ThreadEventQueue<PrioritizedEventQueue<LabeledEventQueue>>; |
315 | | } |