#ifndef THREAD_SAFE_QUEUE_H #define THREAD_SAFE_QUEUE_H #include #include #include namespace xop { template class ThreadSafeQueue { public: ThreadSafeQueue() { } ThreadSafeQueue(ThreadSafeQueue const& other) { std::lock_guard lock(other._mutex); _dataQueue = other._dataQueue; } ~ThreadSafeQueue() { } void push(T value) { std::lock_guard lock(_mutex); _dataQueue.push(value); _dataCond.notify_one(); } bool waitAndPop(T& value) { std::unique_lock lock(_mutex); _dataCond.wait(lock); if (_dataQueue.empty()) { return false; } value = _dataQueue.front(); _dataQueue.pop(); return true; } std::shared_ptr waitAndPop() { std::unique_lock lock(_mutex); _dataCond.wait(lock); if (_dataQueue.empty()) { return nullptr; } std::shared_ptr res(std::make_shared(_dataQueue.front())); _dataQueue.pop(); return res; } bool tryPop(T& value) { std::lock_guard lock(_mutex); if(_dataQueue.empty()) return false; value = _dataQueue.front(); _dataQueue.pop(); return true; } std::shared_ptr tryPop() { std::lock_guard lock(_mutex); if(_dataQueue.empty()) return std::shared_ptr(); std::shared_ptr res(std::make_shared(_dataQueue.front())); _dataQueue.pop(); return res; } size_t size() const { std::lock_guard lock(_mutex); return _dataQueue.size(); } bool empty() const { std::lock_guard lock(_mutex); return _dataQueue.empty(); } void clear() { std::lock_guard lock(_mutex); std::queue empty; _dataQueue.swap(empty); } void wake() { _dataCond.notify_one(); } private: mutable std::mutex _mutex; std::queue _dataQueue; std::condition_variable _dataCond; }; } #endif