EventLoopThread.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #ifndef HV_EVENT_LOOP_THREAD_HPP_
  2. #define HV_EVENT_LOOP_THREAD_HPP_
  3. #include <thread>
  4. #include "hlog.h"
  5. #include "EventLoop.h"
  6. namespace hv {
  7. class EventLoopThread : public Status {
  8. public:
  9. // Return 0 means OK, other failed.
  10. typedef std::function<int()> Functor;
  11. EventLoopThread(EventLoopPtr loop = NULL) {
  12. setStatus(kInitializing);
  13. loop_ = loop ? loop : std::make_shared<EventLoop>();
  14. setStatus(kInitialized);
  15. }
  16. ~EventLoopThread() {
  17. stop();
  18. join();
  19. }
  20. const EventLoopPtr& loop() {
  21. return loop_;
  22. }
  23. hloop_t* hloop() {
  24. return loop_->loop();
  25. }
  26. bool isRunning() {
  27. return loop_->isRunning();
  28. }
  29. // @param wait_thread_started: if ture this method will block until loop_thread started.
  30. // @param pre: This functor will be executed when loop_thread started.
  31. // @param post:This Functor will be executed when loop_thread stopped.
  32. void start(bool wait_thread_started = true,
  33. Functor pre = Functor(),
  34. Functor post = Functor()) {
  35. if (status() >= kStarting && status() < kStopped) return;
  36. setStatus(kStarting);
  37. thread_ = std::make_shared<std::thread>(&EventLoopThread::loop_thread, this, pre, post);
  38. if (wait_thread_started) {
  39. while (loop_->status() < kRunning) {
  40. hv_delay(1);
  41. }
  42. }
  43. }
  44. // @param wait_thread_started: if ture this method will block until loop_thread stopped.
  45. // stop thread-safe
  46. void stop(bool wait_thread_stopped = false) {
  47. if (status() < kStarting || status() >= kStopping) return;
  48. setStatus(kStopping);
  49. long loop_tid = loop_->tid();
  50. loop_->stop();
  51. if (wait_thread_stopped) {
  52. if (hv_gettid() == loop_tid) return;
  53. join();
  54. }
  55. }
  56. // @brief join loop_thread
  57. // @note destructor will join loop_thread if you forget to call this method.
  58. void join() {
  59. if (thread_ && thread_->joinable()) {
  60. thread_->join();
  61. thread_ = NULL;
  62. }
  63. }
  64. private:
  65. void loop_thread(const Functor& pre, const Functor& post) {
  66. hlogi("EventLoopThread started, tid=%ld", hv_gettid());
  67. setStatus(kStarted);
  68. if (pre) {
  69. loop_->queueInLoop([this, pre]{
  70. if (pre() != 0) {
  71. loop_->stop();
  72. }
  73. });
  74. }
  75. loop_->run();
  76. assert(loop_->isStopped());
  77. if (post) {
  78. post();
  79. }
  80. setStatus(kStopped);
  81. hlogi("EventLoopThread stopped, tid=%ld", hv_gettid());
  82. }
  83. private:
  84. EventLoopPtr loop_;
  85. std::shared_ptr<std::thread> thread_;
  86. };
  87. typedef std::shared_ptr<EventLoopThread> EventLoopThreadPtr;
  88. }
  89. #endif // HV_EVENT_LOOP_THREAD_HPP_