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