Home | History | Annotate | Download | only in message_loop
      1 // Copyright 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 
      5 #ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_IO_IOS_H_
      6 #define BASE_MESSAGE_LOOP_MESSAGE_PUMP_IO_IOS_H_
      7 
      8 #include "base/base_export.h"
      9 #include "base/mac/scoped_cffiledescriptorref.h"
     10 #include "base/mac/scoped_cftyperef.h"
     11 #include "base/memory/ref_counted.h"
     12 #include "base/memory/weak_ptr.h"
     13 #include "base/message_loop/message_pump_mac.h"
     14 #include "base/observer_list.h"
     15 #include "base/threading/thread_checker.h"
     16 
     17 namespace base {
     18 
     19 // This file introduces a class to monitor sockets and issue callbacks when
     20 // sockets are ready for I/O on iOS.
     21 class BASE_EXPORT MessagePumpIOSForIO : public MessagePumpNSRunLoop {
     22  public:
     23   class IOObserver {
     24    public:
     25     IOObserver() {}
     26 
     27     // An IOObserver is an object that receives IO notifications from the
     28     // MessagePump.
     29     //
     30     // NOTE: An IOObserver implementation should be extremely fast!
     31     virtual void WillProcessIOEvent() = 0;
     32     virtual void DidProcessIOEvent() = 0;
     33 
     34    protected:
     35     virtual ~IOObserver() {}
     36   };
     37 
     38   // Used with WatchFileDescriptor to asynchronously monitor the I/O readiness
     39   // of a file descriptor.
     40   class Watcher {
     41    public:
     42     // Called from MessageLoop::Run when an FD can be read from/written to
     43     // without blocking
     44     virtual void OnFileCanReadWithoutBlocking(int fd) = 0;
     45     virtual void OnFileCanWriteWithoutBlocking(int fd) = 0;
     46 
     47    protected:
     48     virtual ~Watcher() {}
     49   };
     50 
     51   // Object returned by WatchFileDescriptor to manage further watching.
     52   class FileDescriptorWatcher {
     53    public:
     54     FileDescriptorWatcher();
     55     ~FileDescriptorWatcher();  // Implicitly calls StopWatchingFileDescriptor.
     56 
     57     // NOTE: These methods aren't called StartWatching()/StopWatching() to
     58     // avoid confusion with the win32 ObjectWatcher class.
     59 
     60     // Stop watching the FD, always safe to call.  No-op if there's nothing
     61     // to do.
     62     bool StopWatchingFileDescriptor();
     63 
     64    private:
     65     friend class MessagePumpIOSForIO;
     66     friend class MessagePumpIOSForIOTest;
     67 
     68     // Called by MessagePumpIOSForIO, ownership of |fdref| and |fd_source|
     69     // is transferred to this object.
     70     void Init(CFFileDescriptorRef fdref,
     71               CFOptionFlags callback_types,
     72               CFRunLoopSourceRef fd_source,
     73               bool is_persistent);
     74 
     75     void set_pump(base::WeakPtr<MessagePumpIOSForIO> pump) { pump_ = pump; }
     76     const base::WeakPtr<MessagePumpIOSForIO>& pump() const { return pump_; }
     77 
     78     void set_watcher(Watcher* watcher) { watcher_ = watcher; }
     79 
     80     void OnFileCanReadWithoutBlocking(int fd, MessagePumpIOSForIO* pump);
     81     void OnFileCanWriteWithoutBlocking(int fd, MessagePumpIOSForIO* pump);
     82 
     83     bool is_persistent_;  // false if this event is one-shot.
     84     base::mac::ScopedCFFileDescriptorRef fdref_;
     85     CFOptionFlags callback_types_;
     86     base::ScopedCFTypeRef<CFRunLoopSourceRef> fd_source_;
     87     base::WeakPtr<MessagePumpIOSForIO> pump_;
     88     Watcher* watcher_;
     89 
     90     DISALLOW_COPY_AND_ASSIGN(FileDescriptorWatcher);
     91   };
     92 
     93   enum Mode {
     94     WATCH_READ = 1 << 0,
     95     WATCH_WRITE = 1 << 1,
     96     WATCH_READ_WRITE = WATCH_READ | WATCH_WRITE
     97   };
     98 
     99   MessagePumpIOSForIO();
    100   virtual ~MessagePumpIOSForIO();
    101 
    102   // Have the current thread's message loop watch for a a situation in which
    103   // reading/writing to the FD can be performed without blocking.
    104   // Callers must provide a preallocated FileDescriptorWatcher object which
    105   // can later be used to manage the lifetime of this event.
    106   // If a FileDescriptorWatcher is passed in which is already attached to
    107   // an event, then the effect is cumulative i.e. after the call |controller|
    108   // will watch both the previous event and the new one.
    109   // If an error occurs while calling this method in a cumulative fashion, the
    110   // event previously attached to |controller| is aborted.
    111   // Returns true on success.
    112   // Must be called on the same thread the message_pump is running on.
    113   bool WatchFileDescriptor(int fd,
    114                            bool persistent,
    115                            int mode,
    116                            FileDescriptorWatcher *controller,
    117                            Watcher *delegate);
    118 
    119   void RemoveRunLoopSource(CFRunLoopSourceRef source);
    120 
    121   void AddIOObserver(IOObserver* obs);
    122   void RemoveIOObserver(IOObserver* obs);
    123 
    124  private:
    125   friend class MessagePumpIOSForIOTest;
    126 
    127   void WillProcessIOEvent();
    128   void DidProcessIOEvent();
    129 
    130   static void HandleFdIOEvent(CFFileDescriptorRef fdref,
    131                               CFOptionFlags callback_types,
    132                               void* context);
    133 
    134   ObserverList<IOObserver> io_observers_;
    135   ThreadChecker watch_file_descriptor_caller_checker_;
    136 
    137   base::WeakPtrFactory<MessagePumpIOSForIO> weak_factory_;
    138 
    139   DISALLOW_COPY_AND_ASSIGN(MessagePumpIOSForIO);
    140 };
    141 
    142 }  // namespace base
    143 
    144 #endif  // BASE_MESSAGE_LOOP_MESSAGE_PUMP_IO_IOS_H_
    145