LCOV - code coverage report
Current view: top level - root/contrail/src/contrail-common/base - work_processor-inl.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 63 65 96.9 %
Date: 2026-08-03 02:19:58 Functions: 27 33 81.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #ifndef __WORK_PROCESSOR_INL_H__
       6             : #define __WORK_PROCESSOR_INL_H__
       7             : 
       8             : #include <vector>
       9             : #include <boost/function.hpp>
      10             : #include <boost/bind/bind.hpp>
      11             : #include <boost/shared_ptr.hpp>
      12             : #include <boost/scoped_ptr.hpp>
      13             : #include <boost/assign/list_of.hpp>
      14             : #include <boost/type_traits.hpp>
      15             : #include <boost/mpl/assert.hpp>
      16             : #include <boost/tuple/tuple.hpp>
      17             : #include <limits>
      18             : #include <sstream>
      19             : #include "base/task.h"
      20             : 
      21             : using namespace boost::placeholders;
      22             : 
      23             : struct PipelineWorker : public Task {
      24      222013 :     PipelineWorker(int tid, int tinst, boost::function<bool(void)> runner) :
      25      222013 :         Task(tid,tinst), runner_(runner) {}
      26             : 
      27      221240 :     bool Run() {
      28      221240 :         if (!(runner_)()) return false;
      29      220994 :         return true;
      30             :     }
      31           0 :     std::string Description() const { return "PipelineWorker"; }
      32             : private:
      33             :     const boost::function<bool(void)> runner_;
      34             : };
      35             : 
      36             : template<typename InputT, typename SubResultT, typename ExternalT>
      37             : class WorkProcessor : public ExternalProcIf<ExternalT> {
      38             : public:
      39             :     typedef boost::function<ExternalBase::Efn(
      40             :         uint32_t inst,
      41             :         const std::vector<ExternalT*> & exts, // Info for previous steps of this stage
      42             :         const InputT & inp, // Info from previous stage
      43             :         SubResultT & subRes // Access to final result of this instance
      44             :         )> ExecuteFn;
      45             : 
      46      109874 :     WorkProcessor(uint32_t stage, ExecuteFn efn, FinFn finFn, const InputT & inp,
      47             :         uint32_t inst, int tid, int tinst) :
      48      109862 :             stage_(stage),
      49      109862 :             finFn_(finFn),
      50      109829 :             efn_(efn),
      51      109815 :             inp_(inp),
      52      109740 :             finished_(false),
      53      109740 :             running_(false),
      54      109740 :             inst_(inst),
      55      109740 :             tid_(tid),
      56      109740 :             tinst_(tinst),
      57      109740 :             w_(new PipelineWorker(tid_, tinst_,
      58             :                 boost::bind(&WorkProcessor<InputT,SubResultT,ExternalT>::Runner,
      59      219689 :                 this))) {
      60      109737 :         res_.reset(new SubResultT);
      61      109707 :     }
      62             : 
      63      110003 :     void Start() {
      64      110003 :         TaskScheduler *scheduler = TaskScheduler::GetInstance();
      65      110002 :         scheduler->Enqueue(w_);
      66      110011 :     }   
      67             : 
      68      109535 :     boost::shared_ptr<SubResultT> Result() const {
      69      109535 :         if (!finished_) return boost::shared_ptr<SubResultT>();
      70      109535 :         return res_;
      71             :     }
      72             : 
      73      109342 :     void Release() {
      74      109342 :         assert(finished_);
      75      109342 :         res_.reset();
      76      109788 :     }
      77             :     
      78         254 :     std::string Key() const {
      79         254 :         std::stringstream keystr;
      80         254 :         keystr << "PROC-STAGE:" << stage_ << "-INST:" << inst_ <<
      81         254 :                 "-STEP:" << externals_.size();
      82         508 :         return keystr.str();
      83         254 :     }
      84             : 
      85             : private:
      86             :     uint32_t stage_;
      87             :     FinFn finFn_;
      88             :     const ExecuteFn efn_;
      89             :     const InputT & inp_;
      90             :     boost::shared_ptr<SubResultT> res_;
      91             :     std::vector<ExternalT*> externals_;
      92             :     bool finished_;
      93             :     bool running_;
      94             :     const uint32_t inst_;
      95             :     const int tid_;
      96             :     const int tinst_;
      97             :     PipelineWorker * const w_;
      98             : 
      99      109182 :     void WorkDone(bool ret_code) {
     100      109182 :         for (typename std::vector<ExternalT*>::iterator it = externals_.begin();
     101      218528 :                 it!=externals_.end(); it++) {
     102      109469 :             delete (*it);
     103             :         }
     104      109031 :         finished_ = true;
     105      109031 :         finFn_(ret_code);
     106      109786 :     }
     107             : 
     108      218959 :     bool Runner(void) {
     109      218959 :         running_ = true;
     110      218959 :         ExternalBase::Efn fn = (efn_)(inst_, externals_, inp_, *res_);
     111      219096 :         running_ = false;
     112      219096 :         if (fn.empty()) {
     113      109266 :             WorkDone(true); 
     114             :         } else {
     115      110218 :             if (fn == &ExternalBase::Incomplete) return false;
     116             : 
     117      110209 :             if (!fn(this)) {
     118           0 :                 WorkDone(false);
     119             :             }
     120             :         }
     121      219934 :         return true;
     122      219934 :     }
     123             : 
     124      110375 :     void Response(std::unique_ptr<ExternalT> resp) {
     125      110375 :         ExternalT * msg = resp.get();
     126      110379 :         resp.release();
     127      110378 :         externals_.push_back(msg);
     128      110367 :         assert(!running_);
     129      110367 :         PipelineWorker *w = new PipelineWorker(tid_, tinst_,
     130             :                 boost::bind(&WorkProcessor<InputT,SubResultT,ExternalT>::Runner,
     131             :                 this));
     132      110371 :         TaskScheduler *scheduler = TaskScheduler::GetInstance();
     133      110369 :         scheduler->Enqueue(w);        
     134      110423 :     }
     135             : };
     136             : 
     137             : template <typename InputT, typename ResultT>
     138             : struct WorkStageIf {
     139             :     virtual void Start(uint32_t stage, FinFn finFn, const boost::shared_ptr<InputT> & inp) = 0;
     140             :     virtual boost::shared_ptr<ResultT> Result() const = 0;
     141             :     virtual void Release() = 0;
     142        2063 :     virtual ~WorkStageIf() {}
     143             : };
     144             : #endif

Generated by: LCOV version 1.14