You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					53 lines
				
				892 B
			
		
		
			
		
	
	
					53 lines
				
				892 B
			| 
								 
											5 years ago
										 
									 | 
							
								#pragma once
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <condition_variable>
							 | 
						||
| 
								 | 
							
								#include <mutex>
							 | 
						||
| 
								 | 
							
								#include <queue>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <class T>
							 | 
						||
| 
								 | 
							
								class SafeQueue {
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								  SafeQueue() = default;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  void push(const T& v) {
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      std::unique_lock lk(m);
							 | 
						||
| 
								 | 
							
								      q.push(v);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    cv.notify_one();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  T pop() {
							 | 
						||
| 
								 | 
							
								    std::unique_lock lk(m);
							 | 
						||
| 
								 | 
							
								    cv.wait(lk, [this] { return !q.empty(); });
							 | 
						||
| 
								 | 
							
								    T v = q.front();
							 | 
						||
| 
								 | 
							
								    q.pop();
							 | 
						||
| 
								 | 
							
								    return v;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  bool try_pop(T& v, int timeout_ms = 0) {
							 | 
						||
| 
								 | 
							
								    std::unique_lock lk(m);
							 | 
						||
| 
								 | 
							
								    if (!cv.wait_for(lk, std::chrono::milliseconds(timeout_ms), [this] { return !q.empty(); })) {
							 | 
						||
| 
								 | 
							
								      return false;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    v = q.front();
							 | 
						||
| 
								 | 
							
								    q.pop();
							 | 
						||
| 
								 | 
							
								    return true;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  bool empty() const {
							 | 
						||
| 
								 | 
							
								    std::scoped_lock lk(m);
							 | 
						||
| 
								 | 
							
								    return q.empty();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  size_t size() const {
							 | 
						||
| 
								 | 
							
								    std::scoped_lock lk(m);
							 | 
						||
| 
								 | 
							
								    return q.size();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								  mutable std::mutex m;
							 | 
						||
| 
								 | 
							
								  std::condition_variable cv;
							 | 
						||
| 
								 | 
							
								  std::queue<T> q;
							 | 
						||
| 
								 | 
							
								};
							 |