Ignore:
Timestamp:
Oct 23, 2014, 4:34:39 PM (10 years ago)
Author:
Frederik Heber <heber@…>
Children:
7e6c0d
Parents:
9a4949
git-author:
Frederik Heber <heber@…> (09/03/14 19:26:17)
git-committer:
Frederik Heber <heber@…> (10/23/14 16:34:39)
Message:

Cleaned up use of mutexes in ActionQueue.

  • tempqueue now has its own mutex.
  • more often using lock_guard.
  • run_thread_isIdle has own mutex.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Actions/ActionQueue.cpp

    r9a4949 rfff8fc  
    102102  newaction->prepare(state);
    103103#ifdef HAVE_ACTION_THREAD
    104   mtx_queue.lock();
     104  mtx_actionqueue.lock();
    105105#endif
    106106  actionqueue.push_back( newaction );
     
    129129#else
    130130  const bool new_run_thread_isIdle = (CurrentAction == actionqueue.size());
    131   mtx_queue.unlock();
     131  mtx_actionqueue.unlock();
    132132  {
    133133    boost::lock_guard<boost::mutex> lock(mtx_run_thread_isIdle);
     
    135135  }
    136136#endif
     137}
     138
     139bool ActionQueue::isActionQueueDone() const
     140{
     141#ifdef HAVE_ACTION_THREAD
     142  boost::lock_guard<boost::mutex> lock(mtx_actionqueue);
     143#endif
     144  return (CurrentAction == actionqueue.size());
     145}
     146
     147bool ActionQueue::isTempQueueDone() const
     148{
     149#ifdef HAVE_ACTION_THREAD
     150  boost::lock_guard<boost::mutex> lock(mtx_tempqueue);
     151#endif
     152  return tempqueue.empty();
    137153}
    138154
     
    144160  Action *newaction = _action->clone(state);
    145161  newaction->prepare(state);
    146   mtx_queue.lock();
    147   tempqueue.push_back( newaction );
    148   {
    149     boost::lock_guard<boost::mutex> lock(mtx_run_thread_isIdle);
    150     run_thread_isIdle = !((CurrentAction != actionqueue.size()) || !tempqueue.empty());
    151   }
    152   mtx_queue.unlock();
     162  {
     163    boost::lock_guard<boost::mutex> lock(mtx_tempqueue);
     164    tempqueue.push_back( newaction );
     165  }
     166  {
     167    bool new_run_thread_isIdle = getrun_thread_isIdle();
     168    new_run_thread_isIdle &= isTempQueueDone();
     169    setrun_thread_isIdle(new_run_thread_isIdle);
     170  }
    153171#endif
    154172}
     
    176194//    LOG(1, "DEBUG: Start of ActionQueue's run() loop.");
    177195    // call all currently present Actions
    178     mtx_queue.lock();
    179196    insertTempQueue();
    180     bool status = (CurrentAction != actionqueue.size());
    181     mtx_queue.unlock();
    182     while ((status) && (!Interrupted)) {
     197    while ((!Interrupted) && (!isActionQueueDone())) {
    183198      //      boost::this_thread::disable_interruption di;
    184199      // access actionqueue, hence using mutex
    185       mtx_queue.lock();
     200      mtx_actionqueue.lock();
    186201      LOG(0, "Calling Action " << actionqueue[CurrentAction]->getName() << " ... ");
    187202      try {
     
    210225      // we must have an extra vector for this, as we cannot change actionqueue
    211226      // while an action instance is "in-use"
     227      mtx_actionqueue.unlock();
     228
    212229      insertTempQueue();
    213       status = (CurrentAction != actionqueue.size());
     230
    214231      // set last action
    215232      if (lastActionOk) {
     
    217234        NOTIFY(ActionQueued);
    218235        _lastchangedaction = lastaction;
    219         // unlock before we delve into Observer functions ...
    220         mtx_queue.unlock();
    221       } else {
    222         mtx_queue.unlock();
    223236      }
    224237    }
    225     mtx_queue.lock();
    226     const bool new_run_thread_isIdle = !((CurrentAction != actionqueue.size()) || !tempqueue.empty());
    227     mtx_queue.unlock();
    228238    {
    229       boost::lock_guard<boost::mutex> lock(mtx_run_thread_isIdle);
    230       run_thread_isIdle = new_run_thread_isIdle;
     239      bool new_run_thread_isIdle = isActionQueueDone();
     240      new_run_thread_isIdle &= isTempQueueDone();
     241      setrun_thread_isIdle(new_run_thread_isIdle);
    231242    }
    232243    cond_idle.notify_one();
     
    242253void ActionQueue::insertTempQueue()
    243254{
     255#ifdef HAVE_ACTION_THREAD
     256  boost::lock_guard<boost::mutex> lock(mtx_tempqueue);
     257#endif
    244258  if (!tempqueue.empty()) {
     259#ifdef HAVE_ACTION_THREAD
     260    boost::lock_guard<boost::mutex> lock(mtx_actionqueue);
     261#endif
    245262    ActionQueue_t::iterator InsertionIter = actionqueue.begin();
    246263    std::advance(InsertionIter, CurrentAction);
     
    251268
    252269#ifdef HAVE_ACTION_THREAD
     270void ActionQueue::setrun_thread_isIdle(
     271    const bool _run_thread_isIdle)
     272{
     273  boost::unique_lock<boost::mutex> lock(mtx_run_thread_isIdle);
     274  run_thread_isIdle = _run_thread_isIdle;
     275}
     276
     277bool ActionQueue::getrun_thread_isIdle() const
     278{
     279  boost::unique_lock<boost::mutex> lock(mtx_run_thread_isIdle);
     280  return run_thread_isIdle;
     281}
     282#endif
     283
     284#ifdef HAVE_ACTION_THREAD
    253285void ActionQueue::wait()
    254286{
    255   boost::unique_lock<boost::mutex> lock(mtx_run_thread_isIdle);
    256   if (run_thread_running)
     287  if (run_thread_running) {
     288    boost::unique_lock<boost::mutex> lock(mtx_run_thread_isIdle);
    257289    while(!run_thread_isIdle)
    258290    {
    259291        cond_idle.wait(lock);
    260292    }
     293  }
    261294}
    262295#endif
     
    339372{
    340373  // free all actions contained in actionqueue
    341   for (ActionQueue_t::iterator iter = actionqueue.begin();
    342       !actionqueue.empty(); iter = actionqueue.begin()) {
    343     delete *iter;
    344     actionqueue.erase(iter);
     374  {
     375#ifdef HAVE_ACTION_THREAD
     376    boost::lock_guard<boost::mutex> lock(mtx_actionqueue);
     377#endif
     378    for (ActionQueue_t::iterator iter = actionqueue.begin();
     379        !actionqueue.empty(); iter = actionqueue.begin()) {
     380      delete *iter;
     381      actionqueue.erase(iter);
     382    }
    345383  }
    346384  // free all actions contained in tempqueue
    347   for (ActionQueue_t::iterator iter = tempqueue.begin();
    348       !tempqueue.empty(); iter = tempqueue.begin()) {
    349     delete *iter;
    350     tempqueue.erase(iter);
     385  {
     386#ifdef HAVE_ACTION_THREAD
     387    boost::lock_guard<boost::mutex> lock(mtx_tempqueue);
     388#endif
     389    for (ActionQueue_t::iterator iter = tempqueue.begin();
     390        !tempqueue.empty(); iter = tempqueue.begin()) {
     391      delete *iter;
     392      tempqueue.erase(iter);
     393    }
    351394  }
    352395#ifdef HAVE_ACTION_THREAD
Note: See TracChangeset for help on using the changeset viewer.