Changeset 16094
- Timestamp:
- 05/23/13 19:12:13 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/queue.h
r15625 r16094 6 6 7 7 template<class T> 8 class Queue : std:: deque<T>8 class Queue : std::list<T> 9 9 { 10 10 std::mutex fMutex; // Mutex needed for the conditional … … 13 13 enum state_t 14 14 { 15 kIdle, 15 16 kRun, 16 k Wait,17 k Stop17 kStop, 18 kAbort, 18 19 }; 20 21 size_t fSize; // Only necessary for before C++11 19 22 20 23 state_t fState; // Stop signal for the thread … … 28 31 { 29 32 std::unique_lock<std::mutex> lock(fMutex); 33 30 34 while (1) 31 35 { 32 while (std:: deque<T>::empty() && fState==kRun)36 while (std::list<T>::empty() && fState==kRun) 33 37 fCond.wait(lock); 34 38 35 if (fState==k Stop)39 if (fState==kAbort) 36 40 break; 37 41 38 if (fState==k Wait && std::deque<T>::empty())42 if (fState==kStop && std::list<T>::empty()) 39 43 break; 40 44 41 const T val = std::deque<T>::front(); 42 std::deque<T>::pop_front(); 45 const T &val = std::list<T>::front(); 43 46 44 47 // Theoretically, we can loose a signal here, but this is … … 50 53 51 54 lock.lock(); 55 56 std::list<T>::pop_front(); 57 fSize--; 52 58 } 59 60 std::list<T>::clear(); 61 fSize = 0; 62 63 fState = kIdle; 53 64 } 54 65 55 66 public: 56 Queue(const callback &f) : fS tate(kRun), fCallback(f)67 Queue(const callback &f) : fSize(0), fState(kIdle), fCallback(f) 57 68 { 58 fThread = std::thread(std::bind(&Queue::Thread, this));69 start(); 59 70 } 60 71 ~Queue() 61 72 { 62 stop(); 63 join(); 73 wait(true); 64 74 } 65 75 66 void post(const T &val)76 bool start() 67 77 { 68 78 const std::lock_guard<std::mutex> lock(fMutex); 79 if (fState!=kIdle) 80 return false; 69 81 70 std::deque<T>::push_back(val); 71 fCond.notify_one(); 82 fState = kRun; 83 fThread = std::thread(std::bind(&Queue::Thread, this)); 84 return true; 72 85 } 73 86 74 void wait()87 bool stop() 75 88 { 76 fMutex.lock(); 77 fState = kWait; 89 const std::lock_guard<std::mutex> lock(fMutex); 90 if (fState==kIdle) 91 return false; 92 93 fState = kStop; 78 94 fCond.notify_one(); 79 fMutex.unlock(); 95 96 return true; 80 97 } 81 98 82 void stop()99 bool abort() 83 100 { 84 fMutex.lock(); 85 fState = kStop; 101 const std::lock_guard<std::mutex> lock(fMutex); 102 if (fState==kIdle) 103 return false; 104 105 fState = kAbort; 86 106 fCond.notify_one(); 87 fMutex.unlock(); 107 108 return true; 88 109 } 89 110 90 void join()111 bool wait(bool abrt=false) 91 112 { 92 // This can happen is the thread is not running anymore93 try94 113 { 95 fThread.join(); 114 const std::lock_guard<std::mutex> lock(fMutex); 115 if (fState==kIdle) 116 return false; 117 118 if (fState==kRun) 119 { 120 fState = abrt ? kAbort : kStop; 121 fCond.notify_one(); 122 } 96 123 } 97 catch (const std::system_error &) 98 { 99 } 124 125 fThread.join(); 126 return true; 127 } 128 129 bool post(const T &val) 130 { 131 const std::lock_guard<std::mutex> lock(fMutex); 132 if (fState==kIdle) 133 return false; 134 135 std::list<T>::push_back(val); 136 fSize++; 137 138 fCond.notify_one(); 139 140 return true; 141 } 142 143 size_t size() const 144 { 145 return fSize; 100 146 } 101 147 };
Note:
See TracChangeset
for help on using the changeset viewer.