MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / ~ExplicitProducer

Method ~ExplicitProducer

deps/concurrentqueue/concurrentqueue.h:1768–1831  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1766 }
1767
1768 ~ExplicitProducer()
1769 {
1770 // Destruct any elements not yet dequeued.
1771 // Since we're in the destructor, we can assume all elements
1772 // are either completely dequeued or completely not (no halfways).
1773 if (this->tailBlock != nullptr) { // Note this means there must be a block index too
1774 // First find the block that's partially dequeued, if any
1775 Block* halfDequeuedBlock = nullptr;
1776 if ((this->headIndex.load(std::memory_order_relaxed) & static_cast<index_t>(BLOCK_SIZE - 1)) != 0) {
1777 // The head's not on a block boundary, meaning a block somewhere is partially dequeued
1778 // (or the head block is the tail block and was fully dequeued, but the head/tail are still not on a boundary)
1779 size_t i = (pr_blockIndexFront - pr_blockIndexSlotsUsed) & (pr_blockIndexSize - 1);
1780 while (details::circular_less_than<index_t>(pr_blockIndexEntries[i].base + BLOCK_SIZE, this->headIndex.load(std::memory_order_relaxed))) {
1781 i = (i + 1) & (pr_blockIndexSize - 1);
1782 }
1783 assert(details::circular_less_than<index_t>(pr_blockIndexEntries[i].base, this->headIndex.load(std::memory_order_relaxed)));
1784 halfDequeuedBlock = pr_blockIndexEntries[i].block;
1785 }
1786
1787 // Start at the head block (note the first line in the loop gives us the head from the tail on the first iteration)
1788 auto block = this->tailBlock;
1789 do {
1790 block = block->next;
1791 if (block->ConcurrentQueue::Block::template is_empty<explicit_context>()) {
1792 continue;
1793 }
1794
1795 size_t i = 0; // Offset into block
1796 if (block == halfDequeuedBlock) {
1797 i = static_cast<size_t>(this->headIndex.load(std::memory_order_relaxed) & static_cast<index_t>(BLOCK_SIZE - 1));
1798 }
1799
1800 // Walk through all the items in the block; if this is the tail block, we need to stop when we reach the tail index
1801 auto lastValidIndex = (this->tailIndex.load(std::memory_order_relaxed) & static_cast<index_t>(BLOCK_SIZE - 1)) == 0 ? BLOCK_SIZE : static_cast<size_t>(this->tailIndex.load(std::memory_order_relaxed) & static_cast<index_t>(BLOCK_SIZE - 1));
1802 while (i != BLOCK_SIZE && (block != this->tailBlock || i != lastValidIndex)) {
1803 (*block)[i++]->~T();
1804 }
1805 } while (block != this->tailBlock);
1806 }
1807
1808 // Destroy all blocks that we own
1809 if (this->tailBlock != nullptr) {
1810 auto block = this->tailBlock;
1811 do {
1812 auto nextBlock = block->next;
1813 if (block->dynamicallyAllocated) {
1814 destroy(block);
1815 }
1816 else {
1817 this->parent->add_block_to_free_list(block);
1818 }
1819 block = nextBlock;
1820 } while (block != this->tailBlock);
1821 }
1822
1823 // Destroy the block indices
1824 auto header = static_cast<BlockIndexHeader*>(pr_blockIndexRaw);
1825 while (header != nullptr) {

Callers

nothing calls this directly

Calls 1

destroyFunction · 0.85

Tested by

no test coverage detected