FIX 4.0 Demo 1.0
Loading...
Searching...
No Matches
blockingconcurrentqueue.h
Go to the documentation of this file.
1// Provides an efficient blocking version of moodycamel::ConcurrentQueue.
2// ©2015-2020 Cameron Desrochers. Distributed under the terms of the simplified
3// BSD license, available at the top of concurrentqueue.h.
4// Also dual-licensed under the Boost Software License (see LICENSE.md)
5// Uses Jeff Preshing's semaphore implementation (under the terms of its
6// separate zlib license, see lightweightsemaphore.h).
7
8#pragma once
9
10#include "concurrentqueue.h"
12
13#include <type_traits>
14#include <cerrno>
15#include <memory>
16#include <chrono>
17#include <ctime>
18
19namespace moodycamel
20{
21// This is a blocking version of the queue. It has an almost identical interface to
22// the normal non-blocking version, with the addition of various wait_dequeue() methods
23// and the removal of producer-specific dequeue methods.
24template<typename T, typename Traits = ConcurrentQueueDefaultTraits>
26{
27private:
30
31public:
34
37 typedef typename std::make_signed<size_t>::type ssize_t;
38
46
47public:
48 // Creates a queue with at least `capacity` element slots; note that the
49 // actual number of elements that can be inserted without additional memory
50 // allocation depends on the number of producers and the block size (e.g. if
51 // the block size is equal to `capacity`, only a single block will be allocated
52 // up-front, which means only a single producer will be able to enqueue elements
53 // without an extra allocation -- blocks aren't shared between producers).
54 // This method is not thread safe -- it is up to the user to ensure that the
55 // queue is fully constructed before it starts being used by other threads (this
56 // includes making the memory effects of construction visible, possibly with a
57 // memory barrier).
58 explicit BlockingConcurrentQueue(size_t capacity = 6 * BLOCK_SIZE)
59 : inner(capacity), sema(create<LightweightSemaphore, ssize_t, int>(0, (int)Traits::MAX_SEMA_SPINS), &BlockingConcurrentQueue::template destroy<LightweightSemaphore>)
60 {
61 assert(reinterpret_cast<ConcurrentQueue*>((BlockingConcurrentQueue*)1) == &((BlockingConcurrentQueue*)1)->inner && "BlockingConcurrentQueue must have ConcurrentQueue as its first member");
62 if (!sema) {
63 MOODYCAMEL_THROW(std::bad_alloc());
64 }
65 }
66
69 {
70 assert(reinterpret_cast<ConcurrentQueue*>((BlockingConcurrentQueue*)1) == &((BlockingConcurrentQueue*)1)->inner && "BlockingConcurrentQueue must have ConcurrentQueue as its first member");
71 if (!sema) {
72 MOODYCAMEL_THROW(std::bad_alloc());
73 }
74 }
75
76 // Disable copying and copy assignment
79
80 // Moving is supported, but note that it is *not* a thread-safe operation.
81 // Nobody can use the queue while it's being moved, and the memory effects
82 // of that move must be propagated to other threads before they can use it.
83 // Note: When a queue is moved, its tokens are still valid but can only be
84 // used with the destination queue (i.e. semantically they are moved along
85 // with the queue itself).
87 : inner(std::move(other.inner)), sema(std::move(other.sema))
88 { }
89
94
95 // Swaps this queue's state with the other's. Not thread-safe.
96 // Swapping two queues does not invalidate their tokens, however
97 // the tokens that were created for one queue must be used with
98 // only the swapped queue (i.e. the tokens are tied to the
99 // queue's movable state, not the object itself).
101 {
102 swap_internal(other);
103 }
104
105private:
107 {
108 if (this == &other) {
109 return *this;
110 }
111
112 inner.swap(other.inner);
113 sema.swap(other.sema);
114 return *this;
115 }
116
117public:
118 // Enqueues a single item (by copying it).
119 // Allocates memory if required. Only fails if memory allocation fails (or implicit
120 // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0,
121 // or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
122 // Thread-safe.
123 inline bool enqueue(T const& item)
124 {
125 if ((details::likely)(inner.enqueue(item))) {
126 sema->signal();
127 return true;
128 }
129 return false;
130 }
131
132 // Enqueues a single item (by moving it, if possible).
133 // Allocates memory if required. Only fails if memory allocation fails (or implicit
134 // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0,
135 // or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
136 // Thread-safe.
137 inline bool enqueue(T&& item)
138 {
139 if ((details::likely)(inner.enqueue(std::move(item)))) {
140 sema->signal();
141 return true;
142 }
143 return false;
144 }
145
146 // Enqueues a single item (by copying it) using an explicit producer token.
147 // Allocates memory if required. Only fails if memory allocation fails (or
148 // Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
149 // Thread-safe.
150 inline bool enqueue(producer_token_t const& token, T const& item)
151 {
152 if ((details::likely)(inner.enqueue(token, item))) {
153 sema->signal();
154 return true;
155 }
156 return false;
157 }
158
159 // Enqueues a single item (by moving it, if possible) using an explicit producer token.
160 // Allocates memory if required. Only fails if memory allocation fails (or
161 // Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
162 // Thread-safe.
163 inline bool enqueue(producer_token_t const& token, T&& item)
164 {
165 if ((details::likely)(inner.enqueue(token, std::move(item)))) {
166 sema->signal();
167 return true;
168 }
169 return false;
170 }
171
172 // Enqueues several items.
173 // Allocates memory if required. Only fails if memory allocation fails (or
174 // implicit production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE
175 // is 0, or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
176 // Note: Use std::make_move_iterator if the elements should be moved instead of copied.
177 // Thread-safe.
178 template<typename It>
179 inline bool enqueue_bulk(It itemFirst, size_t count)
180 {
181 if ((details::likely)(inner.enqueue_bulk(std::forward<It>(itemFirst), count))) {
183 return true;
184 }
185 return false;
186 }
187
188 // Enqueues several items using an explicit producer token.
189 // Allocates memory if required. Only fails if memory allocation fails
190 // (or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
191 // Note: Use std::make_move_iterator if the elements should be moved
192 // instead of copied.
193 // Thread-safe.
194 template<typename It>
195 inline bool enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count)
196 {
197 if ((details::likely)(inner.enqueue_bulk(token, std::forward<It>(itemFirst), count))) {
199 return true;
200 }
201 return false;
202 }
203
204 // Enqueues a single item (by copying it).
205 // Does not allocate memory. Fails if not enough room to enqueue (or implicit
206 // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE
207 // is 0).
208 // Thread-safe.
209 inline bool try_enqueue(T const& item)
210 {
211 if (inner.try_enqueue(item)) {
212 sema->signal();
213 return true;
214 }
215 return false;
216 }
217
218 // Enqueues a single item (by moving it, if possible).
219 // Does not allocate memory (except for one-time implicit producer).
220 // Fails if not enough room to enqueue (or implicit production is
221 // disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0).
222 // Thread-safe.
223 inline bool try_enqueue(T&& item)
224 {
225 if (inner.try_enqueue(std::move(item))) {
226 sema->signal();
227 return true;
228 }
229 return false;
230 }
231
232 // Enqueues a single item (by copying it) using an explicit producer token.
233 // Does not allocate memory. Fails if not enough room to enqueue.
234 // Thread-safe.
235 inline bool try_enqueue(producer_token_t const& token, T const& item)
236 {
237 if (inner.try_enqueue(token, item)) {
238 sema->signal();
239 return true;
240 }
241 return false;
242 }
243
244 // Enqueues a single item (by moving it, if possible) using an explicit producer token.
245 // Does not allocate memory. Fails if not enough room to enqueue.
246 // Thread-safe.
247 inline bool try_enqueue(producer_token_t const& token, T&& item)
248 {
249 if (inner.try_enqueue(token, std::move(item))) {
250 sema->signal();
251 return true;
252 }
253 return false;
254 }
255
256 // Enqueues several items.
257 // Does not allocate memory (except for one-time implicit producer).
258 // Fails if not enough room to enqueue (or implicit production is
259 // disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0).
260 // Note: Use std::make_move_iterator if the elements should be moved
261 // instead of copied.
262 // Thread-safe.
263 template<typename It>
264 inline bool try_enqueue_bulk(It itemFirst, size_t count)
265 {
266 if (inner.try_enqueue_bulk(std::forward<It>(itemFirst), count)) {
268 return true;
269 }
270 return false;
271 }
272
273 // Enqueues several items using an explicit producer token.
274 // Does not allocate memory. Fails if not enough room to enqueue.
275 // Note: Use std::make_move_iterator if the elements should be moved
276 // instead of copied.
277 // Thread-safe.
278 template<typename It>
279 inline bool try_enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count)
280 {
281 if (inner.try_enqueue_bulk(token, std::forward<It>(itemFirst), count)) {
283 return true;
284 }
285 return false;
286 }
287
288
289 // Attempts to dequeue from the queue.
290 // Returns false if all producer streams appeared empty at the time they
291 // were checked (so, the queue is likely but not guaranteed to be empty).
292 // Never allocates. Thread-safe.
293 template<typename U>
294 inline bool try_dequeue(U& item)
295 {
296 if (sema->tryWait()) {
297 while (!inner.try_dequeue(item)) {
298 continue;
299 }
300 return true;
301 }
302 return false;
303 }
304
305 // Attempts to dequeue from the queue using an explicit consumer token.
306 // Returns false if all producer streams appeared empty at the time they
307 // were checked (so, the queue is likely but not guaranteed to be empty).
308 // Never allocates. Thread-safe.
309 template<typename U>
310 inline bool try_dequeue(consumer_token_t& token, U& item)
311 {
312 if (sema->tryWait()) {
313 while (!inner.try_dequeue(token, item)) {
314 continue;
315 }
316 return true;
317 }
318 return false;
319 }
320
321 // Attempts to dequeue several elements from the queue.
322 // Returns the number of items actually dequeued.
323 // Returns 0 if all producer streams appeared empty at the time they
324 // were checked (so, the queue is likely but not guaranteed to be empty).
325 // Never allocates. Thread-safe.
326 template<typename It>
327 inline size_t try_dequeue_bulk(It itemFirst, size_t max)
328 {
329 size_t count = 0;
330 max = (size_t)sema->tryWaitMany((LightweightSemaphore::ssize_t)(ssize_t)max);
331 while (count != max) {
332 count += inner.template try_dequeue_bulk<It&>(itemFirst, max - count);
333 }
334 return count;
335 }
336
337 // Attempts to dequeue several elements from the queue using an explicit consumer token.
338 // Returns the number of items actually dequeued.
339 // Returns 0 if all producer streams appeared empty at the time they
340 // were checked (so, the queue is likely but not guaranteed to be empty).
341 // Never allocates. Thread-safe.
342 template<typename It>
343 inline size_t try_dequeue_bulk(consumer_token_t& token, It itemFirst, size_t max)
344 {
345 size_t count = 0;
346 max = (size_t)sema->tryWaitMany((LightweightSemaphore::ssize_t)(ssize_t)max);
347 while (count != max) {
348 count += inner.template try_dequeue_bulk<It&>(token, itemFirst, max - count);
349 }
350 return count;
351 }
352
353
354
355 // Blocks the current thread until there's something to dequeue, then
356 // dequeues it.
357 // Never allocates. Thread-safe.
358 template<typename U>
359 inline void wait_dequeue(U& item)
360 {
361 while (!sema->wait()) {
362 continue;
363 }
364 while (!inner.try_dequeue(item)) {
365 continue;
366 }
367 }
368
369 // Blocks the current thread until either there's something to dequeue
370 // or the timeout (specified in microseconds) expires. Returns false
371 // without setting `item` if the timeout expires, otherwise assigns
372 // to `item` and returns true.
373 // Using a negative timeout indicates an indefinite timeout,
374 // and is thus functionally equivalent to calling wait_dequeue.
375 // Never allocates. Thread-safe.
376 template<typename U>
377 inline bool wait_dequeue_timed(U& item, std::int64_t timeout_usecs)
378 {
379 if (!sema->wait(timeout_usecs)) {
380 return false;
381 }
382 while (!inner.try_dequeue(item)) {
383 continue;
384 }
385 return true;
386 }
387
388 // Blocks the current thread until either there's something to dequeue
389 // or the timeout expires. Returns false without setting `item` if the
390 // timeout expires, otherwise assigns to `item` and returns true.
391 // Never allocates. Thread-safe.
392 template<typename U, typename Rep, typename Period>
393 inline bool wait_dequeue_timed(U& item, std::chrono::duration<Rep, Period> const& timeout)
394 {
395 return wait_dequeue_timed(item, std::chrono::duration_cast<std::chrono::microseconds>(timeout).count());
396 }
397
398 // Blocks the current thread until there's something to dequeue, then
399 // dequeues it using an explicit consumer token.
400 // Never allocates. Thread-safe.
401 template<typename U>
402 inline void wait_dequeue(consumer_token_t& token, U& item)
403 {
404 while (!sema->wait()) {
405 continue;
406 }
407 while (!inner.try_dequeue(token, item)) {
408 continue;
409 }
410 }
411
412 // Blocks the current thread until either there's something to dequeue
413 // or the timeout (specified in microseconds) expires. Returns false
414 // without setting `item` if the timeout expires, otherwise assigns
415 // to `item` and returns true.
416 // Using a negative timeout indicates an indefinite timeout,
417 // and is thus functionally equivalent to calling wait_dequeue.
418 // Never allocates. Thread-safe.
419 template<typename U>
420 inline bool wait_dequeue_timed(consumer_token_t& token, U& item, std::int64_t timeout_usecs)
421 {
422 if (!sema->wait(timeout_usecs)) {
423 return false;
424 }
425 while (!inner.try_dequeue(token, item)) {
426 continue;
427 }
428 return true;
429 }
430
431 // Blocks the current thread until either there's something to dequeue
432 // or the timeout expires. Returns false without setting `item` if the
433 // timeout expires, otherwise assigns to `item` and returns true.
434 // Never allocates. Thread-safe.
435 template<typename U, typename Rep, typename Period>
436 inline bool wait_dequeue_timed(consumer_token_t& token, U& item, std::chrono::duration<Rep, Period> const& timeout)
437 {
438 return wait_dequeue_timed(token, item, std::chrono::duration_cast<std::chrono::microseconds>(timeout).count());
439 }
440
441 // Attempts to dequeue several elements from the queue.
442 // Returns the number of items actually dequeued, which will
443 // always be at least one (this method blocks until the queue
444 // is non-empty) and at most max.
445 // Never allocates. Thread-safe.
446 template<typename It>
447 inline size_t wait_dequeue_bulk(It itemFirst, size_t max)
448 {
449 size_t count = 0;
451 while (count != max) {
452 count += inner.template try_dequeue_bulk<It&>(itemFirst, max - count);
453 }
454 return count;
455 }
456
457 // Attempts to dequeue several elements from the queue.
458 // Returns the number of items actually dequeued, which can
459 // be 0 if the timeout expires while waiting for elements,
460 // and at most max.
461 // Using a negative timeout indicates an indefinite timeout,
462 // and is thus functionally equivalent to calling wait_dequeue_bulk.
463 // Never allocates. Thread-safe.
464 template<typename It>
465 inline size_t wait_dequeue_bulk_timed(It itemFirst, size_t max, std::int64_t timeout_usecs)
466 {
467 size_t count = 0;
469 while (count != max) {
470 count += inner.template try_dequeue_bulk<It&>(itemFirst, max - count);
471 }
472 return count;
473 }
474
475 // Attempts to dequeue several elements from the queue.
476 // Returns the number of items actually dequeued, which can
477 // be 0 if the timeout expires while waiting for elements,
478 // and at most max.
479 // Never allocates. Thread-safe.
480 template<typename It, typename Rep, typename Period>
481 inline size_t wait_dequeue_bulk_timed(It itemFirst, size_t max, std::chrono::duration<Rep, Period> const& timeout)
482 {
483 return wait_dequeue_bulk_timed<It&>(itemFirst, max, std::chrono::duration_cast<std::chrono::microseconds>(timeout).count());
484 }
485
486 // Attempts to dequeue several elements from the queue using an explicit consumer token.
487 // Returns the number of items actually dequeued, which will
488 // always be at least one (this method blocks until the queue
489 // is non-empty) and at most max.
490 // Never allocates. Thread-safe.
491 template<typename It>
492 inline size_t wait_dequeue_bulk(consumer_token_t& token, It itemFirst, size_t max)
493 {
494 size_t count = 0;
496 while (count != max) {
497 count += inner.template try_dequeue_bulk<It&>(token, itemFirst, max - count);
498 }
499 return count;
500 }
501
502 // Attempts to dequeue several elements from the queue using an explicit consumer token.
503 // Returns the number of items actually dequeued, which can
504 // be 0 if the timeout expires while waiting for elements,
505 // and at most max.
506 // Using a negative timeout indicates an indefinite timeout,
507 // and is thus functionally equivalent to calling wait_dequeue_bulk.
508 // Never allocates. Thread-safe.
509 template<typename It>
510 inline size_t wait_dequeue_bulk_timed(consumer_token_t& token, It itemFirst, size_t max, std::int64_t timeout_usecs)
511 {
512 size_t count = 0;
514 while (count != max) {
515 count += inner.template try_dequeue_bulk<It&>(token, itemFirst, max - count);
516 }
517 return count;
518 }
519
520 // Attempts to dequeue several elements from the queue using an explicit consumer token.
521 // Returns the number of items actually dequeued, which can
522 // be 0 if the timeout expires while waiting for elements,
523 // and at most max.
524 // Never allocates. Thread-safe.
525 template<typename It, typename Rep, typename Period>
526 inline size_t wait_dequeue_bulk_timed(consumer_token_t& token, It itemFirst, size_t max, std::chrono::duration<Rep, Period> const& timeout)
527 {
528 return wait_dequeue_bulk_timed<It&>(token, itemFirst, max, std::chrono::duration_cast<std::chrono::microseconds>(timeout).count());
529 }
530
531
532 // Returns an estimate of the total number of elements currently in the queue. This
533 // estimate is only accurate if the queue has completely stabilized before it is called
534 // (i.e. all enqueue and dequeue operations have completed and their memory effects are
535 // visible on the calling thread, and no further operations start while this method is
536 // being called).
537 // Thread-safe.
538 inline size_t size_approx() const
539 {
540 return (size_t)sema->availableApprox();
541 }
542
543
544 // Returns true if the underlying atomic variables used by
545 // the queue are lock-free (they should be on most platforms).
546 // Thread-safe.
547 static constexpr bool is_lock_free()
548 {
550 }
551
552
553private:
554 template<typename U, typename A1, typename A2>
555 static inline U* create(A1&& a1, A2&& a2)
556 {
557 void* p = (Traits::malloc)(sizeof(U));
558 return p != nullptr ? new (p) U(std::forward<A1>(a1), std::forward<A2>(a2)) : nullptr;
559 }
560
561 template<typename U>
562 static inline void destroy(U* p)
563 {
564 if (p != nullptr) {
565 p->~U();
566 }
567 (Traits::free)(p);
568 }
569
570private:
571 ConcurrentQueue inner;
572 std::unique_ptr<LightweightSemaphore, void (*)(LightweightSemaphore*)> sema;
573};
574
575
576template<typename T, typename Traits>
581
582} // end namespace moodycamel
Definition blockingconcurrentqueue.h:26
size_t wait_dequeue_bulk_timed(It itemFirst, size_t max, std::chrono::duration< Rep, Period > const &timeout)
Definition blockingconcurrentqueue.h:481
bool enqueue_bulk(producer_token_t const &token, It itemFirst, size_t count)
Definition blockingconcurrentqueue.h:195
void wait_dequeue(U &item)
Definition blockingconcurrentqueue.h:359
bool wait_dequeue_timed(consumer_token_t &token, U &item, std::int64_t timeout_usecs)
Definition blockingconcurrentqueue.h:420
ConcurrentQueue::consumer_token_t consumer_token_t
Definition blockingconcurrentqueue.h:33
void swap(BlockingConcurrentQueue &other) MOODYCAMEL_NOEXCEPT
Definition blockingconcurrentqueue.h:100
static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE
Definition blockingconcurrentqueue.h:44
bool try_enqueue(T &&item)
Definition blockingconcurrentqueue.h:223
bool try_enqueue_bulk(producer_token_t const &token, It itemFirst, size_t count)
Definition blockingconcurrentqueue.h:279
size_t try_dequeue_bulk(It itemFirst, size_t max)
Definition blockingconcurrentqueue.h:327
BlockingConcurrentQueue(BlockingConcurrentQueue &&other) MOODYCAMEL_NOEXCEPT
Definition blockingconcurrentqueue.h:86
BlockingConcurrentQueue(size_t minCapacity, size_t maxExplicitProducers, size_t maxImplicitProducers)
Definition blockingconcurrentqueue.h:67
static const size_t IMPLICIT_INITIAL_INDEX_SIZE
Definition blockingconcurrentqueue.h:42
bool try_enqueue_bulk(It itemFirst, size_t count)
Definition blockingconcurrentqueue.h:264
static const size_t EXPLICIT_INITIAL_INDEX_SIZE
Definition blockingconcurrentqueue.h:41
bool wait_dequeue_timed(U &item, std::chrono::duration< Rep, Period > const &timeout)
Definition blockingconcurrentqueue.h:393
BlockingConcurrentQueue & operator=(BlockingConcurrentQueue &&other) MOODYCAMEL_NOEXCEPT
Definition blockingconcurrentqueue.h:90
static constexpr bool is_lock_free()
Definition blockingconcurrentqueue.h:547
size_t wait_dequeue_bulk_timed(It itemFirst, size_t max, std::int64_t timeout_usecs)
Definition blockingconcurrentqueue.h:465
size_t size_approx() const
Definition blockingconcurrentqueue.h:538
BlockingConcurrentQueue(size_t capacity=6 *BLOCK_SIZE)
Definition blockingconcurrentqueue.h:58
std::make_signed< size_t >::type ssize_t
Definition blockingconcurrentqueue.h:37
static const size_t BLOCK_SIZE
Definition blockingconcurrentqueue.h:39
static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE
Definition blockingconcurrentqueue.h:43
bool enqueue(producer_token_t const &token, T &&item)
Definition blockingconcurrentqueue.h:163
bool try_dequeue(U &item)
Definition blockingconcurrentqueue.h:294
static const size_t MAX_SUBQUEUE_SIZE
Definition blockingconcurrentqueue.h:45
size_t wait_dequeue_bulk(It itemFirst, size_t max)
Definition blockingconcurrentqueue.h:447
bool enqueue(T const &item)
Definition blockingconcurrentqueue.h:123
bool enqueue_bulk(It itemFirst, size_t count)
Definition blockingconcurrentqueue.h:179
bool enqueue(producer_token_t const &token, T const &item)
Definition blockingconcurrentqueue.h:150
void wait_dequeue(consumer_token_t &token, U &item)
Definition blockingconcurrentqueue.h:402
bool wait_dequeue_timed(U &item, std::int64_t timeout_usecs)
Definition blockingconcurrentqueue.h:377
size_t wait_dequeue_bulk_timed(consumer_token_t &token, It itemFirst, size_t max, std::chrono::duration< Rep, Period > const &timeout)
Definition blockingconcurrentqueue.h:526
bool wait_dequeue_timed(consumer_token_t &token, U &item, std::chrono::duration< Rep, Period > const &timeout)
Definition blockingconcurrentqueue.h:436
bool enqueue(T &&item)
Definition blockingconcurrentqueue.h:137
bool try_enqueue(producer_token_t const &token, T &&item)
Definition blockingconcurrentqueue.h:247
bool try_enqueue(T const &item)
Definition blockingconcurrentqueue.h:209
bool try_enqueue(producer_token_t const &token, T const &item)
Definition blockingconcurrentqueue.h:235
ConcurrentQueue::producer_token_t producer_token_t
Definition blockingconcurrentqueue.h:32
ConcurrentQueue::size_t size_t
Definition blockingconcurrentqueue.h:36
size_t wait_dequeue_bulk_timed(consumer_token_t &token, It itemFirst, size_t max, std::int64_t timeout_usecs)
Definition blockingconcurrentqueue.h:510
ConcurrentQueue::index_t index_t
Definition blockingconcurrentqueue.h:35
size_t wait_dequeue_bulk(consumer_token_t &token, It itemFirst, size_t max)
Definition blockingconcurrentqueue.h:492
bool try_dequeue(consumer_token_t &token, U &item)
Definition blockingconcurrentqueue.h:310
static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD
Definition blockingconcurrentqueue.h:40
BlockingConcurrentQueue(BlockingConcurrentQueue const &) MOODYCAMEL_DELETE_FUNCTION
size_t try_dequeue_bulk(consumer_token_t &token, It itemFirst, size_t max)
Definition blockingconcurrentqueue.h:343
BlockingConcurrentQueue & operator=(BlockingConcurrentQueue const &) MOODYCAMEL_DELETE_FUNCTION
Definition concurrentqueue.h:768
bool try_dequeue(U &item)
Definition concurrentqueue.h:1125
static const size_t MAX_SUBQUEUE_SIZE
Definition concurrentqueue.h:787
static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE
Definition concurrentqueue.h:780
bool enqueue_bulk(It itemFirst, size_t count)
Definition concurrentqueue.h:1037
void swap(ConcurrentQueue &other) MOODYCAMEL_NOEXCEPT
Definition concurrentqueue.h:955
static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE
Definition concurrentqueue.h:781
ConcurrentQueue(size_t capacity=32 *BLOCK_SIZE)
Definition concurrentqueue.h:813
static constexpr bool is_lock_free()
Definition concurrentqueue.h:1338
static const size_t IMPLICIT_INITIAL_INDEX_SIZE
Definition concurrentqueue.h:779
bool try_enqueue(T const &item)
Definition concurrentqueue.h:1060
static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD
Definition concurrentqueue.h:777
Traits::size_t size_t
Definition concurrentqueue.h:774
bool enqueue(T const &item)
Definition concurrentqueue.h:995
Traits::index_t index_t
Definition concurrentqueue.h:773
static const size_t EXPLICIT_INITIAL_INDEX_SIZE
Definition concurrentqueue.h:778
static const size_t BLOCK_SIZE
Definition concurrentqueue.h:776
bool try_enqueue_bulk(It itemFirst, size_t count)
Definition concurrentqueue.h:1101
Definition lightweightsemaphore.h:269
std::make_signed< std::size_t >::type ssize_t
Definition lightweightsemaphore.h:271
#define MOODYCAMEL_NOEXCEPT
Definition concurrentqueue.h:207
#define MOODYCAMEL_THROW(expr)
Definition concurrentqueue.h:183
#define MOODYCAMEL_DELETE_FUNCTION
Definition concurrentqueue.h:233
Definition blockingconcurrentqueue.h:20
void swap(BlockingConcurrentQueue< T, Traits > &a, BlockingConcurrentQueue< T, Traits > &b) MOODYCAMEL_NOEXCEPT
Definition blockingconcurrentqueue.h:577
Definition concurrentqueue.h:717
Definition concurrentqueue.h:652