defaultcircularbuffer.cpp

来自「C++封装的视频采集代码」· C++ 代码 · 共 1,498 行 · 第 1/5 页

CPP
1,498
字号
            // read to having no data available for read?            if (lastAnyReadBuffersAvailable_ && !anyReadBuffersAvailable)            {                // Yes, so notify any read empty listeners                lastAnyReadBuffersAvailable_ = false;                Notifier<EmptyEventListener>::NotifyListeners();            }            // Notify all writers blocked awaiting a buffer that one may now            // be available            NotifyWriters();        }        // }}}        void DefaultCircularBuffer::DoNotify(EmptyEventListener* listener)        // {{{        {            //TRACE("$YDCB::DoNotify - EmptyEvent\n");            listener->EmptyEventOccured();        }        // }}}        void DefaultCircularBuffer::DoNotify(            ReadThresholdEventListener* listener,            const unsigned& readerNumber)        // {{{        {            //TRACE("$YDCB::DoNotify - ReadThreshold for %u\n", readerNumber);            listener->ReadThresholdEventOccured(readerNumber);        }        // }}}        void DefaultCircularBuffer::DoNotify(WriteThresholdEventListener* listener)        // {{{        {            //TRACE("$YDCB::DoNotify - WriteThreshold\n");            listener->WriteThresholdEventOccured();        }        // }}}        ObjectPool* DefaultCircularBuffer::FindPoolForType(CircularBufferResidentObject::Id id)        // {{{        {            std::pair<KNOWN_TYPES_CONTAINTER_TYPE::iterator, KNOWN_TYPES_CONTAINTER_TYPE::iterator> searchResult =                std::equal_range(                    knownObjectTypes_.begin(),                    knownObjectTypes_.end(),                    id,                    SequenceOfPairsCompare<KNOWN_TYPES_CONTAINTER_TYPE::value_type>());            return (searchResult.first == searchResult.second) ? 0 : searchResult.first->second;        }        // }}}        bool DefaultCircularBuffer::FlushAvailableForRead()        // {{{        {            syslib::Lock lock(mutex_);#ifdef INUSE_TRACKING            bool anyIsUse = false;            for (unsigned readerNumber = 0; readerNumber < numberOfReaders_; ++readerNumber)            {                if (readerInUse_[readerNumber]->size())                {                    TRACE("$RDefaultCircularBuffer::FlushAvailableForRead() Attempt to flush while %u objects in-use for reader %u$n\n",                        readerInUse_[readerNumber]->size(), readerNumber);                    anyIsUse = true;                }            }            if (anyIsUse)            {                return false;            }#endif            // Determine the space available to the writer before flushing the            // readers            bool wasBelowWriteThreshold = !GetWriteThreshold() ? true : !IsAboveWriteThreshold();            bool readPointerAdvanced = false;            for (unsigned readerNumber = 0; readerNumber < numberOfReaders_; ++readerNumber)            {                if (outstandingReadAcquisitions_[readerNumber])                {                    TRACE(                        "$RAttempt to flush when reader %u has %u outstanding %s for read$n\n",                        readerNumber,                        outstandingReadAcquisitions_[readerNumber],                        (outstandingReadAcquisitions_[readerNumber] > 1) ? "acquisitions" : "acquisition");                    ASSERT(false);                }                else if (!readPositions_[readerNumber].empty_)                {                    // Flush buffers available to the specified reader, by                    // advancing the read pointer to the write pointer's position                    readPositions_[readerNumber].position_ = writePosition_;                    readPositions_[readerNumber].empty_ = true;                    readPointerAdvanced = true;                    // No objects available for read                    numberOfObjects_[readerNumber] = 0;                    // There were objects left to be read and there was a limit set                    // so the reader may have been blocked on the limit, so unblock                    // it as there are no longer any objects left                    if (readLimitInfo_[readerNumber].first)                    {                        SetReadLimit(readerNumber, 0);                    }                }            }            if (readPointerAdvanced)            {                // Notify writers that space has been freed in the buffer and inform                // any listeners of empty or threshold crossing events                CommonReleaseFromRead(wasBelowWriteThreshold);            }            // Whole buffer must now be available for writing//TRACE("DefaultCircularBuffer::FlushAvailableForRead() Setting writeEmpty_ false\n");            writeEmpty_ = false;            return readPointerAdvanced;        }        // }}}        bool DefaultCircularBuffer::FlushAvailableForRead(unsigned readerNumber)        // {{{        {            syslib::Lock lock(mutex_);#ifdef INUSE_TRACKING            if (readerInUse_[readerNumber]->size())            {                TRACE("$RDefaultCircularBuffer::FlushAvailableForRead(unsigned) Attempt to flush while %u objects in-use for reader %u$n\n",                    readerInUse_[readerNumber]->size(), readerNumber);                return false;            }#endif//TRACE("DefaultCircularBuffer::FlushAvailableForRead(unsigned) Entered for reader %u\n", readerNumber);            // Determine whether the specified reader is the oldest and how            // many oldest readers there are            std::pair<bool, unsigned> oldestResult = IsOldestReader(readerNumber);            bool readPointerAdvanced = false;            if (outstandingReadAcquisitions_[readerNumber])            {                TRACE(                    "$RAttempt to flush when reader %u has %u outstanding %s for read$n\n",                    readerNumber,                    outstandingReadAcquisitions_[readerNumber],                    (outstandingReadAcquisitions_[readerNumber] > 1) ? "acquisitions" : "acquisition");                ASSERT(false);            }            else if (!readPositions_[readerNumber].empty_)            {                // Determine the space available to the writer before flushing                // the readers                bool wasBelowWriteThreshold = !GetWriteThreshold() ? true : !IsAboveWriteThreshold();                // Flush buffers available to the specified reader, by                // advancing the read pointer to the write pointer's position                readPositions_[readerNumber].position_ = writePosition_;                readPositions_[readerNumber].empty_ = true;                readPointerAdvanced = true;                // No objects available for read                numberOfObjects_[readerNumber] = 0;                // Notify writers that space has been freed in the buffer and                // inform any listeners of empty or threshold crossing events                CommonReleaseFromRead(wasBelowWriteThreshold);                // There were objects left to be read and there was a limit set                // so the reader may have been blocked on the limit, so unblock                // it as there are no longer any objects left                if (readLimitInfo_[readerNumber].first)                {//TRACE("DefaultCircularBuffer::FlushAvailableForRead(unsigned) Zeroing read limit for reader %u\n", readerNumber);                    SetReadLimit(readerNumber, 0);                }            }            // If the sole oldest reader was flushed            if (readPointerAdvanced && oldestResult.first && (oldestResult.second == 1))            {                // Must be space available for write//TRACE("DefaultCircularBuffer::FlushAvailableForRead(unsigned) Setting writeEmpty_ false\n");                writeEmpty_ = false;            }            return readPointerAdvanced;        }        // }}}        void DefaultCircularBuffer::ForceUnblockAll()        // {{{        {            syslib::Lock lock(mutex_);//TRACE("$RForceUnblockAll()$n\n");            // Don't allow readers/or writer to block in future            doNotBlock_ = true;            // Deal with blocking readers            SetReaderBlockState(false);            // Unblock any writers awaiting buffers            NotifyWriters();        }        // }}}        unsigned long DefaultCircularBuffer::GetDifference(            const CircularBufferPosition& earlierPosition,            const CircularBufferPosition& laterPosition)        // {{{        {//TRACE("$BearlierPosition=[%lu:%lu:%lu], laterPosition=[%lu:%lu:%lu]$n\n", earlierPosition.GetLoopCount(), earlierPosition.GetOffset(), earlierPosition.GetMargin(), laterPosition.GetLoopCount(), laterPosition.GetOffset(), laterPosition.GetMargin());            unsigned long unusedSpace = 0;            if (earlierPosition < laterPosition)            {//TRACE("$B1$n\n");                if (earlierPosition.GetOffset() < laterPosition.GetOffset())                {//TRACE("$B2$n\n");                    unusedSpace = laterPosition.GetOffset() - earlierPosition.GetOffset();                }                else                {//TRACE("$B3$n\n");                    unusedSpace = earlierPosition.GetMargin() + laterPosition.GetOffset();                }            }//TRACE("$BunusedSpace=%lu$n\n", unusedSpace);            return unusedSpace;        }        // }}}        CircularBufferSpaceInfo DefaultCircularBuffer::GetReadSpaceInfo(            const CircularBufferPosition& readPosition) const        // {{{        {            syslib::Lock lock(mutex_);            // Will assume here that if the write and read positions are the            // same then all the buffer is available for read. The test for            // whether in fact no data is available for read will have been made            // prior to calling this method            //TRACE("$Y%d %d -$n", writePosition_.GetOffset(), readPosition.GetOffset());            if (writePosition_.GetOffset() > readPosition.GetOffset())            {                return CircularBufferSpaceInfo(                    BufferSectionInfo(                        reinterpret_cast<unsigned long>(buffer_->GetBuffer()) +                            readPosition.GetOffset(),                        writePosition_.GetOffset() - readPosition.GetOffset()),                    BufferSectionInfo(0, 0));            }            else            {                return CircularBufferSpaceInfo(                    BufferSectionInfo(                        reinterpret_cast<unsigned long>(buffer_->GetBuffer()) +                            readPosition.GetOffset(),                        readPosition.GetMargin()),                    BufferSectionInfo(                        reinterpret_cast<unsigned long>(buffer_->GetBuffer()),                        writePosition_.GetOffset()));            }        }        // }}}        unsigned long DefaultCircularBuffer::GetReadThreshold(unsigned readerNumber) const        // {{{        {            syslib::Lock lock(mutex_);            return mpReadThresholds_[readerNumber].GetThreshold();        }        // }}}        unsigned long DefaultCircularBuffer::GetWriteThreshold() const        // {{{        {            syslib::Lock lock(mutex_);            return writeThreshold_.GetThreshold();        }        // }}}        unsigned long DefaultCircularBuffer::GetSpaceAvailableForWrite() const        // {{{        {            syslib::Lock lock(mutex_);            CircularBufferSpaceInfo circularBufferSpaceInfo = GetWriteSpaceInfo(writePosition_);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?