Home | History | Annotate | Download | only in core
      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_CORE_DISPATCHER_H_
      6 #define MOJO_CORE_DISPATCHER_H_
      7 
      8 #include <stddef.h>
      9 #include <stdint.h>
     10 
     11 #include <memory>
     12 #include <ostream>
     13 #include <vector>
     14 
     15 #include "base/macros.h"
     16 #include "base/memory/ref_counted.h"
     17 #include "base/strings/string_piece.h"
     18 #include "base/synchronization/lock.h"
     19 #include "mojo/core/handle_signals_state.h"
     20 #include "mojo/core/ports/name.h"
     21 #include "mojo/core/ports/port_ref.h"
     22 #include "mojo/core/system_impl_export.h"
     23 #include "mojo/core/watch.h"
     24 #include "mojo/public/c/system/buffer.h"
     25 #include "mojo/public/c/system/data_pipe.h"
     26 #include "mojo/public/c/system/message_pipe.h"
     27 #include "mojo/public/c/system/quota.h"
     28 #include "mojo/public/c/system/trap.h"
     29 #include "mojo/public/c/system/types.h"
     30 #include "mojo/public/cpp/platform/platform_handle.h"
     31 
     32 namespace mojo {
     33 namespace core {
     34 
     35 namespace ports {
     36 class UserMessageEvent;
     37 }
     38 
     39 class Dispatcher;
     40 class PlatformSharedMemoryMapping;
     41 
     42 using DispatcherVector = std::vector<scoped_refptr<Dispatcher>>;
     43 
     44 // A |Dispatcher| implements Mojo EDK calls that are associated with a
     45 // particular MojoHandle.
     46 class MOJO_SYSTEM_IMPL_EXPORT Dispatcher
     47     : public base::RefCountedThreadSafe<Dispatcher> {
     48  public:
     49   struct DispatcherInTransit {
     50     DispatcherInTransit();
     51     DispatcherInTransit(const DispatcherInTransit& other);
     52     ~DispatcherInTransit();
     53 
     54     scoped_refptr<Dispatcher> dispatcher;
     55     MojoHandle local_handle;
     56   };
     57 
     58   enum class Type {
     59     UNKNOWN = 0,
     60     MESSAGE_PIPE,
     61     DATA_PIPE_PRODUCER,
     62     DATA_PIPE_CONSUMER,
     63     SHARED_BUFFER,
     64     WATCHER,
     65     INVITATION,
     66 
     67     // "Private" types (not exposed via the public interface):
     68     PLATFORM_HANDLE = -1,
     69   };
     70 
     71   // All Dispatchers must minimally implement these methods.
     72 
     73   virtual Type GetType() const = 0;
     74   virtual MojoResult Close() = 0;
     75 
     76   ///////////// Watcher API ////////////////////
     77 
     78   virtual MojoResult WatchDispatcher(scoped_refptr<Dispatcher> dispatcher,
     79                                      MojoHandleSignals signals,
     80                                      MojoTriggerCondition condition,
     81                                      uintptr_t context);
     82   virtual MojoResult CancelWatch(uintptr_t context);
     83   virtual MojoResult Arm(uint32_t* num_blocking_events,
     84                          MojoTrapEvent* blocking_events);
     85 
     86   ///////////// Message pipe API /////////////
     87 
     88   virtual MojoResult WriteMessage(
     89       std::unique_ptr<ports::UserMessageEvent> message);
     90 
     91   virtual MojoResult ReadMessage(
     92       std::unique_ptr<ports::UserMessageEvent>* message);
     93 
     94   ///////////// Shared buffer API /////////////
     95 
     96   // |options| may be null. |new_dispatcher| must not be null, but
     97   // |*new_dispatcher| should be null (and will contain the dispatcher for the
     98   // new handle on success).
     99   virtual MojoResult DuplicateBufferHandle(
    100       const MojoDuplicateBufferHandleOptions* options,
    101       scoped_refptr<Dispatcher>* new_dispatcher);
    102 
    103   virtual MojoResult MapBuffer(
    104       uint64_t offset,
    105       uint64_t num_bytes,
    106       std::unique_ptr<PlatformSharedMemoryMapping>* mapping);
    107 
    108   virtual MojoResult GetBufferInfo(MojoSharedBufferInfo* info);
    109 
    110   ///////////// Data pipe consumer API /////////////
    111 
    112   virtual MojoResult ReadData(const MojoReadDataOptions& options,
    113                               void* elements,
    114                               uint32_t* num_bytes);
    115 
    116   virtual MojoResult BeginReadData(const void** buffer,
    117                                    uint32_t* buffer_num_bytes);
    118 
    119   virtual MojoResult EndReadData(uint32_t num_bytes_read);
    120 
    121   ///////////// Data pipe producer API /////////////
    122 
    123   virtual MojoResult WriteData(const void* elements,
    124                                uint32_t* num_bytes,
    125                                const MojoWriteDataOptions& options);
    126 
    127   virtual MojoResult BeginWriteData(void** buffer, uint32_t* buffer_num_bytes);
    128 
    129   virtual MojoResult EndWriteData(uint32_t num_bytes_written);
    130 
    131   // Invitation API.
    132   virtual MojoResult AttachMessagePipe(base::StringPiece name,
    133                                        ports::PortRef remote_peer_port);
    134   virtual MojoResult ExtractMessagePipe(base::StringPiece name,
    135                                         MojoHandle* message_pipe_handle);
    136 
    137   // Quota API.
    138   virtual MojoResult SetQuota(MojoQuotaType type, uint64_t limit);
    139   virtual MojoResult QueryQuota(MojoQuotaType type,
    140                                 uint64_t* limit,
    141                                 uint64_t* usage);
    142 
    143   ///////////// General-purpose API for all handle types /////////
    144 
    145   // Gets the current handle signals state. (The default implementation simply
    146   // returns a default-constructed |HandleSignalsState|, i.e., no signals
    147   // satisfied or satisfiable.) Note: The state is subject to change from other
    148   // threads.
    149   virtual HandleSignalsState GetHandleSignalsState() const;
    150 
    151   // Adds a WatcherDispatcher reference to this dispatcher, to be notified of
    152   // all subsequent changes to handle state including signal changes or closure.
    153   // The reference is associated with a |context| for disambiguation of
    154   // removals.
    155   virtual MojoResult AddWatcherRef(
    156       const scoped_refptr<WatcherDispatcher>& watcher,
    157       uintptr_t context);
    158 
    159   // Removes a WatcherDispatcher reference from this dispatcher.
    160   virtual MojoResult RemoveWatcherRef(WatcherDispatcher* watcher,
    161                                       uintptr_t context);
    162 
    163   // Informs the caller of the total serialized size (in bytes) and the total
    164   // number of platform handles and ports needed to transfer this dispatcher
    165   // across a message pipe.
    166   //
    167   // Must eventually be followed by a call to EndSerializeAndClose(). Note that
    168   // StartSerialize() and EndSerialize() are always called in sequence, and
    169   // only between calls to BeginTransit() and either (but not both)
    170   // CompleteTransitAndClose() or CancelTransit().
    171   //
    172   // For this reason it is IMPERATIVE that the implementation ensure a
    173   // consistent serializable state between BeginTransit() and
    174   // CompleteTransitAndClose()/CancelTransit().
    175   virtual void StartSerialize(uint32_t* num_bytes,
    176                               uint32_t* num_ports,
    177                               uint32_t* num_platform_handles);
    178 
    179   // Serializes this dispatcher into |destination|, |ports|, and |handles|.
    180   // Returns true iff successful, false otherwise. In either case the dispatcher
    181   // will close.
    182   //
    183   // NOTE: Transit MAY still fail after this call returns. Implementations
    184   // should not assume PlatformHandle ownership has transferred until
    185   // CompleteTransitAndClose() is called. In other words, if CancelTransit() is
    186   // called, the implementation should retain its PlatformHandles in working
    187   // condition.
    188   virtual bool EndSerialize(void* destination,
    189                             ports::PortName* ports,
    190                             PlatformHandle* handles);
    191 
    192   // Does whatever is necessary to begin transit of the dispatcher.  This
    193   // should return |true| if transit is OK, or false if the underlying resource
    194   // is deemed busy by the implementation.
    195   virtual bool BeginTransit();
    196 
    197   // Does whatever is necessary to complete transit of the dispatcher, including
    198   // closure. This is only called upon successfully transmitting an outgoing
    199   // message containing this serialized dispatcher.
    200   virtual void CompleteTransitAndClose();
    201 
    202   // Does whatever is necessary to cancel transit of the dispatcher. The
    203   // dispatcher should remain in a working state and resume normal operation.
    204   virtual void CancelTransit();
    205 
    206   // Deserializes a specific dispatcher type from an incoming message.
    207   static scoped_refptr<Dispatcher> Deserialize(Type type,
    208                                                const void* bytes,
    209                                                size_t num_bytes,
    210                                                const ports::PortName* ports,
    211                                                size_t num_ports,
    212                                                PlatformHandle* platform_handles,
    213                                                size_t platform_handle_count);
    214 
    215  protected:
    216   friend class base::RefCountedThreadSafe<Dispatcher>;
    217 
    218   Dispatcher();
    219   virtual ~Dispatcher();
    220 
    221   DISALLOW_COPY_AND_ASSIGN(Dispatcher);
    222 };
    223 
    224 // So logging macros and |DCHECK_EQ()|, etc. work.
    225 MOJO_SYSTEM_IMPL_EXPORT inline std::ostream& operator<<(std::ostream& out,
    226                                                         Dispatcher::Type type) {
    227   return out << static_cast<int>(type);
    228 }
    229 
    230 }  // namespace core
    231 }  // namespace mojo
    232 
    233 #endif  // MOJO_CORE_DISPATCHER_H_
    234