Home | History | Annotate | Download | only in message_pump
      1 // Copyright 2013 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 MOJO_MESSAGE_PUMP_MESSAGE_PUMP_MOJO_H_
      6 #define MOJO_MESSAGE_PUMP_MESSAGE_PUMP_MOJO_H_
      7 
      8 #include <stdint.h>
      9 
     10 #include <functional>
     11 #include <memory>
     12 #include <set>
     13 #include <unordered_map>
     14 
     15 #include "base/macros.h"
     16 #include "base/message_loop/message_pump.h"
     17 #include "base/observer_list.h"
     18 #include "base/synchronization/lock.h"
     19 #include "base/synchronization/waitable_event.h"
     20 #include "base/time/time.h"
     21 #include "mojo/message_pump/mojo_message_pump_export.h"
     22 #include "mojo/public/cpp/system/core.h"
     23 
     24 namespace mojo {
     25 namespace common {
     26 
     27 class MessagePumpMojoHandler;
     28 
     29 // Mojo implementation of MessagePump.
     30 class MOJO_MESSAGE_PUMP_EXPORT MessagePumpMojo : public base::MessagePump {
     31  public:
     32   class MOJO_MESSAGE_PUMP_EXPORT Observer {
     33    public:
     34     Observer() {}
     35 
     36     virtual void WillSignalHandler() = 0;
     37     virtual void DidSignalHandler() = 0;
     38 
     39    protected:
     40     virtual ~Observer() {}
     41   };
     42 
     43   MessagePumpMojo();
     44   ~MessagePumpMojo() override;
     45 
     46   // Static factory function (for using with |base::Thread::Options|, wrapped
     47   // using |base::Bind()|).
     48   static std::unique_ptr<base::MessagePump> Create();
     49 
     50   // Returns the MessagePumpMojo instance of the current thread, if it exists.
     51   static MessagePumpMojo* current();
     52 
     53   static bool IsCurrent() { return !!current(); }
     54 
     55   // Registers a MessagePumpMojoHandler for the specified handle. Only one
     56   // handler can be registered for a specified handle.
     57   // NOTE: a value of 0 for |deadline| indicates an indefinite timeout.
     58   void AddHandler(MessagePumpMojoHandler* handler,
     59                   const Handle& handle,
     60                   MojoHandleSignals wait_signals,
     61                   base::TimeTicks deadline);
     62 
     63   void RemoveHandler(const Handle& handle);
     64 
     65   void AddObserver(Observer*);
     66   void RemoveObserver(Observer*);
     67 
     68   // MessagePump:
     69   void Run(Delegate* delegate) override;
     70   void Quit() override;
     71   void ScheduleWork() override;
     72   void ScheduleDelayedWork(const base::TimeTicks& delayed_work_time) override;
     73 
     74  private:
     75   struct RunState;
     76 
     77   // Contains the data needed to track a request to AddHandler().
     78   struct Handler {
     79     Handler() : handler(NULL), wait_signals(MOJO_HANDLE_SIGNAL_NONE), id(0) {}
     80 
     81     MessagePumpMojoHandler* handler;
     82     MojoHandleSignals wait_signals;
     83     base::TimeTicks deadline;
     84     // See description of |MessagePumpMojo::next_handler_id_| for details.
     85     int id;
     86   };
     87 
     88   struct HandleHasher {
     89     size_t operator()(const Handle& handle) const {
     90       return std::hash<uint32_t>()(static_cast<uint32_t>(handle.value()));
     91     }
     92   };
     93 
     94   using HandleToHandler = std::unordered_map<Handle, Handler, HandleHasher>;
     95 
     96   // Implementation of Run().
     97   void DoRunLoop(RunState* run_state, Delegate* delegate);
     98 
     99   // Services the set of handles ready. If |block| is true this waits for a
    100   // handle to become ready, otherwise this does not block. Returns |true| if a
    101   // handle has become ready, |false| otherwise.
    102   bool DoInternalWork(const RunState& run_state, bool block);
    103 
    104   bool DoNonMojoWork(const RunState& run_state, bool block);
    105 
    106   // Waits for handles in the wait set to become ready. Returns |true| if ready
    107   // handles may be available, or |false| if the wait's deadline was exceeded.
    108   // Note, ready handles may be unavailable, even though |true| was returned.
    109   bool WaitForReadyHandles(const RunState& run_state) const;
    110 
    111   // Retrieves any 'ready' handles from the wait set, and runs the handler's
    112   // OnHandleReady() or OnHandleError() functions as necessary. Returns |true|
    113   // if any handles were ready and processed.
    114   bool ProcessReadyHandles();
    115 
    116   // Removes any handles that have expired their deadline. Runs the handler's
    117   // OnHandleError() function with |MOJO_RESULT_DEADLINE_EXCEEDED| as the
    118   // result. Returns |true| if any handles were removed.
    119   bool RemoveExpiredHandles();
    120 
    121   void SignalControlPipe();
    122 
    123   // Returns the deadline for the call to MojoWait().
    124   MojoDeadline GetDeadlineForWait(const RunState& run_state) const;
    125 
    126   // Run |OnHandleReady()| for the handler registered with |handle|. |handle|
    127   // must be registered.
    128   void SignalHandleReady(Handle handle);
    129 
    130   // Run |OnHandleError()| for the handler registered with |handle| and the
    131   // error code |result|. |handle| must be registered, and will be removed
    132   // before calling |OnHandleError()|.
    133   void SignalHandleError(Handle handle, MojoResult result);
    134 
    135   void WillSignalHandler();
    136   void DidSignalHandler();
    137 
    138   // If non-NULL we're running (inside Run()). Member is reference to value on
    139   // stack.
    140   RunState* run_state_;
    141 
    142   // Lock for accessing |run_state_|. In general the only method that we have to
    143   // worry about is ScheduleWork(). All other methods are invoked on the same
    144   // thread.
    145   base::Lock run_state_lock_;
    146 
    147   HandleToHandler handlers_;
    148   // Set of handles that have a deadline set. Avoids iterating over all elements
    149   // in |handles_| in the common case (no deadline set).
    150   // TODO(amistry): Make this better and avoid special-casing deadlines.
    151   std::set<Handle> deadline_handles_;
    152 
    153   // An ever increasing value assigned to each Handler::id. Used to detect
    154   // uniqueness while notifying. That is, while notifying expired timers we copy
    155   // |handlers_| and only notify handlers whose id match. If the id does not
    156   // match it means the handler was removed then added so that we shouldn't
    157   // notify it.
    158   int next_handler_id_;
    159 
    160   base::ObserverList<Observer> observers_;
    161 
    162   // Mojo handle for the wait set.
    163   ScopedHandle wait_set_handle_;
    164   // Used to wake up run loop from |SignalControlPipe()|.
    165   ScopedMessagePipeHandle read_handle_;
    166   ScopedMessagePipeHandle write_handle_;
    167 
    168   // Used to sleep until there is more work to do, when the Mojo EDK is shutting
    169   // down.
    170   base::WaitableEvent event_;
    171 
    172   DISALLOW_COPY_AND_ASSIGN(MessagePumpMojo);
    173 };
    174 
    175 }  // namespace common
    176 }  // namespace mojo
    177 
    178 #endif  // MOJO_MESSAGE_PUMP_MESSAGE_PUMP_MOJO_H_
    179