| // Copyright 2016 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef BASE_FILES_FILE_DESCRIPTOR_WATCHER_POSIX_H_ | 
 | #define BASE_FILES_FILE_DESCRIPTOR_WATCHER_POSIX_H_ | 
 |  | 
 | #include <memory> | 
 |  | 
 | #include "base/base_export.h" | 
 | #include "base/callback.h" | 
 | #include "base/macros.h" | 
 | #include "base/memory/ref_counted.h" | 
 | #include "base/memory/weak_ptr.h" | 
 | #include "base/message_loop/message_loop.h" | 
 | #include "base/message_loop/message_pump_for_io.h" | 
 | #include "base/sequence_checker.h" | 
 |  | 
 | namespace base { | 
 |  | 
 | class SingleThreadTaskRunner; | 
 |  | 
 | // The FileDescriptorWatcher API allows callbacks to be invoked when file | 
 | // descriptors are readable or writable without blocking. | 
 | // | 
 | // To enable this API in unit tests, use a ScopedTaskEnvironment with | 
 | // MainThreadType::IO. | 
 | // | 
 | // Note: Prefer FileDescriptorWatcher to MessageLoopForIO::WatchFileDescriptor() | 
 | // for non-critical IO. FileDescriptorWatcher works on threads/sequences without | 
 | // MessagePumps but involves going through the task queue after being notified | 
 | // by the OS (a desirablable property for non-critical IO that shouldn't preempt | 
 | // the main queue). | 
 | class BASE_EXPORT FileDescriptorWatcher { | 
 |  public: | 
 |   // Instantiated and returned by WatchReadable() or WatchWritable(). The | 
 |   // constructor registers a callback to be invoked when a file descriptor is | 
 |   // readable or writable without blocking and the destructor unregisters it. | 
 |   class Controller { | 
 |    public: | 
 |     // Unregisters the callback registered by the constructor. | 
 |     ~Controller(); | 
 |  | 
 |    private: | 
 |     friend class FileDescriptorWatcher; | 
 |     class Watcher; | 
 |  | 
 |     // Registers |callback| to be invoked when |fd| is readable or writable | 
 |     // without blocking (depending on |mode|). | 
 |     Controller(MessagePumpForIO::Mode mode, int fd, const Closure& callback); | 
 |  | 
 |     // Starts watching the file descriptor. | 
 |     void StartWatching(); | 
 |  | 
 |     // Runs |callback_|. | 
 |     void RunCallback(); | 
 |  | 
 |     // The callback to run when the watched file descriptor is readable or | 
 |     // writable without blocking. | 
 |     Closure callback_; | 
 |  | 
 |     // TaskRunner associated with the MessageLoopForIO that watches the file | 
 |     // descriptor. | 
 |     const scoped_refptr<SingleThreadTaskRunner> | 
 |         message_loop_for_io_task_runner_; | 
 |  | 
 |     // Notified by the MessageLoopForIO associated with | 
 |     // |message_loop_for_io_task_runner_| when the watched file descriptor is | 
 |     // readable or writable without blocking. Posts a task to run RunCallback() | 
 |     // on the sequence on which the Controller was instantiated. When the | 
 |     // Controller is deleted, ownership of |watcher_| is transfered to a delete | 
 |     // task posted to the MessageLoopForIO. This ensures that |watcher_| isn't | 
 |     // deleted while it is being used by the MessageLoopForIO. | 
 |     std::unique_ptr<Watcher> watcher_; | 
 |  | 
 |     // Validates that the Controller is used on the sequence on which it was | 
 |     // instantiated. | 
 |     SequenceChecker sequence_checker_; | 
 |  | 
 |     WeakPtrFactory<Controller> weak_factory_; | 
 |  | 
 |     DISALLOW_COPY_AND_ASSIGN(Controller); | 
 |   }; | 
 |  | 
 |   // Registers |message_loop_for_io| to watch file descriptors for which | 
 |   // callbacks are registered from the current thread via WatchReadable() or | 
 |   // WatchWritable(). |message_loop_for_io| may run on another thread. The | 
 |   // constructed FileDescriptorWatcher must not outlive |message_loop_for_io|. | 
 |   FileDescriptorWatcher(MessageLoopForIO* message_loop_for_io); | 
 |   ~FileDescriptorWatcher(); | 
 |  | 
 |   // Registers |callback| to be posted on the current sequence when |fd| is | 
 |   // readable or writable without blocking. |callback| is unregistered when the | 
 |   // returned Controller is deleted (deletion must happen on the current | 
 |   // sequence). To call these methods, a FileDescriptorWatcher must have been | 
 |   // instantiated on the current thread and SequencedTaskRunnerHandle::IsSet() | 
 |   // must return true (these conditions are met at least on all TaskScheduler | 
 |   // threads as well as on threads backed by a MessageLoopForIO). | 
 |   static std::unique_ptr<Controller> WatchReadable(int fd, | 
 |                                                    const Closure& callback); | 
 |   static std::unique_ptr<Controller> WatchWritable(int fd, | 
 |                                                    const Closure& callback); | 
 |  | 
 |  private: | 
 |   DISALLOW_COPY_AND_ASSIGN(FileDescriptorWatcher); | 
 | }; | 
 |  | 
 | }  // namespace base | 
 |  | 
 | #endif  // BASE_FILES_FILE_DESCRIPTOR_WATCHER_POSIX_H_ |