-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathblocking_queue.cpp
More file actions
129 lines (104 loc) · 1.82 KB
/
blocking_queue.cpp
File metadata and controls
129 lines (104 loc) · 1.82 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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <QtCore/qwaitcondition.h>
#include <QtCore/qmutex.h>
#include "blocking_queue.h"
class EventPrivate
{
public:
EventPrivate();
inline void incref();
inline bool decref();
bool wait(unsigned long time);
public:
QWaitCondition condition;
QMutex mutex;
QAtomicInteger<bool> flag;
QAtomicInteger<int> ref;
QAtomicInteger<quint32> waiters;
};
EventPrivate::EventPrivate()
: flag(false)
, ref(1)
, waiters(0)
{}
void EventPrivate::incref()
{
ref.ref();
}
bool EventPrivate::decref()
{
if (!ref.deref()) {
delete this;
return false;
}
return true;
}
bool EventPrivate::wait(unsigned long time)
{
bool f = flag.loadAcquire();
if (time == 0 || f) {
return f;
}
incref();
mutex.lock();
Q_ASSERT(!f);
++waiters;
while (!(f = flag.loadAcquire()) && ref.loadAcquire() > 1) {
condition.wait(&mutex);
}
--waiters;
mutex.unlock();
decref();
return f;
}
Event::Event()
:d(new EventPrivate()) {}
Event::~Event()
{
if (d->decref()) {
d->condition.wakeAll();
}
d = nullptr;
}
void Event::set()
{
if (d) {
if (d->flag.fetchAndStoreAcquire(true)) {
return;
}
d->incref();
if (d->waiters.loadAcquire() > 0) {
d->condition.wakeAll();
}
d->decref();
}
}
void Event::clear()
{
if (d) {
d->flag.storeRelease(false);
}
}
bool Event::wait(unsigned long time)
{
if (d) {
return d->wait(time);
} else {
return false;
}
}
bool Event::isSet() const
{
if (d) {
return d->flag.loadAcquire();
} else {
return false;
}
}
quint32 Event::getting() const
{
if (d) {
return d->waiters.loadAcquire();
} else {
return 0;
}
}