1
0

EventLoopThread.h 2.6 KB

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