LCOV - code coverage report
Current view: top level - cmdlib/src - CommandFacility.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 38.9 % 54 21
Test Date: 2026-10-11 15:05:20 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 <atomic>
      13              : #include <chrono>
      14              : #include <functional>
      15              : #include <future>
      16              : #include <string>
      17              : #include <utility>
      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 =
      38            6 :       std::bind(&CommandFacility::handle_command, this, std::placeholders::_1, std::placeholders::_2);
      39            6 :     m_active.store(true);
      40            6 :     m_executor = std::thread(&CommandFacility::executor, this);
      41              :   } else {
      42            0 :     ers::error(CommandFacilityInitialization(ERS_HERE, "set_commanded shall be called once."));
      43              :   }
      44            6 : }
      45              : 
      46              : void
      47            0 : CommandFacility::execute_command(const cmdobj_t& cmd, cmd::CommandReply meta)
      48              : {
      49            0 :   auto execfut = std::async(std::launch::deferred, m_command_callback, std::move(cmd), std::move(meta));
      50            0 :   m_completion_queue.push(std::move(execfut));
      51            0 : }
      52              : 
      53              : void
      54            0 : CommandFacility::handle_command(const cmdobj_t& cmd, cmd::CommandReply meta)
      55              : {
      56            0 :   try {
      57            0 :     m_commanded_object->execute(cmd);
      58            0 :     meta.success = true;
      59            0 :     meta.result = "OK";
      60            0 :     meta.appname = m_name;
      61            0 :   } catch (const ers::Issue& ei) {
      62            0 :     meta.success = false;
      63            0 :     meta.result = ei.what();
      64            0 :     meta.appname = m_name;
      65            0 :     ers::error(CommandExecutionFailed(ERS_HERE, "Caught ers::Issue", ei));
      66            0 :   } catch (const std::exception& exc) {
      67            0 :     meta.success = false;
      68            0 :     meta.result = exc.what();
      69            0 :     meta.appname = m_name;
      70            0 :     ers::error(CommandExecutionFailed(ERS_HERE, "Caught std::exception", exc));
      71            0 :   } catch (...) { // NOLINT JCF Jan-27-2021 violates letter of the law but not the spirit
      72            0 :     meta.success = false;
      73            0 :     meta.result = "Caught unknown exception";
      74            0 :     meta.appname = m_name;
      75            0 :     ers::error(CommandExecutionFailed(ERS_HERE, meta.result));
      76            0 :   }
      77            0 :   completion_callback(cmd, meta);
      78            0 : }
      79              : 
      80              : void
      81            6 : CommandFacility::executor()
      82              : {
      83            6 :   std::future<void> fut;
      84           14 :   while (m_active.load()) {
      85            8 :     if (m_completion_queue.empty()) {
      86            8 :       std::this_thread::sleep_for(std::chrono::milliseconds(10));
      87              :     } else {
      88            0 :       bool success = m_completion_queue.try_pop(fut);
      89            0 :       if (!success) {
      90            0 :         ers::error(CompletionQueueIssue(ERS_HERE, "Can't get from completion queue."));
      91              :       } else {
      92            0 :         fut.wait(); // trigger execution
      93              :       }
      94              :     }
      95              :   }
      96            6 : }
        

Generated by: LCOV version 2.0-1