MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / enqueue

Method enqueue

deps/concurrentqueue/concurrentqueue.h:2472–2526  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2470
2471 template<AllocationMode allocMode, typename U>
2472 inline bool enqueue(U&& element)
2473 {
2474 index_t currentTailIndex = this->tailIndex.load(std::memory_order_relaxed);
2475 index_t newTailIndex = 1 + currentTailIndex;
2476 if ((currentTailIndex & static_cast<index_t>(BLOCK_SIZE - 1)) == 0) {
2477 // We reached the end of a block, start a new one
2478 auto head = this->headIndex.load(std::memory_order_relaxed);
2479 assert(!details::circular_less_than<index_t>(currentTailIndex, head));
2480 if (!details::circular_less_than<index_t>(head, currentTailIndex + BLOCK_SIZE) || (MAX_SUBQUEUE_SIZE != details::const_numeric_max<size_t>::value && (MAX_SUBQUEUE_SIZE == 0 || MAX_SUBQUEUE_SIZE - BLOCK_SIZE < currentTailIndex - head))) {
2481 return false;
2482 }
2483#ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
2484 debug::DebugLock lock(mutex);
2485#endif
2486 // Find out where we'll be inserting this block in the block index
2487 BlockIndexEntry* idxEntry;
2488 if (!insert_block_index_entry<allocMode>(idxEntry, currentTailIndex)) {
2489 return false;
2490 }
2491
2492 // Get ahold of a new block
2493 auto newBlock = this->parent->ConcurrentQueue::template requisition_block<allocMode>();
2494 if (newBlock == nullptr) {
2495 rewind_block_index_tail();
2496 idxEntry->value.store(nullptr, std::memory_order_relaxed);
2497 return false;
2498 }
2499#ifdef MCDBGQ_TRACKMEM
2500 newBlock->owner = this;
2501#endif
2502 newBlock->ConcurrentQueue::Block::template reset_empty<implicit_context>();
2503
2504 MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (static_cast<T*>(nullptr)) T(std::forward<U>(element)))) {
2505 // May throw, try to insert now before we publish the fact that we have this new block
2506 MOODYCAMEL_TRY {
2507 new ((*newBlock)[currentTailIndex]) T(std::forward<U>(element));
2508 }
2509 MOODYCAMEL_CATCH (...) {
2510 rewind_block_index_tail();
2511 idxEntry->value.store(nullptr, std::memory_order_relaxed);
2512 this->parent->add_block_to_free_list(newBlock);
2513 MOODYCAMEL_RETHROW;
2514 }
2515 }
2516
2517 // Insert the new block into the index
2518 idxEntry->value.store(newBlock, std::memory_order_relaxed);
2519
2520 this->tailBlock = newBlock;
2521
2522 MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (static_cast<T*>(nullptr)) T(std::forward<U>(element)))) {
2523 this->tailIndex.store(newTailIndex, std::memory_order_release);
2524 return true;
2525 }
2526 }
2527
2528 // Enqueue
2529 new ((*this->tailBlock)[currentTailIndex]) T(std::forward<U>(element));

Callers

nothing calls this directly

Calls 2

rewind_block_index_tailFunction · 0.85
MOODYCAMEL_CONSTEXPR_IFFunction · 0.85

Tested by

no test coverage detected