message_pump_fuchsia.h 5.4 KB

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