Coverage Report

Created: 2018-09-25 14:53

/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
}