NVMeBasicContext: Poll all sensors each polling interval

Rework the polling protocol so that the completion of polling sensor N
invokes polling of sensor N+1 for the given context.

The timer is retained in order to trigger polling the initial sensor.

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Change-Id: I599547c8c790905549c0cad9fbfbe63cf6930de4
diff --git a/src/NVMeBasicContext.cpp b/src/NVMeBasicContext.cpp
index dacac26..c755e23 100644
--- a/src/NVMeBasicContext.cpp
+++ b/src/NVMeBasicContext.cpp
@@ -244,19 +244,22 @@
     thread.detach();
 }
 
-void NVMeBasicContext::readAndProcessNVMeSensor()
+void NVMeBasicContext::readAndProcessNVMeSensor(
+    std::list<std::shared_ptr<NVMeSensor>>::iterator iter)
 {
-    if (sensors.empty())
+    if (iter == sensors.end())
     {
+        this->pollNVMeDevices();
         return;
     }
 
-    std::shared_ptr<NVMeSensor>& sensor = sensors.front();
+    std::shared_ptr<NVMeSensor> sensor = *iter++;
 
     if (!sensor->readingStateGood())
     {
         sensor->markAvailable(false);
         sensor->updateValue(std::numeric_limits<double>::quiet_NaN());
+        readAndProcessNVMeSensor(iter);
         return;
     }
 
@@ -314,8 +317,8 @@
             response->prepare(len);
             return len;
         },
-        [self{shared_from_this()},
-         response](const boost::system::error_code& ec, std::size_t length) {
+        [self{shared_from_this()}, iter, sensor, response](
+            const boost::system::error_code& ec, std::size_t length) mutable {
             if (ec)
             {
                 std::cerr << "Got error reading basic query: " << ec << "\n";
@@ -340,29 +343,34 @@
             std::vector<char> data(response->size());
             is.read(data.data(), response->size());
 
-            self->processResponse(data.data(), data.size());
+            /* Update the sensor */
+            self->processResponse(sensor, data.data(), data.size());
+
+            /* Enqueue processing of the next sensor */
+            self->readAndProcessNVMeSensor(iter);
         });
 }
 
 void NVMeBasicContext::pollNVMeDevices()
 {
+    auto scan = sensors.begin();
+
     scanTimer.expires_from_now(boost::posix_time::seconds(1));
-    scanTimer.async_wait(
-        [self{shared_from_this()}](const boost::system::error_code errorCode) {
-            if (errorCode == boost::asio::error::operation_aborted)
-            {
-                return;
-            }
+    scanTimer.async_wait([self{shared_from_this()},
+                          scan](const boost::system::error_code errorCode) {
+        if (errorCode == boost::asio::error::operation_aborted)
+        {
+            return;
+        }
 
-            if (errorCode)
-            {
-                std::cerr << errorCode.message() << "\n";
-                return;
-            }
+        if (errorCode)
+        {
+            std::cerr << errorCode.message() << "\n";
+            return;
+        }
 
-            self->readAndProcessNVMeSensor();
-            self->pollNVMeDevices();
-        });
+        self->readAndProcessNVMeSensor(scan);
+    });
 }
 
 static double getTemperatureReading(int8_t reading)
@@ -378,7 +386,8 @@
     return reading;
 }
 
-void NVMeBasicContext::processResponse(void* msg, size_t len)
+void NVMeBasicContext::processResponse(std::shared_ptr<NVMeSensor>& sensor,
+                                       void* msg, size_t len)
 {
     if (msg == nullptr)
     {
@@ -393,8 +402,6 @@
     }
 
     uint8_t* messageData = static_cast<uint8_t*>(msg);
-
-    std::shared_ptr<NVMeSensor> sensor = sensors.front();
     double value = getTemperatureReading(messageData[2]);
 
     if (std::isfinite(value))
@@ -406,7 +413,4 @@
         sensor->markAvailable(false);
         sensor->incrementError();
     }
-
-    sensors.pop_front();
-    sensors.emplace_back(sensor);
 }