Line data Source code
1 : /* 2 : * Copyright (c) 2014 Juniper Networks, Inc. All right reserved. 3 : * Copyright Contributors to the OpenSDN project 4 : */ 5 : #ifndef AGENT_OPER_INSTANCE_TASK_H__ 6 : #define AGENT_OPER_INSTANCE_TASK_H__ 7 : 8 : #include <queue> 9 : #include <boost/asio.hpp> 10 : #include <boost/function.hpp> 11 : #include "base/timer.h" 12 : #include "base/queue_task.h" 13 : #include "cmn/agent_signal.h" 14 : #include "cmn/agent_cmn.h" 15 : #include "db/db_entry.h" 16 : 17 : class EventManager; 18 : 19 : class InstanceTask { 20 : public: 21 : typedef boost::function<void(InstanceTask *task, const std::string &msg)> 22 : OnDataCallback; 23 : typedef boost::function<void(InstanceTask *task, 24 : const boost::system::error_code &ec)>OnExitCallback; 25 : 26 : InstanceTask(); 27 0 : virtual ~InstanceTask() {} 28 : 29 : virtual bool Run() = 0; 30 : virtual void Stop() = 0; 31 : virtual void Terminate() = 0; 32 : virtual bool IsSetup() = 0; 33 : 34 : // TODO reimplement instance_manager.cc to remove these two? 35 : virtual pid_t pid() const = 0; 36 : virtual const std::string &cmd() const = 0; 37 : 38 : virtual int cmd_type() const = 0; 39 : 40 0 : bool is_running() const { 41 0 : return is_running_; 42 : } 43 : 44 0 : time_t start_time() const { 45 0 : return start_time_; 46 : } 47 : 48 0 : void set_on_data_cb(OnDataCallback cb) { 49 0 : on_data_cb_ = cb; 50 0 : } 51 : 52 0 : void set_on_exit_cb(OnExitCallback cb) { 53 0 : on_exit_cb_ = cb; 54 0 : } 55 : 56 0 : int incr_reattempts() { 57 0 : return ++reattempts_; 58 : } 59 : 60 0 : int reattempts() { 61 0 : return reattempts_; 62 : } 63 : 64 : protected: 65 : bool is_running_; 66 : time_t start_time_; 67 : int reattempts_; 68 : OnDataCallback on_data_cb_; 69 : OnExitCallback on_exit_cb_; 70 : }; 71 : 72 : class InstanceTaskExecvp : public InstanceTask { 73 : public: 74 : static const size_t kBufLen = 4096; 75 : 76 : InstanceTaskExecvp(const std::string &name, const std::string &cmd, 77 : int cmd_type, EventManager *evm); 78 : 79 : bool Run(); 80 : void Stop(); 81 : void Terminate(); 82 : bool IsSetup(); 83 : 84 0 : pid_t pid() const { 85 0 : return pid_; 86 : } 87 : 88 0 : void set_cmd(std::string cmd) { 89 0 : cmd_ = cmd; 90 0 : } 91 : 92 0 : const std::string &cmd() const { 93 0 : return cmd_; 94 : } 95 : 96 0 : int cmd_type() const { 97 0 : return cmd_type_; 98 : } 99 : 100 0 : void set_pipe_stdout(bool pipe) { 101 0 : pipe_stdout_ = pipe; 102 0 : } 103 : 104 : 105 : private: 106 : void ReadData(const boost::system::error_code &ec, size_t read_bytes); 107 : 108 : const std::string name_; 109 : std::string cmd_; 110 : boost::asio::posix::stream_descriptor input_; 111 : bool setup_done_; // indicates whether errors_ has a valid descriptor or not 112 : char rx_buff_[kBufLen]; 113 : 114 : pid_t pid_; 115 : int cmd_type_; 116 : bool pipe_stdout_; 117 : }; 118 : 119 : class InstanceTaskMethod : public InstanceTask { 120 : public: 121 : pid_t pid() const { 122 : return 0; 123 : } 124 : }; 125 : 126 : class InstanceTaskQueue { 127 : public: 128 : typedef boost::function<void(InstanceTaskQueue *task_queue)> OnTimeoutCallback; 129 : InstanceTaskQueue(EventManager *evm); 130 : ~InstanceTaskQueue(); 131 : 132 : bool OnTimerTimeout(); 133 : void TimerErrorHandler(const std::string &name, std::string error); 134 : 135 0 : InstanceTask *Front() { return task_queue_.front(); } 136 0 : void Pop() { task_queue_.pop(); } 137 0 : bool Empty() { return task_queue_.empty(); } 138 0 : void Push(InstanceTask *task) { task_queue_.push(task); } 139 6 : int Size() { return task_queue_.size(); } 140 : void StartTimer(int time); 141 : void StopTimer(); 142 : void Clear(); 143 : 144 2 : void set_on_timeout_cb(OnTimeoutCallback cb) { 145 2 : on_timeout_cb_ = cb; 146 2 : } 147 : 148 : private: 149 : EventManager *evm_; 150 : Timer *timeout_timer_; 151 : std::queue<InstanceTask *> task_queue_; 152 : OnTimeoutCallback on_timeout_cb_; 153 : }; 154 : 155 : #endif // AGENT_OPER_INSTANCE_TASK_H__