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-11-09 02:10:49 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             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #ifndef __WORK_PROCESSOR_INL_H__
       7             : #define __WORK_PROCESSOR_INL_H__
       8             : 
       9             : #include <vector>
      10             : #include <boost/function.hpp>
      11             : #include <boost/bind/bind.hpp>
      12             : #include <boost/shared_ptr.hpp>
      13             : #include <boost/scoped_ptr.hpp>
      14             : #include <boost/assign/list_of.hpp>
      15             : #include <boost/type_traits.hpp>
      16             : #include <boost/mpl/assert.hpp>
      17             : #include <boost/tuple/tuple.hpp>
      18             : #include <limits>
      19             : #include <sstream>
      20             : #include "base/task.h"
      21             : 
      22             : using namespace boost::placeholders;
      23             : 
      24             : struct PipelineWorker : public Task {
      25      222143 :     PipelineWorker(int tid, int tinst, boost::function<bool(void)> runner) :
      26      222143 :         Task(tid,tinst), runner_(runner) {}
      27             : 
      28      221742 :     bool Run() {
      29      221742 :         if (!(runner_)()) return false;
      30      221596 :         return true;
      31             :     }
      32           0 :     std::string Description() const { return "PipelineWorker"; }
      33             : private:
      34             :     const boost::function<bool(void)> runner_;
      35             : };
      36             : 
      37             : template<typename InputT, typename SubResultT, typename ExternalT>
      38             : class WorkProcessor : public ExternalProcIf<ExternalT> {
      39             : public:
      40             :     typedef boost::function<ExternalBase::Efn(
      41             :         uint32_t inst,
      42             :         const std::vector<ExternalT*> & exts, // Info for previous steps of this stage
      43             :         const InputT & inp, // Info from previous stage
      44             :         SubResultT & subRes // Access to final result of this instance
      45             :         )> ExecuteFn;
      46             : 
      47      109931 :     WorkProcessor(uint32_t stage, ExecuteFn efn, FinFn finFn, const InputT & inp,
      48             :         uint32_t inst, int tid, int tinst) :
      49      109920 :             stage_(stage),
      50      109920 :             finFn_(finFn),
      51      109878 :             efn_(efn),
      52      109843 :             inp_(inp),
      53      109835 :             finished_(false),
      54      109835 :             running_(false),
      55      109835 :             inst_(inst),
      56      109835 :             tid_(tid),
      57      109835 :             tinst_(tinst),
      58      109835 :             w_(new PipelineWorker(tid_, tinst_,
      59             :                 boost::bind(&WorkProcessor<InputT,SubResultT,ExternalT>::Runner,
      60      219774 :                 this))) {
      61      109652 :         res_.reset(new SubResultT);
      62      109786 :     }
      63             : 
      64      110046 :     void Start() {
      65      110046 :         TaskScheduler *scheduler = TaskScheduler::GetInstance();
      66      110042 :         scheduler->Enqueue(w_);
      67      110050 :     }   
      68             : 
      69      109517 :     boost::shared_ptr<SubResultT> Result() const {
      70      109517 :         if (!finished_) return boost::shared_ptr<SubResultT>();
      71      109517 :         return res_;
      72             :     }
      73             : 
      74      108823 :     void Release() {
      75      108823 :         assert(finished_);
      76      108823 :         res_.reset();
      77      109754 :     }
      78             :     
      79         252 :     std::string Key() const {
      80         252 :         std::stringstream keystr;
      81         252 :         keystr << "PROC-STAGE:" << stage_ << "-INST:" << inst_ <<
      82         252 :                 "-STEP:" << externals_.size();
      83         504 :         return keystr.str();
      84         252 :     }
      85             : 
      86             : private:
      87             :     uint32_t stage_;
      88             :     FinFn finFn_;
      89             :     const ExecuteFn efn_;
      90             :     const InputT & inp_;
      91             :     boost::shared_ptr<SubResultT> res_;
      92             :     std::vector<ExternalT*> externals_;
      93             :     bool finished_;
      94             :     bool running_;
      95             :     const uint32_t inst_;
      96             :     const int tid_;
      97             :     const int tinst_;
      98             :     PipelineWorker * const w_;
      99             : 
     100      109484 :     void WorkDone(bool ret_code) {
     101      109484 :         for (typename std::vector<ExternalT*>::iterator it = externals_.begin();
     102      219219 :                 it!=externals_.end(); it++) {
     103      109720 :             delete (*it);
     104             :         }
     105      109164 :         finished_ = true;
     106      109164 :         finFn_(ret_code);
     107      109950 :     }
     108             : 
     109      219548 :     bool Runner(void) {
     110      219548 :         running_ = true;
     111      219548 :         ExternalBase::Efn fn = (efn_)(inst_, externals_, inp_, *res_);
     112      219825 :         running_ = false;
     113      219825 :         if (fn.empty()) {
     114      109656 :             WorkDone(true); 
     115             :         } else {
     116      110299 :             if (fn == &ExternalBase::Incomplete) return false;
     117             : 
     118      110336 :             if (!fn(this)) {
     119           0 :                 WorkDone(false);
     120             :             }
     121             :         }
     122      220274 :         return true;
     123      220274 :     }
     124             : 
     125      110358 :     void Response(std::unique_ptr<ExternalT> resp) {
     126      110358 :         ExternalT * msg = resp.get();
     127      110431 :         resp.release();
     128      110425 :         externals_.push_back(msg);
     129      110426 :         assert(!running_);
     130      110426 :         PipelineWorker *w = new PipelineWorker(tid_, tinst_,
     131             :                 boost::bind(&WorkProcessor<InputT,SubResultT,ExternalT>::Runner,
     132             :                 this));
     133      110421 :         TaskScheduler *scheduler = TaskScheduler::GetInstance();
     134      110419 :         scheduler->Enqueue(w);        
     135      110448 :     }
     136             : };
     137             : 
     138             : template <typename InputT, typename ResultT>
     139             : struct WorkStageIf {
     140             :     virtual void Start(uint32_t stage, FinFn finFn, const boost::shared_ptr<InputT> & inp) = 0;
     141             :     virtual boost::shared_ptr<ResultT> Result() const = 0;
     142             :     virtual void Release() = 0;
     143        2054 :     virtual ~WorkStageIf() {}
     144             : };
     145             : #endif

Generated by: LCOV version 1.14