Skip to content
Snippets Groups Projects
Commit 6fa95cd7 authored by Tomasz Kozak's avatar Tomasz Kozak
Browse files

Start of implementation for issue #80

parent 8ab22387
No related branches found
No related tags found
No related merge requests found
......@@ -19,8 +19,8 @@ namespace ChimeraTK {
class ExceptionHandlingDecorator : public ChimeraTK::NDRegisterAccessorDecorator<UserType> {
public:
ExceptionHandlingDecorator(
boost::shared_ptr<ChimeraTK::NDRegisterAccessor<UserType>> accessor, DeviceModule& devMod)
: ChimeraTK::NDRegisterAccessorDecorator<UserType>(accessor), dm(devMod) {}
boost::shared_ptr<ChimeraTK::NDRegisterAccessor<UserType>> accessor, DeviceModule& devMod, EntityOwner* owner)
: ChimeraTK::NDRegisterAccessorDecorator<UserType>(accessor), deviceModule(devMod), _owner(owner) {}
bool doWriteTransfer(ChimeraTK::VersionNumber versionNumber = {}) override;
......@@ -48,9 +48,11 @@ namespace ChimeraTK {
void interrupt() override;
protected:
DeviceModule& dm;
DeviceModule& deviceModule;
DataValidity validity{DataValidity::ok};
bool genericTransfer(std::function<bool(void)> callable, bool invalidateOnFailure = true);
void setOwnerValidity(DataValidity newValidity);
EntityOwner* _owner;
};
DECLARE_TEMPLATE_FOR_CHIMERATK_USER_TYPES(ExceptionHandlingDecorator);
......
......@@ -358,7 +358,7 @@ boost::shared_ptr<ChimeraTK::NDRegisterAccessor<UserType>> Application::createDe
assert(devmod != nullptr);
// decorate the accessor with a ExceptionHandlingDecorator and return it
return boost::make_shared<ExceptionHandlingDecorator<UserType>>(accessor, *devmod);
return boost::make_shared<ExceptionHandlingDecorator<UserType>>(accessor, *devmod, nullptr);
}
/*********************************************************************************************************************/
......@@ -802,7 +802,7 @@ void Application::typedMakeConnection(VariableNetwork& network) {
// In case we have one or more trigger receivers among our consumers, we
// produce one consuming application variable for each device. Later this will create a TriggerFanOut for
// each trigger consimer, i.e. one per device so one blocking device does not affect the others.
// each trigger consumer, i.e. one per device so one blocking device does not affect the others.
/** Map of deviceAliases to their corresponding TriggerFanOuts. */
std::map<std::string, boost::shared_ptr<ChimeraTK::NDRegisterAccessor<UserType>>> triggerFanOuts;
......
......@@ -7,33 +7,49 @@ constexpr useconds_t DeviceOpenTimeout = 500;
namespace ChimeraTK {
template<typename UserType>
void ExceptionHandlingDecorator<UserType>::setOwnerValidity(DataValidity newValidity) {
if (newValidity != validity) {
validity = newValidity;
if (!_owner) return; // hack to deal with null ptr until it filled correctly
if (newValidity == DataValidity::faulty) {
_owner->incrementDataFaultCounter();
} else {
_owner->decrementDataFaultCounter();
}
}
}
template<typename UserType>
bool ExceptionHandlingDecorator<UserType>::genericTransfer(
std::function<bool(void)> callable, bool invalidateOnFailure) {
std::function<void()> invalidateData{};
if(invalidateOnFailure) {
invalidateData = [=]() { setDataValidity(DataValidity::faulty); };
}
std::function<bool(void)> callable, bool updateOwnerValidityFlag) {
std::function<void(DataValidity)> setOwnerValidityFunction{};
if(updateOwnerValidityFlag) {
setOwnerValidityFunction = std::bind(&ExceptionHandlingDecorator<UserType>::setOwnerValidity, this, std::placeholders::_1);
}
else {
invalidateData = []() {}; // do nothing if user does
// not want to invalidate data.
setOwnerValidityFunction = [](DataValidity) {}; // do nothing if user does
// not want to invalidate data.
}
while(true) {
try {
if(!dm.device.isOpened()) {
invalidateData();
if(!deviceModule.device.isOpened()) {
setOwnerValidityFunction(DataValidity::faulty);
Application::getInstance().testableModeUnlock("waitForDeviceOpen");
boost::this_thread::sleep(boost::posix_time::millisec(DeviceOpenTimeout));
Application::getInstance().testableModeLock("waitForDeviceOpen");
continue;
}
auto retval = callable();
setDataValidity(DataValidity::ok);
auto delegatedValidity = ChimeraTK::NDRegisterAccessorDecorator<UserType>::dataValidity();
setOwnerValidityFunction(delegatedValidity);
return retval;
}
catch(ChimeraTK::runtime_error& e) {
invalidateData();
dm.reportException(e.what());
setOwnerValidityFunction(DataValidity::faulty);
deviceModule.reportException(e.what());
}
}
}
......@@ -127,7 +143,7 @@ namespace ChimeraTK {
template<typename UserType>
void ExceptionHandlingDecorator<UserType>::interrupt() {
// notify the condition variable waiting in reportException of the genericTransfer
dm.notify();
deviceModule.notify();
ChimeraTK::NDRegisterAccessorDecorator<UserType>::interrupt();
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment