file_descriptor_watcher_posix.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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/check_op.h"
  10. #include "base/macros.h"
  11. #include "base/memory/ref_counted.h"
  12. #include "base/memory/weak_ptr.h"
  13. #include "base/message_loop/message_pump_for_io.h"
  14. #include "base/sequence_checker.h"
  15. #include "base/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. // Unregisters the callback registered by the constructor.
  37. ~Controller();
  38. private:
  39. friend class FileDescriptorWatcher;
  40. class Watcher;
  41. // Registers |callback| to be invoked when |fd| is readable or writable
  42. // without blocking (depending on |mode|).
  43. Controller(MessagePumpForIO::Mode mode,
  44. int fd,
  45. const RepeatingClosure& callback);
  46. // Starts watching the file descriptor.
  47. void StartWatching();
  48. // Runs |callback_|.
  49. void RunCallback();
  50. // The callback to run when the watched file descriptor is readable or
  51. // writable without blocking.
  52. RepeatingClosure callback_;
  53. // TaskRunner associated with the MessageLoopForIO that watches the file
  54. // descriptor.
  55. const scoped_refptr<SingleThreadTaskRunner> io_thread_task_runner_;
  56. // Notified by the MessageLoopForIO associated with
  57. // |io_thread_task_runner_| when the watched file descriptor is
  58. // readable or writable without blocking. Posts a task to run RunCallback()
  59. // on the sequence on which the Controller was instantiated. When the
  60. // Controller is deleted, ownership of |watcher_| is transfered to a delete
  61. // task posted to the MessageLoopForIO. This ensures that |watcher_| isn't
  62. // deleted while it is being used by the MessageLoopForIO.
  63. std::unique_ptr<Watcher> watcher_;
  64. // Validates that the Controller is used on the sequence on which it was
  65. // instantiated.
  66. SequenceChecker sequence_checker_;
  67. WeakPtrFactory<Controller> weak_factory_{this};
  68. DISALLOW_COPY_AND_ASSIGN(Controller);
  69. };
  70. // Registers |io_thread_task_runner| to watch file descriptors for which
  71. // callbacks are registered from the current thread via WatchReadable() or
  72. // WatchWritable(). |io_thread_task_runner| must post tasks to a thread which
  73. // runs a MessagePumpForIO. If it is not the current thread, it must be highly
  74. // responsive (i.e. not used to run other expensive tasks such as potentially
  75. // blocking I/O) since ~Controller waits for a task posted to it.
  76. explicit FileDescriptorWatcher(
  77. scoped_refptr<SingleThreadTaskRunner> io_thread_task_runner);
  78. ~FileDescriptorWatcher();
  79. // Registers |callback| to be posted on the current sequence when |fd| is
  80. // readable or writable without blocking. |callback| is unregistered when the
  81. // returned Controller is deleted (deletion must happen on the current
  82. // sequence).
  83. // Usage note: To call these methods, a FileDescriptorWatcher must have been
  84. // instantiated on the current thread and SequencedTaskRunnerHandle::IsSet()
  85. // must return true (these conditions are met at least on all ThreadPool
  86. // threads as well as on threads backed by a MessageLoopForIO). |fd| must
  87. // outlive the returned Controller.
  88. // Shutdown note: notifications aren't guaranteed to be emitted once the bound
  89. // (current) SequencedTaskRunner enters its shutdown phase (i.e.
  90. // ThreadPool::Shutdown() or Thread::Stop()) regardless of the
  91. // SequencedTaskRunner's TaskShutdownBehavior.
  92. static std::unique_ptr<Controller> WatchReadable(
  93. int fd,
  94. const RepeatingClosure& callback);
  95. static std::unique_ptr<Controller> WatchWritable(
  96. int fd,
  97. const RepeatingClosure& callback);
  98. // Asserts that usage of this API is allowed on this thread.
  99. static void AssertAllowed()
  100. #if DCHECK_IS_ON()
  101. ;
  102. #else
  103. {
  104. }
  105. #endif
  106. private:
  107. scoped_refptr<SingleThreadTaskRunner> io_thread_task_runner() const {
  108. return io_thread_task_runner_;
  109. }
  110. const scoped_refptr<SingleThreadTaskRunner> io_thread_task_runner_;
  111. DISALLOW_COPY_AND_ASSIGN(FileDescriptorWatcher);
  112. };
  113. } // namespace base
  114. #endif // BASE_FILES_FILE_DESCRIPTOR_WATCHER_POSIX_H_