@@ -69,7 +69,10 @@ class TaskDispatcher
69
69
class AutoTaskDispatcher : public TaskDispatcher
70
70
{
71
71
public:
72
- explicit AutoTaskDispatcher (bool aIsTailDispatcher = false ) : mIsTailDispatcher(aIsTailDispatcher) {}
72
+ explicit AutoTaskDispatcher (bool aIsTailDispatcher = false )
73
+ : mIsTailDispatcher(aIsTailDispatcher)
74
+ {}
75
+
73
76
~AutoTaskDispatcher ()
74
77
{
75
78
// Given that direct tasks may trigger other code that uses the tail
@@ -81,25 +84,33 @@ class AutoTaskDispatcher : public TaskDispatcher
81
84
// potentially not true for other hypothetical AutoTaskDispatchers). Feel
82
85
// free to loosen this restriction to apply only to mIsTailDispatcher if a
83
86
// use-case requires it.
84
- MOZ_ASSERT (mDirectTasks . empty ());
87
+ MOZ_ASSERT (! HaveDirectTasks ());
85
88
86
89
for (size_t i = 0 ; i < mTaskGroups .Length (); ++i) {
87
90
DispatchTaskGroup (Move (mTaskGroups [i]));
88
91
}
89
92
}
90
93
94
+ bool HaveDirectTasks () const
95
+ {
96
+ return mDirectTasks .isSome () && !mDirectTasks ->empty ();
97
+ }
98
+
91
99
void DrainDirectTasks () override
92
100
{
93
- while (! mDirectTasks . empty ()) {
94
- nsCOMPtr<nsIRunnable> r = mDirectTasks . front ();
95
- mDirectTasks . pop ();
101
+ while (HaveDirectTasks ()) {
102
+ nsCOMPtr<nsIRunnable> r = mDirectTasks -> front ();
103
+ mDirectTasks -> pop ();
96
104
r->Run ();
97
105
}
98
106
}
99
107
100
108
void AddDirectTask (already_AddRefed<nsIRunnable> aRunnable) override
101
109
{
102
- mDirectTasks .push (Move (aRunnable));
110
+ if (mDirectTasks .isNothing ()) {
111
+ mDirectTasks .emplace ();
112
+ }
113
+ mDirectTasks ->push (Move (aRunnable));
103
114
}
104
115
105
116
void AddStateChangeTask (AbstractThread* aThread,
@@ -124,7 +135,8 @@ class AutoTaskDispatcher : public TaskDispatcher
124
135
125
136
bool HasTasksFor (AbstractThread* aThread) override
126
137
{
127
- return !!GetTaskGroup (aThread) || (aThread == AbstractThread::GetCurrent () && !mDirectTasks .empty ());
138
+ return !!GetTaskGroup (aThread) ||
139
+ (aThread == AbstractThread::GetCurrent () && HaveDirectTasks ());
128
140
}
129
141
130
142
void DispatchTasksFor (AbstractThread* aThread) override
@@ -232,8 +244,11 @@ class AutoTaskDispatcher : public TaskDispatcher
232
244
thread->Dispatch (r.forget (), failureHandling, reason);
233
245
}
234
246
235
- // Direct tasks.
236
- std::queue<nsCOMPtr<nsIRunnable>> mDirectTasks ;
247
+ // Direct tasks. We use a Maybe<> because (a) this class is hot, (b)
248
+ // mDirectTasks often doesn't get anything put into it, and (c) the
249
+ // std::queue implementation in GNU libstdc++ does two largish heap
250
+ // allocations when creating a new std::queue.
251
+ mozilla::Maybe<std::queue<nsCOMPtr<nsIRunnable>>> mDirectTasks ;
237
252
238
253
// Task groups, organized by thread.
239
254
nsTArray<UniquePtr<PerThreadTaskGroup>> mTaskGroups ;
0 commit comments