LCOV - code coverage report
Current view: top level - cmdlib/src - CommandFacility.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 37.7 % 53 20
Test Date: 2025-12-21 13:07:08 Functions: 60.0 % 5 3

            Line data    Source code
       1              : /**
       2              :  * @file CommandFacility.cpp CommandFacility base implementation
       3              :  *
       4              :  * This is part of the DUNE DAQ Application Framework, copyright 2020.
       5              :  * Licensing/copyright details are in the COPYING file that you should have
       6              :  * received with this code.
       7              :  */
       8              : #include "cmdlib/CommandFacility.hpp"
       9              : #include "cmdlib/Issues.hpp"
      10              : #include "logging/Logging.hpp"
      11              : 
      12              : #include <future>
      13              : #include <functional>
      14              : #include <utility>
      15              : #include <atomic>
      16              : #include <chrono>
      17              : #include <string>
      18              : 
      19              : using namespace dunedaq::cmdlib;
      20              : 
      21           10 : CommandFacility::~CommandFacility() 
      22              : {
      23           10 :   if (m_active.load()) {
      24            6 :     m_active.store(false);
      25            6 :     if(m_executor.joinable()) {
      26            6 :       m_executor.join();
      27              :     } 
      28              :   }
      29           10 : }
      30              : 
      31              : void 
      32            6 : CommandFacility::set_commanded(CommandedObject& commanded, std::string name) 
      33              : {
      34            6 :   if (m_commanded_object == nullptr) {
      35            6 :     m_name = name;
      36            6 :     m_commanded_object = &commanded;
      37            6 :     m_command_callback = std::bind(&CommandFacility::handle_command, this, std::placeholders::_1, std::placeholders::_2);
      38            6 :     m_active.store(true);
      39            6 :     m_executor = std::thread(&CommandFacility::executor, this);
      40              :   } else {
      41            0 :     ers::error(CommandFacilityInitialization(ERS_HERE, "set_commanded shall be called once."));
      42              :   }
      43            6 : }
      44              : 
      45              : void 
      46            0 : CommandFacility::execute_command(const cmdobj_t& cmd, cmd::CommandReply meta)
      47              : {
      48            0 :   auto execfut = std::async(std::launch::deferred, m_command_callback, std::move(cmd), std::move(meta));
      49            0 :   m_completion_queue.push(std::move(execfut));
      50            0 : }
      51              : 
      52              : void
      53            0 : CommandFacility::handle_command(const cmdobj_t& cmd, cmd::CommandReply meta)
      54              : {
      55            0 :   try {
      56            0 :     m_commanded_object->execute(cmd);
      57            0 :     meta.success = true;
      58            0 :     meta.result = "OK";
      59            0 :     meta.appname = m_name;
      60            0 :   } catch (const ers::Issue& ei ) {
      61            0 :     meta.success = false;
      62            0 :     meta.result = ei.what();
      63            0 :     meta.appname = m_name;
      64            0 :     ers::error(CommandExecutionFailed(ERS_HERE, "Caught ers::Issue", ei));
      65            0 :   } catch (const std::exception& exc) {
      66            0 :     meta.success = false;
      67            0 :     meta.result = exc.what();
      68            0 :     meta.appname = m_name;
      69            0 :     ers::error(CommandExecutionFailed(ERS_HERE, "Caught std::exception", exc));
      70            0 :   } catch (...) {  // NOLINT JCF Jan-27-2021 violates letter of the law but not the spirit
      71            0 :     meta.success = false;
      72            0 :     meta.result = "Caught unknown exception";
      73            0 :     meta.appname = m_name;
      74            0 :     ers::error(CommandExecutionFailed(ERS_HERE, meta.result));
      75            0 :   }
      76            0 :   completion_callback(cmd, meta);
      77            0 : }
      78              : 
      79              : void
      80            6 : CommandFacility::executor()
      81              : {
      82            6 :   std::future<void> fut; 
      83           15 :   while (m_active.load()) {
      84            9 :     if (m_completion_queue.empty()) {
      85            9 :       std::this_thread::sleep_for(std::chrono::milliseconds(10));
      86              :     } else {
      87            0 :       bool success = m_completion_queue.try_pop(fut);
      88            0 :       if (!success) {
      89            0 :         ers::error(CompletionQueueIssue(ERS_HERE, "Can't get from completion queue.")); 
      90              :       } else {
      91            0 :         fut.wait(); // trigger execution
      92              :       }  
      93              :     }
      94              :   }
      95            6 : }
        

Generated by: LCOV version 2.0-1