Home | History | Annotate | Download | only in system
      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_SYSTEM_CORE_IMPL_H_
      6 #define MOJO_SYSTEM_CORE_IMPL_H_
      7 
      8 #include "base/basictypes.h"
      9 #include "base/compiler_specific.h"
     10 #include "base/containers/hash_tables.h"
     11 #include "base/memory/ref_counted.h"
     12 #include "base/synchronization/lock.h"
     13 #include "mojo/public/system/core_private.h"
     14 #include "mojo/system/system_impl_export.h"
     15 
     16 namespace mojo {
     17 namespace system {
     18 
     19 class CoreImpl;
     20 class Dispatcher;
     21 
     22 namespace test {
     23 class CoreTestBase;
     24 }
     25 
     26 // |CoreImpl| is a singleton object that implements the Mojo system calls. With
     27 // the (obvious) exception of |Init()|, which must be called first (and the call
     28 // completed) before making any other calls, all the public methods are
     29 // thread-safe.
     30 class MOJO_SYSTEM_IMPL_EXPORT CoreImpl : public CorePrivate {
     31  public:
     32   static void Init();
     33 
     34   // |CorePrivate| implementation:
     35   virtual MojoTimeTicks GetTimeTicksNow() OVERRIDE;
     36   virtual MojoResult Close(MojoHandle handle) OVERRIDE;
     37   virtual MojoResult Wait(MojoHandle handle,
     38                           MojoWaitFlags flags,
     39                           MojoDeadline deadline) OVERRIDE;
     40   virtual MojoResult WaitMany(const MojoHandle* handles,
     41                               const MojoWaitFlags* flags,
     42                               uint32_t num_handles,
     43                               MojoDeadline deadline) OVERRIDE;
     44   virtual MojoResult CreateMessagePipe(
     45       MojoHandle* message_pipe_handle_0,
     46       MojoHandle* message_pipe_handle_1) OVERRIDE;
     47   virtual MojoResult WriteMessage(MojoHandle message_pipe_handle,
     48                                   const void* bytes,
     49                                   uint32_t num_bytes,
     50                                   const MojoHandle* handles,
     51                                   uint32_t num_handles,
     52                                   MojoWriteMessageFlags flags) OVERRIDE;
     53   virtual MojoResult ReadMessage(MojoHandle message_pipe_handle,
     54                                  void* bytes,
     55                                  uint32_t* num_bytes,
     56                                  MojoHandle* handles,
     57                                  uint32_t* num_handles,
     58                                  MojoReadMessageFlags flags) OVERRIDE;
     59   virtual MojoResult CreateDataPipe(
     60       const MojoCreateDataPipeOptions* options,
     61       MojoHandle* data_pipe_producer_handle,
     62       MojoHandle* data_pipe_consumer_handle) OVERRIDE;
     63   virtual MojoResult WriteData(MojoHandle data_pipe_producer_handle,
     64                                const void* elements,
     65                                uint32_t* num_elements,
     66                                MojoWriteDataFlags flags) OVERRIDE;
     67   virtual MojoResult BeginWriteData(MojoHandle data_pipe_producer_handle,
     68                                     void** buffer,
     69                                     uint32_t* buffer_num_elements,
     70                                     MojoWriteDataFlags flags) OVERRIDE;
     71   virtual MojoResult EndWriteData(MojoHandle data_pipe_producer_handle,
     72                                   uint32_t num_elements_written) OVERRIDE;
     73   virtual MojoResult ReadData(MojoHandle data_pipe_consumer_handle,
     74                               void* elements,
     75                               uint32_t* num_elements,
     76                               MojoReadDataFlags flags) OVERRIDE;
     77   virtual MojoResult BeginReadData(MojoHandle data_pipe_consumer_handle,
     78                                    const void** buffer,
     79                                    uint32_t* buffer_num_elements,
     80                                    MojoReadDataFlags flags) OVERRIDE;
     81   virtual MojoResult EndReadData(MojoHandle data_pipe_consumer_handle,
     82                                  uint32_t num_elements_read) OVERRIDE;
     83 
     84  private:
     85   friend class test::CoreTestBase;
     86 
     87   // The |busy| member is used only to deal with functions (in particular
     88   // |WriteMessage()|) that want to hold on to a dispatcher and later remove it
     89   // from the handle table, without holding on to the handle table lock.
     90   //
     91   // For example, if |WriteMessage()| is called with a handle to be sent, (under
     92   // the handle table lock) it must first check that that handle is not busy (if
     93   // it is busy, then it fails with |MOJO_RESULT_BUSY|) and then marks it as
     94   // busy. To avoid deadlock, it should also try to acquire the locks for all
     95   // the dispatchers for the handles that it is sending (and fail with
     96   // |MOJO_RESULT_BUSY| if the attempt fails). At this point, it can release the
     97   // handle table lock.
     98   //
     99   // If |Close()| is simultaneously called on that handle, it too checks if the
    100   // handle is marked busy. If it is, it fails (with |MOJO_RESULT_BUSY|). This
    101   // prevents |WriteMessage()| from sending a handle that has been closed (or
    102   // learning about this too late).
    103   //
    104   // TODO(vtl): Move this implementation note.
    105   // To properly cancel waiters and avoid other races, |WriteMessage()| does not
    106   // transfer dispatchers from one handle to another, even when sending a
    107   // message in-process. Instead, it must transfer the "contents" of the
    108   // dispatcher to a new dispatcher, and then close the old dispatcher. If this
    109   // isn't done, in the in-process case, calls on the old handle may complete
    110   // after the the message has been received and a new handle created (and
    111   // possibly even after calls have been made on the new handle).
    112   struct HandleTableEntry {
    113     HandleTableEntry();
    114     explicit HandleTableEntry(const scoped_refptr<Dispatcher>& dispatcher);
    115     ~HandleTableEntry();
    116 
    117     scoped_refptr<Dispatcher> dispatcher;
    118     bool busy;
    119   };
    120   typedef base::hash_map<MojoHandle, HandleTableEntry> HandleTableMap;
    121 
    122   CoreImpl();
    123   virtual ~CoreImpl();
    124 
    125   // Looks up the dispatcher for the given handle. Returns null if the handle is
    126   // invalid.
    127   scoped_refptr<Dispatcher> GetDispatcher(MojoHandle handle);
    128 
    129   // Assigns a new handle for the given dispatcher (which must be valid);
    130   // returns |MOJO_HANDLE_INVALID| on failure (due to hitting resource limits).
    131   // Must be called under |handle_table_lock_|.
    132   MojoHandle AddDispatcherNoLock(const scoped_refptr<Dispatcher>& dispatcher);
    133 
    134   // Internal implementation of |Wait()| and |WaitMany()|; doesn't do basic
    135   // validation of arguments.
    136   MojoResult WaitManyInternal(const MojoHandle* handles,
    137                               const MojoWaitFlags* flags,
    138                               uint32_t num_handles,
    139                               MojoDeadline deadline);
    140 
    141   // ---------------------------------------------------------------------------
    142 
    143   // TODO(vtl): |handle_table_lock_| should be a reader-writer lock (if only we
    144   // had them).
    145   base::Lock handle_table_lock_;  // Protects the immediately-following members.
    146   HandleTableMap handle_table_;
    147   MojoHandle next_handle_;  // Invariant: never |MOJO_HANDLE_INVALID|.
    148 
    149   // ---------------------------------------------------------------------------
    150 
    151   DISALLOW_COPY_AND_ASSIGN(CoreImpl);
    152 };
    153 
    154 }  // namespace system
    155 }  // namespace mojo
    156 
    157 #endif  // MOJO_SYSTEM_CORE_IMPL_H_
    158