ChimeraTK-ApplicationCore 04.08.00
Loading...
Searching...
No Matches
ReverseRecoveryDecorator.cc
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
4
5namespace ChimeraTK {
6 /********************************************************************************************************************/
7
8 template<typename UserType>
10 boost::shared_ptr<ChimeraTK::NDRegisterAccessor<UserType>> accessor,
11 boost::shared_ptr<RecoveryHelper> recoveryHelper)
12 : ChimeraTK::NDRegisterAccessorDecorator<UserType>(std::move(accessor)), _recoveryHelper(std::move(recoveryHelper)) {
13 // Check if we are wrapping a push-type variable and forbid that
14 if(TransferElement::getAccessModeFlags().has(AccessMode::wait_for_new_data)) {
15 throw ChimeraTK::logic_error("Cannot use reverse recovery on push-type input");
16 }
17
18 // Set ourselves as wfnd:
19 TransferElement::_accessModeFlags.add(AccessMode::wait_for_new_data);
20
21 _recoveryHelper->notificationQueue = cppext::future_queue<void>(3);
23
24 // The DeviceManager will trigger the initial value read by writing to this readQueue.
25 this->_readQueue = _recoveryHelper->notificationQueue.template then<void>(
26 [&, this]() {
27 try {
28 _target->read();
29 }
30 catch(const ChimeraTK::runtime_error&) {
31 // Runtime errors may occur as a race condition, if the device breaks again between start of recovery in the
32 // DeviceManager and the initial value read request being processed here.
33 // We simply skip the initial value poll in that case, since we will be triggered again by the DeviceManager
34 // once the device recovers again.
35 throw ChimeraTK::detail::DiscardValueException(); // NOLINT(hicpp-exception-baseclass)
36 }
37 },
38 std::launch::deferred);
39 }
40
41 /********************************************************************************************************************/
42
43 template<typename UserType>
45 this->interrupt_impl(this->_recoveryHelper->notificationQueue);
46 }
47
48 /********************************************************************************************************************/
49
50 template<typename UserType>
52 // Skip flagging our target as being in a ReadAnyGroup (it isn't since we replace the readQueue with our own)
53 // NOLINTNEXTLINE(bugprone-parent-virtual-call)
54 NDRegisterAccessor<UserType>::setInReadAnyGroup(rag);
55 }
56
57 /********************************************************************************************************************/
58
59 template<typename UserType>
61
62 /********************************************************************************************************************/
63
64 template<typename UserType>
65 void ReverseRecoveryDecorator<UserType>::doPostRead(TransferType, bool updateBuffer) {
66 // Do the same as NDRegisterAccessorDecorator::doPostRead() but without delegating to the target. We must
67 // not delegate, because we did not call preRead() and the entire operation is executed inside the
68 // continuation of the readQueue (see constructor implementation).
69 _target->setActiveException(this->_activeException);
70
71 // Decorators have to copy meta data even if updateDataBuffer is false
72 this->_dataValidity = _target->dataValidity();
73 this->_versionNumber = _target->getVersionNumber();
74
75 if(!updateBuffer) {
76 return;
77 }
78
79 for(size_t i = 0; i < _target->getNumberOfChannels(); ++i) {
80 this->buffer_2D[i].swap(_target->accessChannel(i));
81 }
82 }
83
84 /********************************************************************************************************************/
85
87} // namespace ChimeraTK
void doPostRead(TransferType, bool updateBuffer) override
boost::shared_ptr< RecoveryHelper > _recoveryHelper
ReverseRecoveryDecorator(boost::shared_ptr< ChimeraTK::NDRegisterAccessor< UserType > > accessor, boost::shared_ptr< RecoveryHelper > recoveryHelper)
void setInReadAnyGroup(ReadAnyGroup *rag) override
InvalidityTracer application module.
INSTANTIATE_TEMPLATE_FOR_CHIMERATK_USER_TYPES(DebugPrintAccessorDecorator)