Home | History | Annotate | Download | only in files
      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 
      5 #ifndef BASE_FILES_FILE_DESCRIPTOR_WATCHER_POSIX_H_
      6 #define BASE_FILES_FILE_DESCRIPTOR_WATCHER_POSIX_H_
      7 
      8 #include <memory>
      9 
     10 #include "base/base_export.h"
     11 #include "base/callback.h"
     12 #include "base/macros.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/memory/weak_ptr.h"
     15 #include "base/message_loop/message_loop.h"
     16 #include "base/sequence_checker.h"
     17 
     18 namespace base {
     19 
     20 class SingleThreadTaskRunner;
     21 
     22 // The FileDescriptorWatcher API allows callbacks to be invoked when file
     23 // descriptors are readable or writable without blocking.
     24 class BASE_EXPORT FileDescriptorWatcher {
     25  public:
     26   // Instantiated and returned by WatchReadable() or WatchWritable(). The
     27   // constructor registers a callback to be invoked when a file descriptor is
     28   // readable or writable without blocking and the destructor unregisters it.
     29   class Controller {
     30    public:
     31     // Unregisters the callback registered by the constructor.
     32     ~Controller();
     33 
     34    private:
     35     friend class FileDescriptorWatcher;
     36     class Watcher;
     37 
     38     // Registers |callback| to be invoked when |fd| is readable or writable
     39     // without blocking (depending on |mode|).
     40     Controller(MessageLoopForIO::Mode mode, int fd, const Closure& callback);
     41 
     42     // Starts watching the file descriptor.
     43     void StartWatching();
     44 
     45     // Runs |callback_|.
     46     void RunCallback();
     47 
     48     // The callback to run when the watched file descriptor is readable or
     49     // writable without blocking.
     50     Closure callback_;
     51 
     52     // TaskRunner associated with the MessageLoopForIO that watches the file
     53     // descriptor.
     54     const scoped_refptr<SingleThreadTaskRunner>
     55         message_loop_for_io_task_runner_;
     56 
     57     // Notified by the MessageLoopForIO associated with
     58     // |message_loop_for_io_task_runner_| when the watched file descriptor is
     59     // readable or writable without blocking. Posts a task to run RunCallback()
     60     // on the sequence on which the Controller was instantiated. When the
     61     // Controller is deleted, ownership of |watcher_| is transfered to a delete
     62     // task posted to the MessageLoopForIO. This ensures that |watcher_| isn't
     63     // deleted while it is being used by the MessageLoopForIO.
     64     std::unique_ptr<Watcher> watcher_;
     65 
     66     // Validates that the Controller is used on the sequence on which it was
     67     // instantiated.
     68     SequenceChecker sequence_checker_;
     69 
     70     WeakPtrFactory<Controller> weak_factory_;
     71 
     72     DISALLOW_COPY_AND_ASSIGN(Controller);
     73   };
     74 
     75   // Registers |message_loop_for_io| to watch file descriptors for which
     76   // callbacks are registered from the current thread via WatchReadable() or
     77   // WatchWritable(). |message_loop_for_io| may run on another thread. The
     78   // constructed FileDescriptorWatcher must not outlive |message_loop_for_io|.
     79   FileDescriptorWatcher(MessageLoopForIO* message_loop_for_io);
     80   ~FileDescriptorWatcher();
     81 
     82   // Registers |callback| to be invoked on the current sequence when |fd| is
     83   // readable or writable without blocking. |callback| is unregistered when the
     84   // returned Controller is deleted (deletion must happen on the current
     85   // sequence). To call these methods, a FileDescriptorWatcher must have been
     86   // instantiated on the current thread and SequencedTaskRunnerHandle::IsSet()
     87   // must return true.
     88   static std::unique_ptr<Controller> WatchReadable(int fd,
     89                                                    const Closure& callback);
     90   static std::unique_ptr<Controller> WatchWritable(int fd,
     91                                                    const Closure& callback);
     92 
     93  private:
     94   DISALLOW_COPY_AND_ASSIGN(FileDescriptorWatcher);
     95 };
     96 
     97 }  // namespace base
     98 
     99 #endif  // BASE_FILES_FILE_DESCRIPTOR_WATCHER_POSIX_H_
    100