diff --git a/include/DeviceModule.h b/include/DeviceModule.h index e53ecf75d4ca96642e26822822a8273d353e6c0b..44717ff21c98fea7d38e0e69953667ed7400d94a 100644 --- a/include/DeviceModule.h +++ b/include/DeviceModule.h @@ -257,10 +257,6 @@ namespace ChimeraTK { * The function is running an endless loop inside its own thread (moduleThread). */ void handleException(); - /** List of TransferElements to be written after the device has been opened. This is used to write constant feeders - * to the device. */ - std::list<boost::shared_ptr<TransferElement>> writeAfterOpen; - /** List of TransferElements to be written after the device has been recovered. * See function addRecoveryAccessor() for details.*/ std::list<boost::shared_ptr<TransferElement>> writeRecoveryOpen; diff --git a/src/Application.cc b/src/Application.cc index f44320224cb22bf75fa4f46e4f1fc6209299fc77..b65d7458f6c9b1abf0883056fcb337299167c9ef 100644 --- a/src/Application.cc +++ b/src/Application.cc @@ -1006,8 +1006,13 @@ void Application::typedMakeConnection(VariableNetwork& network) { impl->write(); } else if(consumer.getType() == NodeType::Device) { - auto impl = createDeviceVariable<UserType>(consumer.getDeviceAlias(), consumer.getRegisterName(), - {VariableDirection::consuming, false}, consumer.getMode(), consumer.getNumberOfElements()); + // we register the required accessor as a recovery accessor. This is just a bare RegisterAccessor without any decorations directly from the backend. + if(deviceMap.count(consumer.getDeviceAlias()) == 0) { + deviceMap[consumer.getDeviceAlias()] = + ChimeraTK::BackendFactory::getInstance().createBackend(consumer.getDeviceAlias()); + } + auto impl = deviceMap[consumer.getDeviceAlias()]->getRegisterAccessor<UserType>( + consumer.getRegisterName(), consumer.getNumberOfElements(), 0, {}); impl->accessChannel(0) = feedingImpl->accessChannel(0); // find the right DeviceModule for this alias name DeviceModule* devmod = nullptr; @@ -1018,8 +1023,8 @@ void Application::typedMakeConnection(VariableNetwork& network) { } } assert(devmod != nullptr); - // register feeder to be written after the device has been opened - devmod->writeAfterOpen.push_back(impl); + + devmod->addRecoveryAccessor(impl); } else if(consumer.getType() == NodeType::TriggerReceiver) { throw ChimeraTK::logic_error("Using constants as triggers is not supported!"); diff --git a/src/DeviceModule.cc b/src/DeviceModule.cc index ae76d4cdc29504e1f86938c3a9253e477d7e6731..73f21703929e4c116dc47cc63d9df4d9198c92c2 100644 --- a/src/DeviceModule.cc +++ b/src/DeviceModule.cc @@ -294,13 +294,16 @@ namespace ChimeraTK { } } } + // The device was successfully opened, try to initialise it try { for(auto& initHandler : initialisationHandlers) { initHandler(this); } - for(auto& te : writeAfterOpen) { - te->write(); + for(auto& te : writeRecoveryOpen) { + if(te->getVersionNumber() != VersionNumber{nullptr}) { + te->write(); + } } } catch(ChimeraTK::runtime_error& e) { @@ -377,7 +380,9 @@ namespace ChimeraTK { { // scope for the lock guard boost::unique_lock<boost::shared_mutex> uniqueLock(recoverySharedMutex); for(auto& te : writeRecoveryOpen) { - te->write(); + if(te->getVersionNumber() != VersionNumber{nullptr}) { + te->write(); + } } } // end of scope for the lock guard } diff --git a/src/ExceptionHandlingDecorator.cc b/src/ExceptionHandlingDecorator.cc index 2eae375e7a76df2880af32804b01ab4fb932eb5a..caa98bfae82bbb69c8530c5f6b45101d5ab8410c 100644 --- a/src/ExceptionHandlingDecorator.cc +++ b/src/ExceptionHandlingDecorator.cc @@ -52,9 +52,6 @@ namespace ChimeraTK { // If the application has not yet fully started, we cannot wait for the device to open. Instead register // the variable in the DeviceMoule, so the transfer will be performed after the device is opened. assert(_recoveryAccessor != nullptr); // should always be true for writeable registers with this decorator - // Note: it's ok to use the recoveryAccessor here as well, since device opening and recovery happens in the - // same thread in the DeviceModule. - deviceModule.writeAfterOpen.push_back(this->_recoveryAccessor); return false; } // We artificially increase the testabel mode counter so the test does not slip out of testable mode here in case