diff --git a/src/DoocsUpdater.cc b/src/DoocsUpdater.cc index ddcd99c025ba55d57756a7054e6f500bc68ab950..47242dc7216e723a375fe3a8b6e18c7d44d4d0c1 100644 --- a/src/DoocsUpdater.cc +++ b/src/DoocsUpdater.cc @@ -36,22 +36,26 @@ namespace ChimeraTK { return; } + // Worst-case: We need to lock all locations, so pre-allocate this here + std::unordered_set<EqFct*> locationsToLock; + locationsToLock.reserve(_toDoocsEqFctMap.size()); + ReadAnyGroup group(_elementsToRead.begin(), _elementsToRead.end()); while(true) { // Wait until any variable got an update auto notification = group.waitAny(); auto updatedElement = notification.getId(); // Gather all involved locations in a unique set - std::unordered_set<EqFct*> locationsToLock; - for(auto& location : _toDoocsEqFctMap[updatedElement]) locationsToLock.insert(location); - // Lock all involved locations - for(auto& location : locationsToLock) location->lock(); + for(auto& location : _toDoocsEqFctMap[updatedElement]) { + if(locationsToLock.insert(location).second) location->lock(); + } // Complete the read transfer of the process variable notification.accept(); // Call all updater functions for(auto& updaterFunction : _toDoocsUpdateMap[updatedElement]) updaterFunction(); // Unlock all involved locations for(auto& location : locationsToLock) location->unlock(); + locationsToLock.clear(); // Allow shutting down this thread... boost::this_thread::interruption_point(); }