Changeset 23b6cf for src/Actions


Ignore:
Timestamp:
Oct 23, 2014, 4:33:11 PM (10 years ago)
Author:
Frederik Heber <heber@…>
Children:
9a4949
Parents:
7b38d3
git-author:
Frederik Heber <heber@…> (08/29/14 09:46:02)
git-committer:
Frederik Heber <heber@…> (10/23/14 16:33:11)
Message:

THREADFIX: Fixed ActionQueue with respect to mutex and threads.

  • run_thread is now last member variable, hence started after all other variables are initialized.
  • separated accesses to queues and to run_thread_isIdle flag. Also renamed its mutex for easier association with it.
Location:
src/Actions
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/Actions/ActionQueue.cpp

    r7b38d3 r23b6cf  
    6666#else
    6767    lastActionOk(true),
    68     run_thread(boost::bind(&ActionQueue::run, this)),
    69     run_thread_isIdle(true)
     68    run_thread_isIdle(true),
     69    run_thread(boost::bind(&ActionQueue::run, this))
    7070#endif
    7171{
     
    127127  }
    128128#else
     129  const bool new_run_thread_isIdle = (CurrentAction == actionqueue.size());
     130  mtx_queue.unlock();
    129131  {
    130     boost::lock_guard<boost::mutex> lock(mtx_idle);
    131     run_thread_isIdle = (CurrentAction == actionqueue.size());
    132   }
    133   mtx_queue.unlock();
     132    boost::lock_guard<boost::mutex> lock(mtx_run_thread_isIdle);
     133    run_thread_isIdle = new_run_thread_isIdle;
     134  }
    134135#endif
    135136}
     
    145146  tempqueue.push_back( newaction );
    146147  {
    147     boost::lock_guard<boost::mutex> lock(mtx_idle);
     148    boost::lock_guard<boost::mutex> lock(mtx_run_thread_isIdle);
    148149    run_thread_isIdle = !((CurrentAction != actionqueue.size()) || !tempqueue.empty());
    149150  }
     
    160161    try {
    161162#if BOOST_VERSION < 105000
    162       run_thread.sleep(boost::get_system_time() + boost::posix_time::milliseconds(100));
     163      boost::this_thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(100));
    163164#else
    164165      boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
     
    176177    while (status) {
    177178      //      boost::this_thread::disable_interruption di;
     179      // access actionqueue, hence using mutex
     180      mtx_queue.lock();
    178181      LOG(0, "Calling Action " << actionqueue[CurrentAction]->getName() << " ... ");
    179182      try {
     
    195198        CurrentAction = (size_t)-1;
    196199      }
    197       if (lastActionOk) {
    198         OBSERVE;
    199         NOTIFY(ActionQueued);
    200         _lastchangedaction = actionqueue[CurrentAction];
    201       }
    202       // access actionqueue, hence using mutex
    203       mtx_queue.lock();
     200      // remember action we juse executed
     201      const Action *lastaction = actionqueue[CurrentAction];
    204202      // step on to next action and check for end
    205203      CurrentAction++;
     
    209207      insertTempQueue();
    210208      status = (CurrentAction != actionqueue.size());
    211       mtx_queue.unlock();
     209      // set last action
     210      if (lastActionOk) {
     211        OBSERVE;
     212        NOTIFY(ActionQueued);
     213        _lastchangedaction = lastaction;
     214        // unlock before we delve into Observer functions ...
     215        mtx_queue.unlock();
     216      } else {
     217        mtx_queue.unlock();
     218      }
    212219    }
     220    mtx_queue.lock();
     221    const bool new_run_thread_isIdle = !((CurrentAction != actionqueue.size()) || !tempqueue.empty());
     222    mtx_queue.unlock();
    213223    {
    214       boost::lock_guard<boost::mutex> lock(mtx_idle);
    215       run_thread_isIdle = !((CurrentAction != actionqueue.size()) || !tempqueue.empty());
     224      boost::lock_guard<boost::mutex> lock(mtx_run_thread_isIdle);
     225      run_thread_isIdle = new_run_thread_isIdle;
    216226    }
    217227    cond_idle.notify_one();
     
    234244void ActionQueue::wait()
    235245{
    236   boost::unique_lock<boost::mutex> lock(mtx_idle);
     246  boost::unique_lock<boost::mutex> lock(mtx_run_thread_isIdle);
    237247  while(!run_thread_isIdle)
    238248  {
  • src/Actions/ActionQueue.hpp

    r7b38d3 r23b6cf  
    265265
    266266#ifdef HAVE_ACTION_THREAD
     267  //!> internal mutex to synchronize access to queue
     268  boost::mutex mtx_queue;
     269
     270  //!> conditional variable notifying when run_thread is idling
     271  boost::condition_variable cond_idle;
     272
     273  //!> flag indicating whether run_thread is idle or not
     274  bool run_thread_isIdle;
     275
     276  //!> internal mutex to synchronize access to run_thread_isIdle
     277  boost::mutex mtx_run_thread_isIdle;
     278#endif
     279
     280  //!> internal list of status messages from Actions for UIs to display
     281  ActionStatusList StatusList;
     282
     283  // set run_thread to end such that others are initialized first (especially mutexes)
     284#ifdef HAVE_ACTION_THREAD
    267285  //!> internal thread to call Actions
    268286  boost::thread run_thread;
    269 
    270   //!> internal mutex to synchronize access to queue
    271   boost::mutex mtx_queue;
    272 
    273   //!> conditional variable notifying when run_thread is idling
    274   boost::condition_variable cond_idle;
    275 
    276   //!> flag indicating whether run_thread is idle or not
    277   bool run_thread_isIdle;
    278 
    279   //!> internal mutex to synchronize access to run_thread_isIdle
    280   boost::mutex mtx_idle;
    281 #endif
    282 
    283   //!> internal list of status messages from Actions for UIs to display
    284   ActionStatusList StatusList;
     287#endif
    285288};
    286289namespace Queuedetail {
Note: See TracChangeset for help on using the changeset viewer.