-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBlockingQueue.h
More file actions
98 lines (82 loc) · 2.1 KB
/
Copy pathBlockingQueue.h
File metadata and controls
98 lines (82 loc) · 2.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#pragma once
/// <summary>
/// Simple blocking queue, first in first out
/// </summary>
/// <typeparam name="Element_t">type of items in queue</typeparam>
/// <remarks>when list is empty it waits during poping</remarks>
template <typename Element_t>
class BlockingQueue
{
public:
/// <summary>
/// insert new element to list
/// </summary>
/// <param name="newElement"></param>
/// <remarks>perfect forwarding is used</remarks>
void push(Element_t&& newElement);
/// <summary>
/// gets and removes first element,
/// it will not block if list is empty
/// </summary>
/// <returns>
/// false if list is empty and no elements is return
/// true if element is return, secand field contains element
/// </returns>
tuple<bool, Element_t> tryPop();
/// <summary>
/// gets and removes first element,
/// if list is empty it waits until new elements is added
/// </summary>
/// <returns>first element of the queue</returns>
Element_t pop();
/// <summary>
/// Size of queue
/// </summary>
/// <returns></returns>
size_t size();
private:
/// <summary>
/// for synchronizing push and pop
/// </summary>
mutex mtx;
/// <summary>
/// for synchronizing push and pop
/// </summary>
condition_variable condition;
/// <summary>
/// implementation of queue
/// </summary>
queue<Element_t> myQueue;
};
template<typename Element_t>
inline void BlockingQueue<Element_t>::push(Element_t&& newElement)
{
lock_guard lock(mtx);
myQueue.push(forward<Element_t>(newElement));
condition.notify_one();
}
template<typename Element_t>
inline tuple<bool, Element_t> BlockingQueue<Element_t>::tryPop()
{
lock_guard lock(mtx);
if (myQueue.empty()) {
return tuple(false, Element_t());
}
auto ret = tuple(true, Element_t(move(myQueue.front())));
myQueue.pop();
return ret;
}
template<typename Element_t>
inline Element_t BlockingQueue<Element_t>::pop()
{
unique_lock lock(mtx);
condition.wait(lock, [this]() {return !myQueue.empty(); });
Element_t element(move(myQueue.front()));
myQueue.pop();
return element;
}
template<typename Element_t>
inline size_t BlockingQueue<Element_t>::size()
{
return myQueue.size();
}