If canSleep returns true, then the queue is empty and the next push() will return true
| 142 | |
| 143 | // If canSleep returns true, then the queue is empty and the next push() will return true |
| 144 | bool canSleep() { |
| 145 | if (sleepy) { |
| 146 | return false; // We already have sleeping in the queue from a previous call to canSleep. Pop it and then |
| 147 | // maybe you can sleep! |
| 148 | } |
| 149 | if (this->tail != &stub || this->tail->next.load()) { |
| 150 | #if VALGRIND |
| 151 | ANNOTATE_HAPPENS_BEFORE(&this->tail->next); |
| 152 | #endif |
| 153 | return false; // There is definitely something in the queue. This is a rejection test not needed for |
| 154 | // correctness, but avoids calls to pushNode |
| 155 | } |
| 156 | #if VALGRIND |
| 157 | ANNOTATE_HAPPENS_BEFORE(&this->tail->next); |
| 158 | #endif |
| 159 | // sleeping is definitely not in the queue, so we can safely try... |
| 160 | sleeping.next.store(nullptr); |
| 161 | bool ok = pushNode(&sleeping) == &stub; |
| 162 | sleepy = true; // sleeping is in the queue, regardless of whether it's the first thing; we need to pop it before |
| 163 | // sleeping again |
| 164 | return ok; |
| 165 | } |
| 166 | |
| 167 | Optional<T> pop() { |
| 168 | BaseNode* b = popNode(); |
no test coverage detected