Skip to content

Commit 974a964

Browse files
author
Jean-Yves Avenard
committed
Bug 1644009 - P8. Add SimpleTaskQueue object. r=froydnj
We will use it later for implementing direct task dispatching where required. Differential Revision: https://phabricator.services.mozilla.com/D79092
1 parent 71373f3 commit 974a964

File tree

1 file changed

+37
-19
lines changed

1 file changed

+37
-19
lines changed

xpcom/threads/TaskDispatcher.h

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,39 @@
2020

2121
namespace mozilla {
2222

23+
class SimpleTaskQueue {
24+
public:
25+
SimpleTaskQueue() = default;
26+
virtual ~SimpleTaskQueue() = default;
27+
28+
void AddTask(already_AddRefed<nsIRunnable> aRunnable) {
29+
if (!mTasks) {
30+
mTasks.emplace();
31+
}
32+
mTasks->push(std::move(aRunnable));
33+
}
34+
35+
void DrainTasks() {
36+
if (!mTasks) {
37+
return;
38+
}
39+
auto& queue = mTasks.ref();
40+
while (!queue.empty()) {
41+
nsCOMPtr<nsIRunnable> r = std::move(queue.front());
42+
queue.pop();
43+
r->Run();
44+
}
45+
}
46+
47+
bool HaveTasks() const { return mTasks && !mTasks->empty(); }
48+
49+
private:
50+
// We use a Maybe<> because (a) when used for DirectTasks it often doesn't get
51+
// anything put into it, and (b) the std::queue implementation in GNU
52+
// libstdc++ does two largish heap allocations when creating a new std::queue.
53+
Maybe<std::queue<nsCOMPtr<nsIRunnable>>> mTasks;
54+
};
55+
2356
/*
2457
* A classic approach to cross-thread communication is to dispatch asynchronous
2558
* runnables to perform updates on other threads. This generally works well, but
@@ -88,23 +121,12 @@ class AutoTaskDispatcher : public TaskDispatcher {
88121
}
89122
}
90123

91-
bool HaveDirectTasks() const {
92-
return mDirectTasks.isSome() && !mDirectTasks->empty();
93-
}
124+
bool HaveDirectTasks() const { return mDirectTasks.HaveTasks(); }
94125

95-
void DrainDirectTasks() override {
96-
while (HaveDirectTasks()) {
97-
nsCOMPtr<nsIRunnable> r = mDirectTasks->front();
98-
mDirectTasks->pop();
99-
r->Run();
100-
}
101-
}
126+
void DrainDirectTasks() override { mDirectTasks.DrainTasks(); }
102127

103128
void AddDirectTask(already_AddRefed<nsIRunnable> aRunnable) override {
104-
if (mDirectTasks.isNothing()) {
105-
mDirectTasks.emplace();
106-
}
107-
mDirectTasks->push(std::move(aRunnable));
129+
mDirectTasks.AddTask(std::move(aRunnable));
108130
}
109131

110132
void AddStateChangeTask(AbstractThread* aThread,
@@ -245,11 +267,7 @@ class AutoTaskDispatcher : public TaskDispatcher {
245267
return thread->Dispatch(r.forget(), reason);
246268
}
247269

248-
// Direct tasks. We use a Maybe<> because (a) this class is hot, (b)
249-
// mDirectTasks often doesn't get anything put into it, and (c) the
250-
// std::queue implementation in GNU libstdc++ does two largish heap
251-
// allocations when creating a new std::queue.
252-
mozilla::Maybe<std::queue<nsCOMPtr<nsIRunnable>>> mDirectTasks;
270+
SimpleTaskQueue mDirectTasks;
253271

254272
// Task groups, organized by thread.
255273
nsTArray<UniquePtr<PerThreadTaskGroup>> mTaskGroups;

0 commit comments

Comments
 (0)