file_descriptor_watcher_posix.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Copyright 2016 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_FILES_FILE_DESCRIPTOR_WATCHER_POSIX_H_
  5. #define BASE_FILES_FILE_DESCRIPTOR_WATCHER_POSIX_H_
  6. #include <memory>
  7. #include "base/base_export.h"
  8. #include "base/callback.h"
  9. #include "base/dcheck_is_on.h"
  10. #include "base/memory/raw_ptr.h"
  11. #include "base/memory/weak_ptr.h"
  12. #include "base/message_loop/message_pump_for_io.h"
  13. #include "base/sequence_checker.h"
  14. #include "base/synchronization/waitable_event.h"
  15. #include "base/task/single_thread_task_runner.h"
  16. namespace base {
  17. class SingleThreadTaskRunner;
  18. // The FileDescriptorWatcher API allows callbacks to be invoked when file
  19. // descriptors are readable or writable without blocking.
  20. //
  21. // To enable this API in unit tests, use a TaskEnvironment with
  22. // MainThreadType::IO.
  23. //
  24. // Note: Prefer FileDescriptorWatcher to MessageLoopForIO::WatchFileDescriptor()
  25. // for non-critical IO. FileDescriptorWatcher works on threads/sequences without
  26. // MessagePumps but involves going through the task queue after being notified
  27. // by the OS (a desirablable property for non-critical IO that shouldn't preempt
  28. // the main queue).
  29. class BASE_EXPORT FileDescriptorWatcher {
  30. public:
  31. // Instantiated and returned by WatchReadable() or WatchWritable(). The
  32. // constructor registers a callback to be invoked when a file descriptor is
  33. // readable or writable without blocking and the destructor unregisters it.
  34. class Controller {
  35. public:
  36. Controller(const Controller&) = delete;
  37. Controller& operator=(const Controller&) = delete;
  38. // Unregisters the callback registered by the constructor.
  39. ~Controller();
  40. private:
  41. friend class FileDescriptorWatcher;
  42. class Watcher;
  43. // Registers |callback| to be invoked when |fd| is readable or writable
  44. // without blocking (depending on |mode|).
  45. Controller(MessagePumpForIO::Mode mode,
  46. int fd,
  47. const RepeatingClosure& callback);
  48. // Starts watching the file descriptor.
  49. void StartWatching();
  50. // Runs |callback_|.
  51. void RunCallback();
  52. // The callback to run when the watched file descriptor is readable or
  53. // writable without blocking.
  54. RepeatingClosure callback_;
  55. // TaskRunner associated with the MessageLoopForIO that watches the file
  56. // descriptor.
  57. const scoped_refptr<SingleThreadTaskRunner> io_thread_task_runner_;
  58. // Notified by the MessageLoopForIO associated with
  59. // |io_thread_task_runner_| when the watched file descriptor is
  60. // readable or writable without blocking. Posts a task to run RunCallback()
  61. // on the sequence on which the Controller was instantiated. When the
  62. // Controller is deleted, ownership of |watcher_| is transfered to a delete
  63. // task posted to the MessageLoopForIO. This ensures that |watcher_| isn't
  64. // deleted while it is being used by the MessageLoopForIO.
  65. //
  66. // TODO(crbug.com/1298696): Breaks base_unittests.
  67. raw_ptr<Watcher, DanglingUntriagedDegradeToNoOpWhenMTE> watcher_;
  68. // An event for the watcher to notify controller that it's destroyed.
  69. // As the |watcher_| is owned by Controller, always outlives the Watcher.
  70. base::WaitableEvent on_watcher_destroyed_;
  71. // Validates that the Controller is used on the sequence on which it was
  72. // instantiated.
  73. SequenceChecker sequence_checker_;
  74. WeakPtrFactory<Controller> weak_factory_{this};
  75. };
  76. // Registers |io_thread_task_runner| to watch file descriptors for which
  77. // callbacks are registered from the current thread via WatchReadable() or
  78. // WatchWritable(). |io_thread_task_runner| must post tasks to a thread which
  79. // runs a MessagePumpForIO. If it is not the current thread, it must be highly
  80. // responsive (i.e. not used to run other expensive tasks such as potentially
  81. // blocking I/O) since ~Controller waits for a task posted to it.
  82. explicit FileDescriptorWatcher(
  83. scoped_refptr<SingleThreadTaskRunner> io_thread_task_runner);
  84. FileDescriptorWatcher(const FileDescriptorWatcher&) = delete;
  85. FileDescriptorWatcher& operator=(const FileDescriptorWatcher&) = delete;
  86. ~FileDescriptorWatcher();
  87. // Registers |callback| to be posted on the current sequence when |fd| is
  88. // readable or writable without blocking. |callback| is unregistered when the
  89. // returned Controller is deleted (deletion must happen on the current
  90. // sequence).
  91. // Usage note: To call these methods, a FileDescriptorWatcher must have been
  92. // instantiated on the current thread and SequencedTaskRunnerHandle::IsSet()
  93. // must return true (these conditions are met at least on all ThreadPool
  94. // threads as well as on threads backed by a MessageLoopForIO). |fd| must
  95. // outlive the returned Controller.
  96. // Shutdown note: notifications aren't guaranteed to be emitted once the bound
  97. // (current) SequencedTaskRunner enters its shutdown phase (i.e.
  98. // ThreadPool::Shutdown() or Thread::Stop()) regardless of the
  99. // SequencedTaskRunner's TaskShutdownBehavior.
  100. static std::unique_ptr<Controller> WatchReadable(
  101. int fd,
  102. const RepeatingClosure& callback);
  103. static std::unique_ptr<Controller> WatchWritable(
  104. int fd,
  105. const RepeatingClosure& callback);
  106. // Asserts that usage of this API is allowed on this thread.
  107. static void AssertAllowed()
  108. #if DCHECK_IS_ON()
  109. ;
  110. #else
  111. {
  112. }
  113. #endif
  114. private:
  115. scoped_refptr<SingleThreadTaskRunner> io_thread_task_runner() const {
  116. return io_thread_task_runner_;
  117. }
  118. const scoped_refptr<SingleThreadTaskRunner> io_thread_task_runner_;
  119. };
  120. } // namespace base
  121. #endif // BASE_FILES_FILE_DESCRIPTOR_WATCHER_POSIX_H_