Skip to content
Snippets Groups Projects
Commit 4e7a1ba2 authored by Martin Killenberg's avatar Martin Killenberg
Browse files

wip ExceptionHandling

- fixed that ConsumingFanOut is propagating the data to the slaves in case of exceptions
- /testPropagateDataFaultFlag currently passing (still commented sections)
parent 01f4306a
No related branches found
No related tags found
No related merge requests found
......@@ -26,20 +26,31 @@ namespace ChimeraTK {
: FanOut<UserType>(feedingImpl), ChimeraTK::NDRegisterAccessorDecorator<UserType>(feedingImpl) {
assert(feedingImpl->isReadable());
_lastReceivedValue.resize(buffer_2D[0].size());
// Add the consuming accessors
for(auto el : consumerImplementationPairs) {
FanOut<UserType>::addSlave(el.first, el.second);
}
}
void doPostRead(TransferType type, bool hasNewData) override {
ChimeraTK::NDRegisterAccessorDecorator<UserType>::doPostRead(type, hasNewData);
if(!hasNewData) return;
void doPostRead(TransferType type, bool updateDataBuffer) override {
ChimeraTK::NDRegisterAccessorDecorator<UserType>::doPostRead(type, updateDataBuffer);
if(updateDataBuffer) {
// We have to keep a copy to write into the slaves. There might
// be decorators arount this fanout which swap out buffer_2D, so it is
// not available any more for a second read witout updateDataBuffer (exception case).
_lastReceivedValue = buffer_2D[0];
}
// The ConsumingFanOut conceptually never has a wait_fow_new_data flags. Hence each read
// operation returns with "new" data, even in case of an exception. So each read
// always synchronises all slaves and pushes the content of the data buffer.
for(auto& slave : FanOut<UserType>::slaves) { // send out copies to slaves
// do not send copy if no data is expected (e.g. trigger)
if(slave->getNumberOfSamples() != 0) {
slave->accessChannel(0) = buffer_2D[0];
slave->accessChannel(0) = _lastReceivedValue;
}
slave->setDataValidity(this->dataValidity());
slave->writeDestructively();
......@@ -56,6 +67,7 @@ namespace ChimeraTK {
protected:
using ChimeraTK::NDRegisterAccessor<UserType>::buffer_2D;
std::vector<UserType> _lastReceivedValue;
};
} /* namespace ChimeraTK */
......
......@@ -729,10 +729,11 @@ BOOST_AUTO_TEST_CASE(testConsumingFanout) {
consumingFanoutSource = 0;
device1DummyBackend->throwExceptionRead = true;
threadedFanoutInput = 20;
threadedFanoutInput.write();
CHECK_TIMEOUT(result.readLatest(), 10000);
BOOST_CHECK_EQUAL(result, 111);
BOOST_CHECK_EQUAL(result, 121);
BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
CHECK_TIMEOUT(fromConsumingFanout.readLatest(), 10000);
......@@ -741,10 +742,18 @@ BOOST_AUTO_TEST_CASE(testConsumingFanout) {
// --------------------------------------------------------//
// Recovery
device1DummyBackend->throwExceptionRead = true;
device1DummyBackend->throwExceptionRead = false;
// Wait until the device has recovered. Otherwise the read might be skipped and we still read the previous value with the faulty flag.
while((void)device1Status.read(), device1Status == 1) {
usleep(1000);
}
threadedFanoutInput = 30;
threadedFanoutInput.write();
CHECK_TIMEOUT(result.readLatest(), 10000);
BOOST_CHECK_EQUAL(result, 110);
BOOST_CHECK_EQUAL(result, 130);
BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
CHECK_TIMEOUT(fromConsumingFanout.readLatest(), 10000);
......
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