Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / mojo / system / dispatcher.h
index c6ef752..4e9e13f 100644 (file)
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/synchronization/lock.h"
+#include "mojo/embedder/platform_handle.h"
 #include "mojo/public/c/system/core.h"
-// TODO(vtl): We need this since we can't forward declare
-// |RawSharedBuffer::Mapping|. Maybe fix this.
-#include "mojo/system/raw_shared_buffer.h"
 #include "mojo/system/system_impl_export.h"
 
 namespace mojo {
 namespace system {
 
 class Channel;
-class CoreImpl;
+class Core;
 class Dispatcher;
 class DispatcherTransport;
+class HandleTable;
 class LocalMessagePipeEndpoint;
-class MessageInTransit;
 class ProxyMessagePipeEndpoint;
+class RawSharedBufferMapping;
+class TransportData;
 class Waiter;
 
+typedef std::vector<scoped_refptr<Dispatcher> > DispatcherVector;
+
 namespace test {
 
 // Test helper. We need to declare it here so we can friend it.
@@ -77,12 +79,11 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher :
   // |dispatchers| must be non-null but empty, if |num_dispatchers| is non-null
   // and nonzero. On success, it will be set to the dispatchers to be received
   // (and assigned handles) as part of the message.
-  MojoResult ReadMessage(
-      void* bytes,
-      uint32_t* num_bytes,
-      std::vector<scoped_refptr<Dispatcher> >* dispatchers,
-      uint32_t* num_dispatchers,
-      MojoReadMessageFlags flags);
+  MojoResult ReadMessage(void* bytes,
+                         uint32_t* num_bytes,
+                         DispatcherVector* dispatchers,
+                         uint32_t* num_dispatchers,
+                         MojoReadMessageFlags flags);
   MojoResult WriteData(const void* elements,
                        uint32_t* elements_num_bytes,
                        MojoWriteDataFlags flags);
@@ -106,7 +107,7 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher :
   MojoResult MapBuffer(uint64_t offset,
                        uint64_t num_bytes,
                        MojoMapBufferFlags flags,
-                       scoped_ptr<RawSharedBuffer::Mapping>* mapping);
+                       scoped_ptr<RawSharedBufferMapping>* mapping);
 
   // Adds a waiter to this dispatcher. The waiter will be woken up when this
   // object changes state to satisfy |flags| with result |wake_result| (which
@@ -126,17 +127,18 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher :
   void RemoveWaiter(Waiter* waiter);
 
   // A dispatcher must be put into a special state in order to be sent across a
-  // message pipe. Outside of tests, only |CoreImplAccess| is allowed to do
+  // message pipe. Outside of tests, only |HandleTableAccess| is allowed to do
   // this, since there are requirements on the handle table (see below).
   //
   // In this special state, only a restricted set of operations is allowed.
   // These are the ones available as |DispatcherTransport| methods. Other
   // |Dispatcher| methods must not be called until |DispatcherTransport::End()|
   // has been called.
-  class CoreImplAccess {
+  class HandleTableAccess {
    private:
-    friend class CoreImpl;
-    // Tests also need this, to avoid needing |CoreImpl|.
+    friend class Core;
+    friend class HandleTable;
+    // Tests also need this, to avoid needing |Core|.
     friend DispatcherTransport test::DispatcherTryStartTransport(Dispatcher*);
 
     // This must be called under the handle table lock and only if the handle
@@ -145,32 +147,36 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher :
     static DispatcherTransport TryStartTransport(Dispatcher* dispatcher);
   };
 
-  // A |MessageInTransit| may serialize dispatchers that are attached to it to a
-  // given |Channel| and then (probably in a different process) deserialize.
+  // A |TransportData| may serialize dispatchers that are given to it (and which
+  // were previously attached to the |MessageInTransit| that is creating it) to
+  // a given |Channel| and then (probably in a different process) deserialize.
+  // Note that the |MessageInTransit| "owns" (i.e., has the only ref to) these
+  // dispatchers, so there are no locking issues. (There's no lock ordering
+  // issue, and in fact no need to take dispatcher locks at all.)
   // TODO(vtl): Consider making another wrapper similar to |DispatcherTransport|
   // (but with an owning, unique reference), and having
   // |CreateEquivalentDispatcherAndCloseImplNoLock()| return that wrapper (and
-  // |MessageInTransit| only holding on to such wrappers).
-  class MessageInTransitAccess {
+  // |MessageInTransit|, etc. only holding on to such wrappers).
+  class TransportDataAccess {
    private:
-    friend class MessageInTransit;
+    friend class TransportData;
 
     // Serialization API. These functions may only be called on such
     // dispatchers. (|channel| is the |Channel| to which the dispatcher is to be
     // serialized.) See the |Dispatcher| methods of the same names for more
     // details.
-    // TODO(vtl): Consider replacing this API below with a proper two-phase one
-    // ("StartSerialize()" and "EndSerializeAndClose()", with the lock possibly
-    // being held across their invocations).
-    static size_t GetMaximumSerializedSize(const Dispatcher* dispatcher,
-                                           const Channel* channel);
-    static bool SerializeAndClose(Dispatcher* dispatcher,
-                                  Channel* channel,
-                                  void* destination,
-                                  size_t* actual_size);
+    static void StartSerialize(Dispatcher* dispatcher,
+                               Channel* channel,
+                               size_t* max_size,
+                               size_t* max_platform_handles);
+    static bool EndSerializeAndClose(
+        Dispatcher* dispatcher,
+        Channel* channel,
+        void* destination,
+        size_t* actual_size,
+        std::vector<embedder::PlatformHandle>* platform_handles);
 
     // Deserialization API.
-    // TODO(vtl): Implement this.
     static scoped_refptr<Dispatcher> Deserialize(Channel* channel,
                                                  int32_t type,
                                                  const void* source,
@@ -200,12 +206,11 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher :
       uint32_t num_bytes,
       std::vector<DispatcherTransport>* transports,
       MojoWriteMessageFlags flags);
-  virtual MojoResult ReadMessageImplNoLock(
-      void* bytes,
-      uint32_t* num_bytes,
-      std::vector<scoped_refptr<Dispatcher> >* dispatchers,
-      uint32_t* num_dispatchers,
-      MojoReadMessageFlags flags);
+  virtual MojoResult ReadMessageImplNoLock(void* bytes,
+                                           uint32_t* num_bytes,
+                                           DispatcherVector* dispatchers,
+                                           uint32_t* num_dispatchers,
+                                           MojoReadMessageFlags flags);
   virtual MojoResult WriteDataImplNoLock(const void* elements,
                                          uint32_t* num_bytes,
                                          MojoWriteDataFlags flags);
@@ -227,7 +232,7 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher :
       uint64_t offset,
       uint64_t num_bytes,
       MojoMapBufferFlags flags,
-      scoped_ptr<RawSharedBuffer::Mapping>* mapping);
+      scoped_ptr<RawSharedBufferMapping>* mapping);
   virtual MojoResult AddWaiterImplNoLock(Waiter* waiter,
                                          MojoWaitFlags flags,
                                          MojoResult wake_result);
@@ -237,13 +242,24 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher :
   // (described below). They will only be called on a dispatcher that's attached
   // to and "owned" by a |MessageInTransit|. See the non-"impl" versions for
   // more information.
+  //
+  // Note: |StartSerializeImplNoLock()| is actually called with |lock_| NOT
+  // held, since the dispatcher should only be accessible to the calling thread.
+  // On Debug builds, |EndSerializeAndCloseImplNoLock()| is called with |lock_|
+  // held, to satisfy any |lock_.AssertAcquired()| (e.g., in |CloseImplNoLock()|
+  // -- and anything it calls); disentangling those assertions is
+  // difficult/fragile, and would weaken our general checking of invariants.
+  //
   // TODO(vtl): Consider making these pure virtual once most things support
   // being passed over a message pipe.
-  virtual size_t GetMaximumSerializedSizeImplNoLock(
-      const Channel* channel) const;
-  virtual bool SerializeAndCloseImplNoLock(Channel* channel,
-                                           void* destination,
-                                           size_t* actual_size);
+  virtual void StartSerializeImplNoLock(Channel* channel,
+                                        size_t* max_size,
+                                        size_t* max_platform_handles);
+  virtual bool EndSerializeAndCloseImplNoLock(
+      Channel* channel,
+      void* destination,
+      size_t* actual_size,
+      std::vector<embedder::PlatformHandle>* platform_handles);
 
   // Available to subclasses. (Note: Returns a non-const reference, just like
   // |base::AutoLock|'s constructor takes a non-const reference.)
@@ -271,25 +287,39 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher :
   scoped_refptr<Dispatcher> CreateEquivalentDispatcherAndCloseNoLock();
 
   // API to serialize dispatchers to a |Channel|, exposed to only
-  // |MessageInTransit| (via |MessageInTransitAccess|). They may only be called
-  // on a dispatcher attached to a |MessageInTransit| (and in particular not in
+  // |TransportData| (via |TransportData|). They may only be called on a
+  // dispatcher attached to a |MessageInTransit| (and in particular not in
   // |CoreImpl|'s handle table).
-  // Gets the maximum amount of space that'll be needed to serialize this
-  // dispatcher to the given |Channel|. This amount must be no greater than
-  // |MessageInTransit::kMaxSerializedDispatcherSize| (message_in_transit.h).
-  // Returns zero to indicate that this dispatcher cannot be serialized (to the
-  // given |Channel|).
-  size_t GetMaximumSerializedSize(const Channel* channel) const;
-  // Serializes this dispatcher to the given |Channel| by writing to
-  // |destination| and then closes this dispatcher. It may write no more than
-  // was indicated by |GetMaximumSerializedSize()|. (WARNING: Beware of races,
-  // e.g., if something can be mutated between the two calls!) Returns true on
-  // success, in which case |*actual_size| is set to the amount it actually
-  // wrote to |destination|. On failure, |*actual_size| should not be modified;
-  // however, the dispatcher will still be closed.
-  bool SerializeAndClose(Channel* channel,
-                         void* destination,
-                         size_t* actual_size);
+  //
+  // Starts the serialization. Returns (via the two "out" parameters) the
+  // maximum amount of space that may be needed to serialize this dispatcher to
+  // the given |Channel| (no more than
+  // |TransportData::kMaxSerializedDispatcherSize|) and the maximum number of
+  // |PlatformHandle|s that may need to be attached (no more than
+  // |TransportData::kMaxSerializedDispatcherPlatformHandles|). If this
+  // dispatcher cannot be serialized to the given |Channel|, |*max_size| and
+  // |*max_platform_handles| should be set to zero. A call to this method will
+  // ALWAYS be followed by a call to |EndSerializeAndClose()| (even if this
+  // dispatcher cannot be serialized to the given |Channel|).
+  void StartSerialize(Channel* channel,
+                      size_t* max_size,
+                      size_t* max_platform_handles);
+  // Completes the serialization of this dispatcher to the given |Channel| and
+  // closes it. (This call will always follow an earlier call to
+  // |StartSerialize()|, with the same |Channel|.) This does so by writing to
+  // |destination| and appending any |PlatformHandle|s needed to
+  // |platform_handles| (which may be null if no platform handles were indicated
+  // to be required to |StartSerialize()|). This may write no more than the
+  // amount indicated by |StartSerialize()|. (WARNING: Beware of races, e.g., if
+  // something can be mutated between the two calls!) Returns true on success,
+  // in which case |*actual_size| is set to the amount it actually wrote to
+  // |destination|. On failure, |*actual_size| should not be modified; however,
+  // the dispatcher will still be closed.
+  bool EndSerializeAndClose(
+      Channel* channel,
+      void* destination,
+      size_t* actual_size,
+      std::vector<embedder::PlatformHandle>* platform_handles);
 
   // This protects the following members as well as any state added by
   // subclasses.
@@ -300,8 +330,8 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher :
 };
 
 // Wrapper around a |Dispatcher| pointer, while it's being processed to be
-// passed in a message pipe. See the comment about |Dispatcher::CoreImplAccess|
-// for more details.
+// passed in a message pipe. See the comment about
+// |Dispatcher::HandleTableAccess| for more details.
 //
 // Note: This class is deliberately "thin" -- no more expensive than a
 // |Dispatcher*|.
@@ -324,7 +354,7 @@ class MOJO_SYSTEM_IMPL_EXPORT DispatcherTransport {
   Dispatcher* dispatcher() { return dispatcher_; }
 
  private:
-  friend class Dispatcher::CoreImplAccess;
+  friend class Dispatcher::HandleTableAccess;
 
   explicit DispatcherTransport(Dispatcher* dispatcher)
       : dispatcher_(dispatcher) {}