#ifndef HV_EVENT_LOOP_THREAD_HPP_ #define HV_EVENT_LOOP_THREAD_HPP_ #include #include "hlog.h" #include "EventLoop.h" namespace hv { class EventLoopThread : public Status { public: // Return 0 means OK, other failed. typedef std::function Functor; EventLoopThread(EventLoopPtr loop = NULL) { setStatus(kInitializing); loop_ = loop ? loop : std::make_shared(); setStatus(kInitialized); } ~EventLoopThread() { stop(); join(); } const EventLoopPtr& loop() { return loop_; } hloop_t* hloop() { return loop_->loop(); } bool isRunning() { return loop_->isRunning(); } // @param wait_thread_started: if ture this method will block until loop_thread started. // @param pre: This functor will be executed when loop_thread started. // @param post:This Functor will be executed when loop_thread stopped. void start(bool wait_thread_started = true, Functor pre = Functor(), Functor post = Functor()) { if (status() >= kStarting && status() < kStopped) return; setStatus(kStarting); thread_ = std::make_shared(&EventLoopThread::loop_thread, this, pre, post); if (wait_thread_started) { while (loop_->status() < kRunning) { hv_delay(1); } } } // @param wait_thread_started: if ture this method will block until loop_thread stopped. // stop thread-safe void stop(bool wait_thread_stopped = false) { if (status() < kStarting || status() >= kStopping) return; setStatus(kStopping); long loop_tid = loop_->tid(); loop_->stop(); if (wait_thread_stopped) { if (hv_gettid() == loop_tid) return; join(); } } // @brief join loop_thread // @note destructor will join loop_thread if you forget to call this method. void join() { if (thread_ && thread_->joinable()) { thread_->join(); thread_ = NULL; } } private: void loop_thread(const Functor& pre, const Functor& post) { hlogi("EventLoopThread started, tid=%ld", hv_gettid()); setStatus(kStarted); if (pre) { loop_->queueInLoop([this, pre]{ if (pre() != 0) { loop_->stop(); } }); } loop_->run(); assert(loop_->isStopped()); if (post) { post(); } setStatus(kStopped); hlogi("EventLoopThread stopped, tid=%ld", hv_gettid()); } private: EventLoopPtr loop_; std::shared_ptr thread_; }; typedef std::shared_ptr EventLoopThreadPtr; } #endif // HV_EVENT_LOOP_THREAD_HPP_