#ifndef PROJECT_TSQUEUE_H #define PROJECT_TSQUEUE_H #include #include #include namespace ffcpp { template class TSQueue { private: using LockType = std::lock_guard; private: mutable std::mutex _mutex; std::condition_variable _readCond; std::condition_variable _writeCond; std::queue> _queue; size_t _maxSize; public: TSQueue(size_t maxSize): _maxSize(maxSize) { } bool empty() const { LockType lock(_mutex); return _queue.empty(); } void push(T value) { auto data = std::make_shared(std::move(value)); LockType lock(_mutex); _queue.push(data); _readCond.notify_one(); } void pushOrWait(T value) { auto data = std::make_shared(std::move(value)); std::unique_lock lock(_mutex); if(_queue.size() == _maxSize) { _writeCond.wait(lock, [this]{ return _queue.size() < _maxSize; }); } _queue.push(data); _readCond.notify_one(); } std::shared_ptr waitAndPop() { std::unique_lock lock(_mutex); _readCond.wait(lock, [this]{ return !_queue.empty(); }); auto res = _queue.front(); _queue.pop(); return res; } std::shared_ptr tryPop() { LockType lock(_mutex); if(_queue.empty()) return std::shared_ptr(); auto res = _queue.front(); _queue.pop(); return res; } std::shared_ptr popOrWait() { std::unique_lock lock(_mutex); if(_queue.empty()) { _readCond.wait(lock, [this]{ return !_queue.empty(); }); } auto res = _queue.front(); _queue.pop(); return res; } }; } #endif //PROJECT_TSQUEUE_H