Dispatch Queue
Dispatch Queue / Thread Pool implementation for C++11 with built-in C++20 coroutine support
 
Loading...
Searching...
No Matches
pending_task_queue.cpp
Go to the documentation of this file.
1#include "../include/detail/pending_task_queue.hpp"
2
3namespace dispatch_queue {
4
5namespace detail {
6
7bool pending_task_queue::empty() const {
8 for (auto&& it : tagged_tasks) {
9 if (!it.second.empty()) {
10 return false;
11 }
12 }
13 return background_tasks.empty();
14}
15
16size_t pending_task_queue::size() const {
17 size_t count = 0;
18 for (auto&& it : tagged_tasks) {
19 count += it.second.size();
20 }
21 return count + background_tasks.size();
22}
23
24void pending_task_queue::clear() {
25 for (auto&& it : tagged_tasks) {
26 it.second.clear();
27 }
28 background_tasks.clear();
29}
30
31bool pending_task_queue::push(task_type type, task_function&& task, task_tag tag) {
32 switch (type) {
33 case task_type::main:
34 main_loop_tasks.push_back({ std::move(task) });
35 return false;
36
37 case task_type::tagged:
38 if (tag != NULL_TAG) {
39#ifdef __cpp_lib_unordered_map_try_emplace
40 auto pair = tagged_tasks.try_emplace(tag, std::list<pending_task>{});
41#else
42 auto pair = tagged_tasks.emplace(tag, std::list<pending_task>{});
43#endif
44 if (pair.second) {
45 // tag didn't exist, task is readily available to be processed
46 background_tasks.push_back({ std::move(task), tag });
47 return true;
48 }
49 else {
50 // tag exists and is being processed: queue task until tag gets unblocked
51 pair.first->second.push_back({ std::move(task), tag });
52 return false;
53 }
54 }
55 [[fallthrough]];
56
57 case task_type::background:
58 background_tasks.push_back({ std::move(task), NULL_TAG });
59 return true;
60
61 default:
62 return false;
63 }
64}
65
66bool pending_task_queue::try_pop(pending_task& task) {
67 task_tag previous_tag = task.tag;
68 if (previous_tag != NULL_TAG) {
69 auto it = tagged_tasks.find(previous_tag);
70 if (it->second.empty()) {
71 // when last task with tag is processed, erase the tag: this unblocks the tag
72 tagged_tasks.erase(it);
73 }
74 else {
75 // otherwise, move the first task for the tag to the end of background_tasks queue
76 background_tasks.splice(background_tasks.end(), it->second, it->second.begin());
77 }
78 }
79
80 if (!background_tasks.empty()) {
81 task = std::move(background_tasks.front());
82 background_tasks.pop_front();
83 return true;
84 }
85 else {
86 task = {};
87 return false;
88 }
89}
90
91std::list<task_function> pending_task_queue::pop_main_loop_tasks() {
92 std::list<task_function> result;
93 main_loop_tasks.swap(result);
94 return result;
95}
96
97} // end namespace detail
98
99} // end namespace dispatch_queue
Definition when_all.hpp:12
Definition dispatch_queue.hpp:19
int task_tag
Definition task_tag.hpp:12