Skip to content
Snippets Groups Projects
Commit 94f757a1 authored by Christoph Kampmeyer's avatar Christoph Kampmeyer
Browse files

Merge branch 'master' into wip/ckampm/wip-fix-compatibility-da

parents b7fb1f68 756e33c8
No related branches found
No related tags found
No related merge requests found
......@@ -13,9 +13,18 @@
namespace ChimeraTK {
/** Implementation of the NDRegisterAccessor which delivers always the same
* value and ignors any write operations.
* If AccessMode::wait_for_new_data was set, TransferElement::read() will
* still block until new data has arrived.
* value and ignors any write operations */
* return once with the initial value, and the block on the second call, waiting for new
* data which obviously nerver arrives. A blocking call can be interrupted by
* calling TransferElemtent::interrupt, which will throw a boost::thread_interrupted exception.
*
* For writing, it conceptually works like /dev/null. The data is intentionally dropped and
* not considered "lost". Hence write() and writeNonBlocking() always return 'false' (no data
* was lost), so it can also be connected to modules which retry sending data for fault recovery
* until they succeed.
*/
template<typename UserType>
class ConstantAccessor : public ChimeraTK::NDRegisterAccessor<UserType> {
public:
......@@ -25,7 +34,10 @@ namespace ChimeraTK {
ChimeraTK::NDRegisterAccessor<UserType>::buffer_2D[0] = _value;
if(TransferElement::_accessModeFlags.has(AccessMode::wait_for_new_data)) {
TransferElement::_readQueue = cppext::future_queue<void>(0);
// This implementation does not have a data transport queue, hence _readQueue
// is not set up as a continuation. We directly make it a cppext::future_queue
TransferElement::_readQueue = cppext::future_queue<void>(3); // minimum required length is 2
// Push once into the queue for the initial value.
TransferElement::_readQueue.push();
}
}
......@@ -34,15 +46,22 @@ namespace ChimeraTK {
void doReadTransferSynchronously() override {}
void doPostRead(TransferType /*type*/, bool /* hasNewData */) override {
ChimeraTK::NDRegisterAccessor<UserType>::buffer_2D[0] = _value;
void doPostRead(TransferType /*type*/, bool updateUserBuffer) override {
// - updateUserBuffer is false for further calls to readLatest with wait_for_new_data.
// In this case the user buffer must not be touched.
// - updateUserBuffer is true for all calls without wait_for_new_data. The user buffer must
// be overwritten.
if(updateUserBuffer) {
ChimeraTK::NDRegisterAccessor<UserType>::buffer_2D[0] = _value;
// It is OK to generate the version number just here since the read transfer is empty anyway.
this->_versionNumber = {};
this->_dataValidity = DataValidity::ok; // the constant is always valid by definiton
}
}
bool doWriteTransfer(ChimeraTK::VersionNumber /*versionNumber*/ = {}) override { return true; }
bool doWriteTransfer(ChimeraTK::VersionNumber /*versionNumber*/ = {}) override { return false; }
bool mayReplaceOther(const boost::shared_ptr<ChimeraTK::TransferElement const>&) const override {
return false; /// @todo implement properly?
}
bool mayReplaceOther(const boost::shared_ptr<ChimeraTK::TransferElement const>&) const override { return false; }
bool isReadOnly() const override { return false; }
......@@ -56,15 +75,10 @@ namespace ChimeraTK {
std::list<boost::shared_ptr<ChimeraTK::TransferElement>> getInternalElements() override { return {}; }
void interrupt() override { TransferElement::interrupt_impl(this->_readQueue); }
protected:
std::vector<UserType> _value;
bool firstRead{true};
bool isInterrupted{false};
boost::promise<void> promise;
VersionNumber versionNumber{nullptr};
};
} /* namespace ChimeraTK */
......
......@@ -37,6 +37,8 @@ namespace ChimeraTK {
void doPreWrite(TransferType type, VersionNumber versionNumber) override;
void doPostWrite(TransferType type, VersionNumber versionNumber) override;
void setOwner(EntityOwner* owner);
void doPostRead(TransferType type, bool hasNewData) override;
......
......@@ -99,6 +99,18 @@ namespace ChimeraTK {
}
}
template<typename UserType>
void ExceptionHandlingDecorator<UserType>::doPostWrite(TransferType type, VersionNumber versionNumber) {
try {
if(transferAllowed) {
ChimeraTK::NDRegisterAccessorDecorator<UserType>::doPostWrite(type, versionNumber);
}
}
catch(ChimeraTK::runtime_error& e) {
deviceModule.reportException(e.what());
}
}
template<typename UserType>
void ExceptionHandlingDecorator<UserType>::setOwner(EntityOwner* owner) {
_owner = owner;
......
......@@ -80,6 +80,7 @@ namespace ChimeraTK {
VariableNetworkNode::VariableNetworkNode(VariableNetworkNode& nodeToTrigger, int)
: pdata(boost::make_shared<VariableNetworkNode_data>()) {
pdata->type = NodeType::TriggerReceiver;
pdata->mode = UpdateMode::push;
pdata->direction = {VariableDirection::consuming, false};
pdata->nodeToTrigger = nodeToTrigger;
pdata->name = "trigger:" + nodeToTrigger.getName();
......
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