mirror of
				https://gitee.com/jiuyilian/embedded-framework.git
				synced 2025-10-24 18:20:15 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			116 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			116 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #ifndef HV_EVENT_LOOP_THREAD_HPP_
 | |
| #define HV_EVENT_LOOP_THREAD_HPP_
 | |
| 
 | |
| #include <thread>
 | |
| 
 | |
| #include "hlog.h"
 | |
| 
 | |
| #include "EventLoop.h"
 | |
| 
 | |
| namespace hv {
 | |
| 
 | |
| class EventLoopThread : public Status {
 | |
| public:
 | |
|     // Return 0 means OK, other failed.
 | |
|     typedef std::function<int()> Functor;
 | |
| 
 | |
|     EventLoopThread(EventLoopPtr loop = NULL) {
 | |
|         setStatus(kInitializing);
 | |
|         loop_ = loop ? loop : std::make_shared<EventLoop>();
 | |
|         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<std::thread>(&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<std::thread> thread_;
 | |
| };
 | |
| 
 | |
| typedef std::shared_ptr<EventLoopThread> EventLoopThreadPtr;
 | |
| 
 | |
| }
 | |
| 
 | |
| #endif // HV_EVENT_LOOP_THREAD_HPP_
 | 
