From 075359c4dda650625b78ef1414cf38cfa0cfa17b Mon Sep 17 00:00:00 2001
From: Martin Hierholzer <martin.hierholzer@desy.de>
Date: Wed, 8 Feb 2017 17:15:21 +0100
Subject: [PATCH] proper readAny implementation for the VariableGroup based on
 the new DeviceAccess features

---
 include/Accessor.h   |  7 +++++++
 src/VariableGroup.cc | 20 +++++++++++---------
 2 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/include/Accessor.h b/include/Accessor.h
index f3c24f23..98fb906f 100644
--- a/include/Accessor.h
+++ b/include/Accessor.h
@@ -83,6 +83,9 @@ namespace ChimeraTK {
         return node;
       }
       
+      /** Return the implementation as a TransferElement */
+      virtual boost::shared_ptr<TransferElement> getTransferElement() = 0;
+      
       /** Explicitly return the node */
       VariableNetworkNode& getNode() {
         return node;
@@ -158,6 +161,10 @@ namespace ChimeraTK {
         node = VariableNetworkNode(*this);
       }
 
+      boost::shared_ptr<TransferElement> getTransferElement() override {
+        return boost::static_pointer_cast<TransferElement>(impl);
+      }
+
     protected:
 
       Module *_owner;
diff --git a/src/VariableGroup.cc b/src/VariableGroup.cc
index b20be8b5..60d647a7 100644
--- a/src/VariableGroup.cc
+++ b/src/VariableGroup.cc
@@ -16,18 +16,20 @@ namespace ChimeraTK {
 /*********************************************************************************************************************/
   
   void VariableGroup::readAny() {
-    bool gotUpdate = false;
     auto accessorList = getAccessorListRecursive();
-    while(!gotUpdate) {     /// @todo TODO FIXME make proper blocking implementation
-      boost::this_thread::yield();
-      boost::this_thread::interruption_point();
-      
-      for(auto accessor : accessorList) {       // @todo FIXME make sure no submodule is accessing the variables itself... (e.g. by forcing all submodules to be a VariablGroup and not e.g. an ApplicationModule)
-        if(accessor->getUpdateMode() == UpdateMode::push) {
-          if(accessor->readNonBlocking()) gotUpdate = true;
-        }
+
+    // put push-type transfer elements into a list suitable for TransferElement::readAny()
+    std::list<std::reference_wrapper<TransferElement>> transferElementList;
+    for(auto &accessor : accessorList) {
+      if(accessor->getUpdateMode() == UpdateMode::push) {
+        transferElementList.emplace_back(*(accessor->getTransferElement()));
       }
     }
+    
+    // wait until one of the push-type accessors receives an update
+    mtca4u::TransferElement::readAny(transferElementList);
+    
+    // trigger read on the poll-type accessors
     for(auto accessor : accessorList) {
       if(accessor->getUpdateMode() == UpdateMode::poll) {
         accessor->read();
-- 
GitLab