message_pump_libevent.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_LIBEVENT_H_
  5. #define BASE_MESSAGE_LOOP_MESSAGE_PUMP_LIBEVENT_H_
  6. #include <memory>
  7. #include "base/compiler_specific.h"
  8. #include "base/macros.h"
  9. #include "base/message_loop/message_pump.h"
  10. #include "base/message_loop/watchable_io_message_pump_posix.h"
  11. #include "base/threading/thread_checker.h"
  12. // Declare structs we need from libevent.h rather than including it
  13. struct event_base;
  14. struct event;
  15. namespace base {
  16. // Class to monitor sockets and issue callbacks when sockets are ready for I/O
  17. // TODO(dkegel): add support for background file IO somehow
  18. class BASE_EXPORT MessagePumpLibevent : public MessagePump,
  19. public WatchableIOMessagePumpPosix {
  20. public:
  21. class FdWatchController : public FdWatchControllerInterface {
  22. public:
  23. explicit FdWatchController(const Location& from_here);
  24. // Implicitly calls StopWatchingFileDescriptor.
  25. ~FdWatchController() override;
  26. // FdWatchControllerInterface:
  27. bool StopWatchingFileDescriptor() override;
  28. private:
  29. friend class MessagePumpLibevent;
  30. friend class MessagePumpLibeventTest;
  31. // Called by MessagePumpLibevent.
  32. void Init(std::unique_ptr<event> e);
  33. // Used by MessagePumpLibevent to take ownership of |event_|.
  34. std::unique_ptr<event> ReleaseEvent();
  35. void set_pump(MessagePumpLibevent* pump) { pump_ = pump; }
  36. MessagePumpLibevent* pump() const { return pump_; }
  37. void set_watcher(FdWatcher* watcher) { watcher_ = watcher; }
  38. void OnFileCanReadWithoutBlocking(int fd, MessagePumpLibevent* pump);
  39. void OnFileCanWriteWithoutBlocking(int fd, MessagePumpLibevent* pump);
  40. std::unique_ptr<event> event_;
  41. MessagePumpLibevent* pump_ = nullptr;
  42. FdWatcher* watcher_ = nullptr;
  43. // If this pointer is non-NULL, the pointee is set to true in the
  44. // destructor.
  45. bool* was_destroyed_ = nullptr;
  46. DISALLOW_COPY_AND_ASSIGN(FdWatchController);
  47. };
  48. MessagePumpLibevent();
  49. ~MessagePumpLibevent() override;
  50. bool WatchFileDescriptor(int fd,
  51. bool persistent,
  52. int mode,
  53. FdWatchController* controller,
  54. FdWatcher* delegate);
  55. // MessagePump methods:
  56. void Run(Delegate* delegate) override;
  57. void Quit() override;
  58. void ScheduleWork() override;
  59. void ScheduleDelayedWork(const TimeTicks& delayed_work_time) override;
  60. private:
  61. friend class MessagePumpLibeventTest;
  62. // Risky part of constructor. Returns true on success.
  63. bool Init();
  64. // Called by libevent to tell us a registered FD can be read/written to.
  65. static void OnLibeventNotification(int fd, short flags, void* context);
  66. // Unix pipe used to implement ScheduleWork()
  67. // ... callback; called by libevent inside Run() when pipe is ready to read
  68. static void OnWakeup(int socket, short flags, void* context);
  69. // This flag is set to false when Run should return.
  70. bool keep_running_;
  71. // This flag is set when inside Run.
  72. bool in_run_;
  73. // This flag is set if libevent has processed I/O events.
  74. bool processed_io_events_;
  75. // Libevent dispatcher. Watches all sockets registered with it, and sends
  76. // readiness callbacks when a socket is ready for I/O.
  77. event_base* event_base_;
  78. // ... write end; ScheduleWork() writes a single byte to it
  79. int wakeup_pipe_in_;
  80. // ... read end; OnWakeup reads it and then breaks Run() out of its sleep
  81. int wakeup_pipe_out_;
  82. // ... libevent wrapper for read end
  83. event* wakeup_event_;
  84. ThreadChecker watch_file_descriptor_caller_checker_;
  85. DISALLOW_COPY_AND_ASSIGN(MessagePumpLibevent);
  86. };
  87. } // namespace base
  88. #endif // BASE_MESSAGE_LOOP_MESSAGE_PUMP_LIBEVENT_H_