message_pump_glib.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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 <memory>
  7. #include "base/base_export.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/observer_list.h"
  12. #include "base/threading/thread_checker.h"
  13. #include "base/time/time.h"
  14. typedef struct _GMainContext GMainContext;
  15. typedef struct _GPollFD GPollFD;
  16. typedef struct _GSource GSource;
  17. namespace base {
  18. // This class implements a base MessagePump needed for TYPE_UI MessageLoops on
  19. // platforms using GLib.
  20. class BASE_EXPORT MessagePumpGlib : public MessagePump,
  21. public WatchableIOMessagePumpPosix {
  22. public:
  23. class FdWatchController : public FdWatchControllerInterface {
  24. public:
  25. explicit FdWatchController(const Location& from_here);
  26. ~FdWatchController() override;
  27. // FdWatchControllerInterface:
  28. bool StopWatchingFileDescriptor() override;
  29. private:
  30. friend class MessagePumpGlib;
  31. friend class MessagePumpGLibFdWatchTest;
  32. // FdWatchController instances can be reused (unless fd changes), so we
  33. // need to keep track of initialization status and taking it into account
  34. // when setting up a fd watching. Please refer to
  35. // WatchableIOMessagePumpPosix docs for more details. This is called by
  36. // WatchFileDescriptor() and sets up a GSource for the input parameters.
  37. // The source is not attached here, so the events will not be fired until
  38. // Attach() is called.
  39. bool InitOrUpdate(int fd, int mode, FdWatcher* watcher);
  40. // Returns the current initialization status.
  41. bool IsInitialized() const;
  42. // Tries to attach the internal GSource instance to the |pump|'s
  43. // GMainContext, so IO events start to be dispatched. Returns false if
  44. // |this| is not correctly initialized, otherwise returns true.
  45. bool Attach(MessagePumpGlib* pump);
  46. // Forward read and write events to |watcher_|. It is a no-op if watcher_
  47. // is null, which can happen when controller is suddenly stopped through
  48. // StopWatchingFileDescriptor().
  49. void NotifyCanRead();
  50. void NotifyCanWrite();
  51. FdWatcher* watcher_ = nullptr;
  52. GSource* source_ = nullptr;
  53. std::unique_ptr<GPollFD> poll_fd_;
  54. // If this pointer is non-null, the pointee is set to true in the
  55. // destructor.
  56. bool* was_destroyed_ = nullptr;
  57. DISALLOW_COPY_AND_ASSIGN(FdWatchController);
  58. };
  59. MessagePumpGlib();
  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(const TimeTicks& delayed_work_time) override;
  82. // Internal methods used for processing the FdWatchSource callbacks. As for
  83. // main pump callbacks, they are public for simplicity but should not be used
  84. // directly.
  85. bool HandleFdWatchCheck(FdWatchController* controller);
  86. void HandleFdWatchDispatch(FdWatchController* controller);
  87. private:
  88. bool ShouldQuit() const;
  89. // We may make recursive calls to Run, so we save state that needs to be
  90. // separate between them in this structure type.
  91. struct RunState;
  92. RunState* state_;
  93. // This is a GLib structure that we can add event sources to. On the main
  94. // thread, we use the default GLib context, which is the one to which all GTK
  95. // events are dispatched.
  96. GMainContext* context_ = nullptr;
  97. bool context_owned_ = false;
  98. // The work source. It is shared by all calls to Run and destroyed when
  99. // the message pump is destroyed.
  100. GSource* work_source_;
  101. // We use a wakeup pipe to make sure we'll get out of the glib polling phase
  102. // when another thread has scheduled us to do some work. There is a glib
  103. // mechanism g_main_context_wakeup, but this won't guarantee that our event's
  104. // Dispatch() will be called.
  105. int wakeup_pipe_read_;
  106. int wakeup_pipe_write_;
  107. // Use a unique_ptr to avoid needing the definition of GPollFD in the header.
  108. std::unique_ptr<GPollFD> wakeup_gpollfd_;
  109. THREAD_CHECKER(watch_fd_caller_checker_);
  110. DISALLOW_COPY_AND_ASSIGN(MessagePumpGlib);
  111. };
  112. } // namespace base
  113. #endif // BASE_MESSAGE_LOOP_MESSAGE_PUMP_GLIB_H_