message_pump_fuchsia.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // Copyright 2017 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_FUCHSIA_H_
  5. #define BASE_MESSAGE_LOOP_MESSAGE_PUMP_FUCHSIA_H_
  6. #include <lib/async/wait.h>
  7. #include "base/base_export.h"
  8. #include "base/location.h"
  9. #include "base/macros.h"
  10. #include "base/memory/weak_ptr.h"
  11. #include "base/message_loop/message_pump.h"
  12. #include "base/message_loop/watchable_io_message_pump_posix.h"
  13. typedef struct fdio fdio_t;
  14. namespace async {
  15. class Loop;
  16. } // namespace async
  17. namespace base {
  18. class BASE_EXPORT MessagePumpFuchsia : public MessagePump,
  19. public WatchableIOMessagePumpPosix {
  20. public:
  21. // Implemented by callers to receive notifications of handle & fd events.
  22. class ZxHandleWatcher {
  23. public:
  24. virtual void OnZxHandleSignalled(zx_handle_t handle,
  25. zx_signals_t signals) = 0;
  26. protected:
  27. virtual ~ZxHandleWatcher() {}
  28. };
  29. // Manages an active watch on an zx_handle_t.
  30. class ZxHandleWatchController : public async_wait_t {
  31. public:
  32. explicit ZxHandleWatchController(const Location& from_here);
  33. // Deleting the Controller implicitly calls StopWatchingZxHandle.
  34. virtual ~ZxHandleWatchController();
  35. // Stop watching the handle, always safe to call. No-op if there's nothing
  36. // to do.
  37. bool StopWatchingZxHandle();
  38. const Location& created_from_location() { return created_from_location_; }
  39. protected:
  40. friend class MessagePumpFuchsia;
  41. virtual bool WaitBegin();
  42. bool is_active() const { return async_wait_t::handler != nullptr; }
  43. static void HandleSignal(async_dispatcher_t* async,
  44. async_wait_t* wait,
  45. zx_status_t status,
  46. const zx_packet_signal_t* signal);
  47. const Location created_from_location_;
  48. // This bool is used by the pump when invoking the ZxHandleWatcher callback,
  49. // and by the FdHandleWatchController when invoking read & write callbacks,
  50. // to cope with the possibility of the caller deleting the *Watcher within
  51. // the callback. The pump sets |was_stopped_| to a location on the stack,
  52. // and the Watcher writes to it, if set, when deleted, allowing the pump
  53. // to check the value on the stack to short-cut any post-callback work.
  54. bool* was_stopped_ = nullptr;
  55. // Set directly from the inputs to WatchFileDescriptor.
  56. ZxHandleWatcher* watcher_ = nullptr;
  57. // Used to safely access resources owned by the associated message pump.
  58. WeakPtr<MessagePumpFuchsia> weak_pump_;
  59. // A watch may be marked as persistent, which means it remains active even
  60. // after triggering.
  61. bool persistent_ = false;
  62. DISALLOW_COPY_AND_ASSIGN(ZxHandleWatchController);
  63. };
  64. class FdWatchController : public FdWatchControllerInterface,
  65. public ZxHandleWatchController,
  66. public ZxHandleWatcher {
  67. public:
  68. explicit FdWatchController(const Location& from_here);
  69. ~FdWatchController() override;
  70. // FdWatchControllerInterface:
  71. bool StopWatchingFileDescriptor() override;
  72. private:
  73. friend class MessagePumpFuchsia;
  74. // Determines the desires signals, and begins waiting on the handle.
  75. bool WaitBegin() override;
  76. // ZxHandleWatcher interface.
  77. void OnZxHandleSignalled(zx_handle_t handle, zx_signals_t signals) override;
  78. // Set directly from the inputs to WatchFileDescriptor.
  79. FdWatcher* watcher_ = nullptr;
  80. int fd_ = -1;
  81. uint32_t desired_events_ = 0;
  82. // Set by WatchFileDescriptor() to hold a reference to the descriptor's
  83. // fdio.
  84. fdio_t* io_ = nullptr;
  85. DISALLOW_COPY_AND_ASSIGN(FdWatchController);
  86. };
  87. enum Mode {
  88. WATCH_READ = 1 << 0,
  89. WATCH_WRITE = 1 << 1,
  90. WATCH_READ_WRITE = WATCH_READ | WATCH_WRITE
  91. };
  92. MessagePumpFuchsia();
  93. ~MessagePumpFuchsia() override;
  94. bool WatchZxHandle(zx_handle_t handle,
  95. bool persistent,
  96. zx_signals_t signals,
  97. ZxHandleWatchController* controller,
  98. ZxHandleWatcher* delegate);
  99. bool WatchFileDescriptor(int fd,
  100. bool persistent,
  101. int mode,
  102. FdWatchController* controller,
  103. FdWatcher* delegate);
  104. // MessagePump implementation:
  105. void Run(Delegate* delegate) override;
  106. void Quit() override;
  107. void ScheduleWork() override;
  108. void ScheduleDelayedWork(const TimeTicks& delayed_work_time) override;
  109. private:
  110. // Handles IO events by running |async_dispatcher_| until |deadline|. Returns
  111. // true if any events were received or if ScheduleWork() was called.
  112. bool HandleIoEventsUntil(zx_time_t deadline);
  113. // This flag is set to false when Run should return.
  114. bool keep_running_ = true;
  115. std::unique_ptr<async::Loop> async_loop_;
  116. base::WeakPtrFactory<MessagePumpFuchsia> weak_factory_;
  117. DISALLOW_COPY_AND_ASSIGN(MessagePumpFuchsia);
  118. };
  119. } // namespace base
  120. #endif // BASE_MESSAGE_LOOP_MESSAGE_PUMP_FUCHSIA_H_