message_pump_glib.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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_GLIB_H_
  5. #define BASE_MESSAGE_LOOP_MESSAGE_PUMP_GLIB_H_
  6. #include <glib.h>
  7. #include <memory>
  8. #include "base/base_export.h"
  9. #include "base/memory/raw_ptr.h"
  10. #include "base/message_loop/message_pump.h"
  11. #include "base/message_loop/watchable_io_message_pump_posix.h"
  12. #include "base/threading/thread_checker.h"
  13. #include "base/time/time.h"
  14. namespace base {
  15. // This class implements a base MessagePump needed for TYPE_UI MessageLoops on
  16. // platforms using GLib.
  17. class BASE_EXPORT MessagePumpGlib : public MessagePump,
  18. public WatchableIOMessagePumpPosix {
  19. public:
  20. class FdWatchController : public FdWatchControllerInterface {
  21. public:
  22. explicit FdWatchController(const Location& from_here);
  23. FdWatchController(const FdWatchController&) = delete;
  24. FdWatchController& operator=(const FdWatchController&) = delete;
  25. ~FdWatchController() override;
  26. // FdWatchControllerInterface:
  27. bool StopWatchingFileDescriptor() override;
  28. private:
  29. friend class MessagePumpGlib;
  30. friend class MessagePumpGLibFdWatchTest;
  31. // FdWatchController instances can be reused (unless fd changes), so we
  32. // need to keep track of initialization status and taking it into account
  33. // when setting up a fd watching. Please refer to
  34. // WatchableIOMessagePumpPosix docs for more details. This is called by
  35. // WatchFileDescriptor() and sets up a GSource for the input parameters.
  36. // The source is not attached here, so the events will not be fired until
  37. // Attach() is called.
  38. bool InitOrUpdate(int fd, int mode, FdWatcher* watcher);
  39. // Returns the current initialization status.
  40. bool IsInitialized() const;
  41. // Tries to attach the internal GSource instance to the |pump|'s
  42. // GMainContext, so IO events start to be dispatched. Returns false if
  43. // |this| is not correctly initialized, otherwise returns true.
  44. bool Attach(MessagePumpGlib* pump);
  45. // Forward read and write events to |watcher_|. It is a no-op if watcher_
  46. // is null, which can happen when controller is suddenly stopped through
  47. // StopWatchingFileDescriptor().
  48. void NotifyCanRead();
  49. void NotifyCanWrite();
  50. raw_ptr<FdWatcher> watcher_ = nullptr;
  51. raw_ptr<GSource> source_ = nullptr;
  52. std::unique_ptr<GPollFD> poll_fd_;
  53. // If this pointer is non-null, the pointee is set to true in the
  54. // destructor.
  55. raw_ptr<bool> was_destroyed_ = nullptr;
  56. };
  57. MessagePumpGlib();
  58. MessagePumpGlib(const MessagePumpGlib&) = delete;
  59. MessagePumpGlib& operator=(const MessagePumpGlib&) = delete;
  60. ~MessagePumpGlib() override;
  61. // Part of WatchableIOMessagePumpPosix interface.
  62. // Please refer to WatchableIOMessagePumpPosix docs for more details.
  63. bool WatchFileDescriptor(int fd,
  64. bool persistent,
  65. int mode,
  66. FdWatchController* controller,
  67. FdWatcher* delegate);
  68. // Internal methods used for processing the pump callbacks. They are public
  69. // for simplicity but should not be used directly. HandlePrepare is called
  70. // during the prepare step of glib, and returns a timeout that will be passed
  71. // to the poll. HandleCheck is called after the poll has completed, and
  72. // returns whether or not HandleDispatch should be called. HandleDispatch is
  73. // called if HandleCheck returned true.
  74. int HandlePrepare();
  75. bool HandleCheck();
  76. void HandleDispatch();
  77. // Overridden from MessagePump:
  78. void Run(Delegate* delegate) override;
  79. void Quit() override;
  80. void ScheduleWork() override;
  81. void ScheduleDelayedWork(
  82. const Delegate::NextWorkInfo& next_work_info) override;
  83. // Internal methods used for processing the FdWatchSource callbacks. As for
  84. // main pump callbacks, they are public for simplicity but should not be used
  85. // directly.
  86. bool HandleFdWatchCheck(FdWatchController* controller);
  87. void HandleFdWatchDispatch(FdWatchController* controller);
  88. private:
  89. struct GMainContextDeleter {
  90. inline void operator()(GMainContext* context) const {
  91. if (context) {
  92. g_main_context_pop_thread_default(context);
  93. g_main_context_unref(context);
  94. }
  95. }
  96. };
  97. struct GSourceDeleter {
  98. inline void operator()(GSource* source) const {
  99. if (source) {
  100. g_source_destroy(source);
  101. g_source_unref(source);
  102. }
  103. }
  104. };
  105. bool ShouldQuit() const;
  106. // We may make recursive calls to Run, so we save state that needs to be
  107. // separate between them in this structure type.
  108. struct RunState;
  109. raw_ptr<RunState> state_;
  110. std::unique_ptr<GMainContext, GMainContextDeleter> owned_context_;
  111. // This is a GLib structure that we can add event sources to. On the main
  112. // thread, we use the default GLib context, which is the one to which all GTK
  113. // events are dispatched.
  114. raw_ptr<GMainContext> context_ = nullptr;
  115. // The work source. It is shared by all calls to Run and destroyed when
  116. // the message pump is destroyed.
  117. std::unique_ptr<GSource, GSourceDeleter> work_source_;
  118. // We use a wakeup pipe to make sure we'll get out of the glib polling phase
  119. // when another thread has scheduled us to do some work. There is a glib
  120. // mechanism g_main_context_wakeup, but this won't guarantee that our event's
  121. // Dispatch() will be called.
  122. int wakeup_pipe_read_;
  123. int wakeup_pipe_write_;
  124. // Use a unique_ptr to avoid needing the definition of GPollFD in the header.
  125. std::unique_ptr<GPollFD> wakeup_gpollfd_;
  126. THREAD_CHECKER(watch_fd_caller_checker_);
  127. };
  128. } // namespace base
  129. #endif // BASE_MESSAGE_LOOP_MESSAGE_PUMP_GLIB_H_