Changeset 9ac3d3


Ignore:
Timestamp:
Jul 19, 2018, 2:39:51 PM (6 years ago)
Author:
Frederik Heber <frederik.heber@…>
Branches:
Candidate_v1.6.1
Children:
209f4c
Parents:
ca2880
git-author:
Frederik Heber <frederik.heber@…> (07/19/18 14:39:04)
git-committer:
Frederik Heber <frederik.heber@…> (07/19/18 14:39:51)
Message:

FIX: Constrained locking in CodePattern's Notification and Observable.

  • this is not a full soluton to possible race conditions with Qt's own threading but seems to help for the guichecks.
Location:
ThirdParty/CodePatterns/src/Observer
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • ThirdParty/CodePatterns/src/Observer/Notification.cpp

    rca2880 r9ac3d3  
    5252void Notification::notifyAll(Observable * const publisher)
    5353{
    54   boost::recursive_mutex::scoped_lock guard(TargetsLock);
    55   // copy such that signOff() within receiving update() does not affect iterating
    56   // this is because within the same thread and with the update() signOff() may be
    57   // called and when executed it modifies targets
    58   targets_t temp_targets = targets;
     54  targets_t temp_targets;
     55  {
     56    boost::recursive_mutex::scoped_lock guard(TargetsLock);
     57    // copy such that signOff() within receiving update() does not affect iterating
     58    // this is because within the same thread and with the update() signOff() may be
     59    // called and when executed it modifies targets
     60    temp_targets = targets;
     61  }
    5962  for(targets_t::iterator it=temp_targets.begin();
    6063      it!=temp_targets.end();++it){
  • ThirdParty/CodePatterns/src/Observer/Observable.cpp

    rca2880 r9ac3d3  
    152152  // and call all observers
    153153  try {
    154     boost::recursive_mutex::scoped_lock lock(GlobalObservableInfo::getInstance().getObservablesMapMutex());
    155     GlobalObservableInfo::calltable_t& callTable = GlobalObservableInfo::getInstance().getcallTable();
    156     const bool callTable_contains = callTable.find(this) != callTable.end();
     154    bool callTable_contains;
     155    {
     156      boost::recursive_mutex::scoped_lock lock(GlobalObservableInfo::getInstance().getObservablesMapMutex());
     157      GlobalObservableInfo::calltable_t& callTable = GlobalObservableInfo::getInstance().getcallTable();
     158      callTable_contains = callTable.find(this) != callTable.end();
     159    }
    157160    if (callTable_contains) {
     161      GlobalObservableInfo::callees_t callees;
     162      {
     163        boost::recursive_mutex::scoped_lock lock(GlobalObservableInfo::getInstance().getObservablesMapMutex());
     164        GlobalObservableInfo::calltable_t& callTable = GlobalObservableInfo::getInstance().getcallTable();
     165        callees = callTable[this];
     166      }
    158167      // elements are stored sorted by keys in the multimap
    159168      // so iterating over it gives us a the callees sorted by
     
    162171      // this is because within the same thread and with the updateKilled() signOff() may be
    163172      // called and when executed it modifies targets
    164       GlobalObservableInfo::callees_t callees = callTable[this];
    165173      GlobalObservableInfo::callees_t::iterator iter;
    166174      for(iter=callees.begin();iter!=callees.end();++iter){
     
    178186  // send out all notifications that need to be done
    179187  {
    180     boost::recursive_mutex::scoped_lock lock(GlobalObservableInfo::getInstance().getObservablesMapMutex());
    181     GlobalObservableInfo::notificationSet currentNotifications =
    182         (GlobalObservableInfo::getInstance().getnotifications())[this];
     188    GlobalObservableInfo::notificationSet currentNotifications;
     189    {
     190      boost::recursive_mutex::scoped_lock lock(GlobalObservableInfo::getInstance().getObservablesMapMutex());
     191      currentNotifications = (GlobalObservableInfo::getInstance().getnotifications())[this];
     192    }
    183193    for(GlobalObservableInfo::notificationSet::iterator it = currentNotifications.begin();
    184194        it != currentNotifications.end();++it){
     
    224234  }
    225235  else {
    226     boost::recursive_mutex::scoped_lock lock(GlobalObservableInfo::getInstance().getObservablesMapMutex());
    227     // see if we are in the process of changing ourselves
    228     // if we are changing ourselves at the same time our sub-observables change
    229     // we do not need to publish all the changes at each time we are called
    230     std::map<Observable*, int>& depth = GlobalObservableInfo::getInstance().getdepth();
    231     const bool depth_contains = depth.find(this)==depth.end();
     236    bool depth_contains;
     237    {
     238      boost::recursive_mutex::scoped_lock lock(GlobalObservableInfo::getInstance().getObservablesMapMutex());
     239      // see if we are in the process of changing ourselves
     240      // if we are changing ourselves at the same time our sub-observables change
     241      // we do not need to publish all the changes at each time we are called
     242      std::map<Observable*, int>& depth = GlobalObservableInfo::getInstance().getdepth();
     243      depth_contains = depth.find(this)==depth.end();
     244    }
    232245    if(depth_contains) {
    233246#ifdef LOG_OBSERVER
     
    409422  }
    410423  if(CallTable_contains) {
    411     // copy the list from the map
    412     boost::recursive_mutex::scoped_lock lock(GlobalObservableInfo::getInstance().getObservablesMapMutex());
    413     // copy such that signOff() within receiving subjectKilled() does not affect iterating
    414     // this is because within the same thread and with the subjectKilled() signOff() may be
    415     // called and when executed it modifies targets
    416     GlobalObservableInfo::callees_t callees = (GlobalObservableInfo::getInstance().getcallTable())[this];
     424    GlobalObservableInfo::callees_t callees;
     425    {
     426      // copy the list from the map
     427      boost::recursive_mutex::scoped_lock lock(GlobalObservableInfo::getInstance().getObservablesMapMutex());
     428      // copy such that signOff() within receiving subjectKilled() does not affect iterating
     429      // this is because within the same thread and with the subjectKilled() signOff() may be
     430      // called and when executed it modifies targets
     431      callees = (GlobalObservableInfo::getInstance().getcallTable())[this];
     432    }
    417433    // delete all entries for this observable
    418434    GlobalObservableInfo::callees_t::iterator iter;
     
    420436      (*iter).second->subjectKilled(this);
    421437    // erase the list in the map
    422     (GlobalObservableInfo::getInstance().getcallTable()).erase(this);
     438    {
     439      boost::recursive_mutex::scoped_lock lock(GlobalObservableInfo::getInstance().getObservablesMapMutex());
     440      (GlobalObservableInfo::getInstance().getcallTable()).erase(this);
     441    }
    423442  }
    424443
Note: See TracChangeset for help on using the changeset viewer.