Changes in / [7e6c0d:eea0bb]


Ignore:
Location:
src/Actions
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/Actions/ActionQueue.cpp

    r7e6c0d reea0bb  
    6565    lastActionOk(true)
    6666#else
     67    CurrentAction(0),
    6768    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)
    7271#endif
    7372{
     
    105104  newaction->prepare(state);
    106105#ifdef HAVE_ACTION_THREAD
    107   mtx_actionqueue.lock();
     106  mtx_queue.lock();
    108107#endif
    109108  actionqueue.push_back( newaction );
     
    115114    std::cerr << "Action " << *boost::get_error_info<ActionNameString>(e) << " has failed." << std::endl;
    116115    World::getInstance().setExitFlag(5);
    117 //    clearQueue(actionqueue.size()-1);
     116    clearQueue(actionqueue.size()-1);
    118117    lastActionOk = false;
    119 //    std::cerr << "Remaining Actions cleared from queue." << std::endl;
     118    std::cerr << "Remaining Actions cleared from queue." << std::endl;
    120119  } catch (std::exception &e) {
    121120    pushStatus("FAIL: General exception caught, aborting.");
    122121    World::getInstance().setExitFlag(134);
    123 //    clearQueue(actionqueue.size()-1);
     122    clearQueue(actionqueue.size()-1);
    124123    lastActionOk = false;
    125 //    std::cerr << "Remaining Actions cleared from queue." << std::endl;
     124    std::cerr << "Remaining Actions cleared from queue." << std::endl;
    126125  }
    127126  if (lastActionOk) {
     
    131130  }
    132131#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}
    152136
    153137void ActionQueue::insertAction(Action *_action, enum Action::QueryOptions state)
     
    158142  Action *newaction = _action->clone(state);
    159143  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();
    169148#endif
    170149}
     
    173152void ActionQueue::run()
    174153{
    175   {
    176     boost::lock_guard<boost::mutex> lock(mtx_run_thread_isIdle);
    177     run_thread_running = true;
    178   }
    179154  bool Interrupted = false;
    180155  do {
     
    182157    try {
    183158#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));
    185160#else
    186161      boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
     
    192167//    LOG(1, "DEBUG: Start of ActionQueue's run() loop.");
    193168    // call all currently present Actions
     169    mtx_queue.lock();
    194170    insertTempQueue();
    195     while ((!Interrupted) && (!isActionQueueDone())) {
     171    bool status = (CurrentAction != actionqueue.size());
     172    mtx_queue.unlock();
     173    while (status) {
    196174      //      boost::this_thread::disable_interruption di;
    197       // access actionqueue, hence using mutex
    198       mtx_actionqueue.lock();
    199175      LOG(0, "Calling Action " << actionqueue[CurrentAction]->getName() << " ... ");
    200176      try {
     
    216192        std::cerr << "Remaining Actions cleared from queue." << std::endl;
    217193      }
    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();
    222204      // insert new actions (before [CurrentAction]) if they have been spawned
    223205      // we must have an extra vector for this, as we cannot change actionqueue
    224206      // while an action instance is "in-use"
    225       mtx_actionqueue.unlock();
    226 
    227207      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();
    235210    }
    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()) );
    241212    cond_idle.notify_one();
    242213//    LOG(1, "DEBUG: End of ActionQueue's run() loop.");
    243214  } while (!Interrupted);
    244   {
    245     boost::lock_guard<boost::mutex> lock(mtx_run_thread_isIdle);
    246     run_thread_running = false;
    247   }
    248215}
    249216
    250217void ActionQueue::insertTempQueue()
    251218{
    252   boost::lock_guard<boost::mutex> lock(mtx_tempqueue);
    253219  if (!tempqueue.empty()) {
    254     boost::lock_guard<boost::mutex> lock(mtx_actionqueue);
    255220    ActionQueue_t::iterator InsertionIter = actionqueue.begin();
    256221    std::advance(InsertionIter, CurrentAction);
     
    260225}
    261226
    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() const
    270 {
    271   boost::unique_lock<boost::mutex> lock(mtx_run_thread_isIdle);
    272   return run_thread_isIdle;
    273 }
    274 
    275227void ActionQueue::wait()
    276228{
    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
    286238void ActionQueue::stop()
    287239{
     
    359311void ActionQueue::clearQueue(const size_t _fromAction)
    360312{
    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
     331void 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
     341void ActionQueue::setRunThreadIdle(const bool _flag)
     342{
    362343  {
    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;
    391346  }
    392347}
  • src/Actions/ActionQueue.hpp

    r7e6c0d reea0bb  
    215215  void clearTempQueue();
    216216
     217  /** Sets the run_thread_isIdle flag.
     218   *
     219   * @param _flag state to set to
     220   */
     221  void setRunThreadIdle(const bool _flag);
     222
    217223  /** Runs the ActionQueue.
    218224   *
     
    249255  void insertAction(Action *_action, enum Action::QueryOptions state);
    250256
    251 #ifdef HAVE_ACTION_THREAD
    252   /** Helper to check whether there are more actions in actionqueue for
    253    * 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 for
    260    * run_thread.
    261    *
    262    * \return false - more actions, true - tempqueue is empty
    263    */
    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 not
    269    */
    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_thread
    275    */
    276   void setrun_thread_isIdle(
    277       const bool _run_thread_isIdle);
    278 #endif
    279 
    280257private:
    281258  /** Private cstor for ActionQueue.
     
    314291  ActionQueue_t tempqueue;
    315292
     293  //!> internal thread to call Actions
     294  boost::thread run_thread;
     295
    316296  //!> 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;
    321298
    322299  //!> conditional variable notifying when run_thread is idling
     
    327304
    328305  //!> internal mutex to synchronize access to run_thread_isIdle
    329   mutable boost::mutex mtx_run_thread_isIdle;
     306  boost::mutex mtx_idle;
    330307#endif
    331308
    332309  //!> internal list of status messages from Actions for UIs to display
    333310  ActionStatusList StatusList;
    334 
    335   // set run_thread to end such that others are initialized first (especially mutexes)
    336 #ifdef HAVE_ACTION_THREAD
    337   //!> internal flag to tell whether run_thread is still running
    338   bool run_thread_running;
    339 
    340   //!> internal thread to call Actions
    341   boost::thread run_thread;
    342 #endif
    343311};
    344312namespace Queuedetail {
Note: See TracChangeset for help on using the changeset viewer.