Changes in / [7e6c0d:eea0bb]
- Location:
- src/Actions
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Actions/ActionQueue.cpp
r7e6c0d reea0bb 65 65 lastActionOk(true) 66 66 #else 67 CurrentAction(0), 67 68 lastActionOk(true), 68 CurrentAction(0), 69 run_thread_isIdle(true), 70 run_thread_running(false), 71 run_thread(boost::bind(&ActionQueue::run, this)) 69 run_thread(boost::bind(&ActionQueue::run, this)), 70 run_thread_isIdle(true) 72 71 #endif 73 72 { … … 105 104 newaction->prepare(state); 106 105 #ifdef HAVE_ACTION_THREAD 107 mtx_ actionqueue.lock();106 mtx_queue.lock(); 108 107 #endif 109 108 actionqueue.push_back( newaction ); … … 115 114 std::cerr << "Action " << *boost::get_error_info<ActionNameString>(e) << " has failed." << std::endl; 116 115 World::getInstance().setExitFlag(5); 117 //clearQueue(actionqueue.size()-1);116 clearQueue(actionqueue.size()-1); 118 117 lastActionOk = false; 119 //std::cerr << "Remaining Actions cleared from queue." << std::endl;118 std::cerr << "Remaining Actions cleared from queue." << std::endl; 120 119 } catch (std::exception &e) { 121 120 pushStatus("FAIL: General exception caught, aborting."); 122 121 World::getInstance().setExitFlag(134); 123 //clearQueue(actionqueue.size()-1);122 clearQueue(actionqueue.size()-1); 124 123 lastActionOk = false; 125 //std::cerr << "Remaining Actions cleared from queue." << std::endl;124 std::cerr << "Remaining Actions cleared from queue." << std::endl; 126 125 } 127 126 if (lastActionOk) { … … 131 130 } 132 131 #else 133 mtx_actionqueue.unlock(); 134 const bool new_run_thread_isIdle = isActionQueueDone(); 135 setrun_thread_isIdle(new_run_thread_isIdle); 136 #endif 137 } 138 139 #ifdef HAVE_ACTION_THREAD 140 bool ActionQueue::isActionQueueDone() const 141 { 142 boost::lock_guard<boost::mutex> lock(mtx_actionqueue); 143 return (CurrentAction == actionqueue.size()); 144 } 145 146 bool ActionQueue::isTempQueueDone() const 147 { 148 boost::lock_guard<boost::mutex> lock(mtx_tempqueue); 149 return tempqueue.empty(); 150 } 151 #endif 132 setRunThreadIdle(CurrentAction == actionqueue.size()); 133 mtx_queue.unlock(); 134 #endif 135 } 152 136 153 137 void ActionQueue::insertAction(Action *_action, enum Action::QueryOptions state) … … 158 142 Action *newaction = _action->clone(state); 159 143 newaction->prepare(state); 160 { 161 boost::lock_guard<boost::mutex> lock(mtx_tempqueue); 162 tempqueue.push_back( newaction ); 163 } 164 { 165 bool new_run_thread_isIdle = getrun_thread_isIdle(); 166 new_run_thread_isIdle &= isTempQueueDone(); 167 setrun_thread_isIdle(new_run_thread_isIdle); 168 } 144 mtx_queue.lock(); 145 tempqueue.push_back( newaction ); 146 setRunThreadIdle( !((CurrentAction != actionqueue.size()) || !tempqueue.empty()) ); 147 mtx_queue.unlock(); 169 148 #endif 170 149 } … … 173 152 void ActionQueue::run() 174 153 { 175 {176 boost::lock_guard<boost::mutex> lock(mtx_run_thread_isIdle);177 run_thread_running = true;178 }179 154 bool Interrupted = false; 180 155 do { … … 182 157 try { 183 158 #if BOOST_VERSION < 105000 184 boost::this_thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(100));159 run_thread.sleep(boost::get_system_time() + boost::posix_time::milliseconds(100)); 185 160 #else 186 161 boost::this_thread::sleep_for(boost::chrono::milliseconds(100)); … … 192 167 // LOG(1, "DEBUG: Start of ActionQueue's run() loop."); 193 168 // call all currently present Actions 169 mtx_queue.lock(); 194 170 insertTempQueue(); 195 while ((!Interrupted) && (!isActionQueueDone())) { 171 bool status = (CurrentAction != actionqueue.size()); 172 mtx_queue.unlock(); 173 while (status) { 196 174 // boost::this_thread::disable_interruption di; 197 // access actionqueue, hence using mutex198 mtx_actionqueue.lock();199 175 LOG(0, "Calling Action " << actionqueue[CurrentAction]->getName() << " ... "); 200 176 try { … … 216 192 std::cerr << "Remaining Actions cleared from queue." << std::endl; 217 193 } 218 // remember action we juse executed 219 const Action *lastaction = actionqueue[CurrentAction]; 220 // step on to next action and check for end 221 CurrentAction++; 194 if (lastActionOk) { 195 OBSERVE; 196 NOTIFY(ActionQueued); 197 _lastchangedaction = actionqueue[CurrentAction]; 198 mtx_queue.lock(); 199 CurrentAction++; 200 mtx_queue.unlock(); 201 } 202 // access actionqueue, hence using mutex 203 mtx_queue.lock(); 222 204 // insert new actions (before [CurrentAction]) if they have been spawned 223 205 // we must have an extra vector for this, as we cannot change actionqueue 224 206 // while an action instance is "in-use" 225 mtx_actionqueue.unlock();226 227 207 insertTempQueue(); 228 229 // set last action 230 if (lastActionOk) { 231 OBSERVE; 232 NOTIFY(ActionQueued); 233 _lastchangedaction = lastaction; 234 } 208 status = (CurrentAction != actionqueue.size()); 209 mtx_queue.unlock(); 235 210 } 236 { 237 bool new_run_thread_isIdle = isActionQueueDone(); 238 new_run_thread_isIdle &= isTempQueueDone(); 239 setrun_thread_isIdle(new_run_thread_isIdle); 240 } 211 setRunThreadIdle( !((CurrentAction != actionqueue.size()) || !tempqueue.empty()) ); 241 212 cond_idle.notify_one(); 242 213 // LOG(1, "DEBUG: End of ActionQueue's run() loop."); 243 214 } while (!Interrupted); 244 {245 boost::lock_guard<boost::mutex> lock(mtx_run_thread_isIdle);246 run_thread_running = false;247 }248 215 } 249 216 250 217 void ActionQueue::insertTempQueue() 251 218 { 252 boost::lock_guard<boost::mutex> lock(mtx_tempqueue);253 219 if (!tempqueue.empty()) { 254 boost::lock_guard<boost::mutex> lock(mtx_actionqueue);255 220 ActionQueue_t::iterator InsertionIter = actionqueue.begin(); 256 221 std::advance(InsertionIter, CurrentAction); … … 260 225 } 261 226 262 void ActionQueue::setrun_thread_isIdle(263 const bool _run_thread_isIdle)264 {265 boost::unique_lock<boost::mutex> lock(mtx_run_thread_isIdle);266 run_thread_isIdle = _run_thread_isIdle;267 }268 269 bool ActionQueue::getrun_thread_isIdle() const270 {271 boost::unique_lock<boost::mutex> lock(mtx_run_thread_isIdle);272 return run_thread_isIdle;273 }274 275 227 void ActionQueue::wait() 276 228 { 277 if (run_thread_running) {278 boost::unique_lock<boost::mutex> lock(mtx_run_thread_isIdle);279 while(!run_thread_isIdle)280 {281 cond_idle.wait(lock);282 283 } 284 } 285 229 boost::unique_lock<boost::mutex> lock(mtx_idle); 230 while(!run_thread_isIdle) 231 { 232 cond_idle.wait(lock); 233 } 234 } 235 #endif 236 237 #ifdef HAVE_ACTION_THREAD 286 238 void ActionQueue::stop() 287 239 { … … 359 311 void ActionQueue::clearQueue(const size_t _fromAction) 360 312 { 361 // free all actions contained in actionqueue 313 #ifdef HAVE_ACTION_THREAD 314 mtx_queue.lock(); 315 #endif 316 LOG(1, "Removing all Actions from position " << _fromAction << " onward."); 317 // free all actions still to be called contained in actionqueue 318 ActionQueue_t::iterator inititer = actionqueue.begin(); 319 std::advance(inititer, _fromAction); 320 for (ActionQueue_t::iterator iter = inititer; iter != actionqueue.end(); ++iter) 321 delete *iter; 322 actionqueue.erase(inititer, actionqueue.end()); 323 LOG(1, "There are " << actionqueue.size() << " remaining Actions."); 324 #ifdef HAVE_ACTION_THREAD 325 CurrentAction = actionqueue.size(); 326 mtx_queue.unlock(); 327 #endif 328 } 329 330 #ifdef HAVE_ACTION_THREAD 331 void ActionQueue::clearTempQueue() 332 { 333 // free all actions contained in tempqueue 334 for (ActionQueue_t::iterator iter = tempqueue.begin(); 335 !tempqueue.empty(); iter = tempqueue.begin()) { 336 delete *iter; 337 tempqueue.erase(iter); 338 } 339 } 340 341 void ActionQueue::setRunThreadIdle(const bool _flag) 342 { 362 343 { 363 #ifdef HAVE_ACTION_THREAD 364 boost::lock_guard<boost::mutex> lock(mtx_actionqueue); 365 #endif 366 LOG(1, "Removing all Actions from position " << _fromAction << " onward."); 367 // free all actions still to be called contained in actionqueue 368 ActionQueue_t::iterator inititer = actionqueue.begin(); 369 std::advance(inititer, _fromAction); 370 for (ActionQueue_t::iterator iter = inititer; iter != actionqueue.end(); ++iter) 371 delete *iter; 372 actionqueue.erase(inititer, actionqueue.end()); 373 LOG(1, "There are " << actionqueue.size() << " remaining Actions."); 374 #ifdef HAVE_ACTION_THREAD 375 CurrentAction = actionqueue.size(); 376 #endif 377 } 378 } 379 380 #ifdef HAVE_ACTION_THREAD 381 void ActionQueue::clearTempQueue() 382 { 383 // free all actions contained in tempqueue 384 { 385 boost::lock_guard<boost::mutex> lock(mtx_tempqueue); 386 for (ActionQueue_t::iterator iter = tempqueue.begin(); 387 !tempqueue.empty(); iter = tempqueue.begin()) { 388 delete *iter; 389 tempqueue.erase(iter); 390 } 344 boost::unique_lock<boost::mutex> lock(mtx_idle); 345 run_thread_isIdle = _flag; 391 346 } 392 347 } -
src/Actions/ActionQueue.hpp
r7e6c0d reea0bb 215 215 void clearTempQueue(); 216 216 217 /** Sets the run_thread_isIdle flag. 218 * 219 * @param _flag state to set to 220 */ 221 void setRunThreadIdle(const bool _flag); 222 217 223 /** Runs the ActionQueue. 218 224 * … … 249 255 void insertAction(Action *_action, enum Action::QueryOptions state); 250 256 251 #ifdef HAVE_ACTION_THREAD252 /** Helper to check whether there are more actions in actionqueue for253 * run_thread.254 *255 * \return false - more actions, true - CurrentAction is beyond last action.256 */257 bool isActionQueueDone() const;258 259 /** Helper to check whether there are more actions in tempqueue for260 * run_thread.261 *262 * \return false - more actions, true - tempqueue is empty263 */264 bool isTempQueueDone() const;265 266 /** Getter to run_thread_isIdle wrapped in mutex.267 *268 * \return true - run_thread is idle, false - it is not269 */270 bool getrun_thread_isIdle() const;271 272 /** Setter for run_thread_isIdle wrapped in mutex.273 *274 * \param _run_thread_isIdle new idle status for run_thread275 */276 void setrun_thread_isIdle(277 const bool _run_thread_isIdle);278 #endif279 280 257 private: 281 258 /** Private cstor for ActionQueue. … … 314 291 ActionQueue_t tempqueue; 315 292 293 //!> internal thread to call Actions 294 boost::thread run_thread; 295 316 296 //!> internal mutex to synchronize access to queue 317 mutable boost::mutex mtx_actionqueue; 318 319 //!> internal mutex to synchronize access to queue 320 mutable boost::mutex mtx_tempqueue; 297 boost::mutex mtx_queue; 321 298 322 299 //!> conditional variable notifying when run_thread is idling … … 327 304 328 305 //!> internal mutex to synchronize access to run_thread_isIdle 329 mutable boost::mutex mtx_run_thread_isIdle;306 boost::mutex mtx_idle; 330 307 #endif 331 308 332 309 //!> internal list of status messages from Actions for UIs to display 333 310 ActionStatusList StatusList; 334 335 // set run_thread to end such that others are initialized first (especially mutexes)336 #ifdef HAVE_ACTION_THREAD337 //!> internal flag to tell whether run_thread is still running338 bool run_thread_running;339 340 //!> internal thread to call Actions341 boost::thread run_thread;342 #endif343 311 }; 344 312 namespace Queuedetail {
Note:
See TracChangeset
for help on using the changeset viewer.