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 
 | ||
|  | 
 |