Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / mojo / system / channel.h
index 4af6daa..883d88a 100644 (file)
@@ -59,11 +59,9 @@ class MOJO_SYSTEM_IMPL_EXPORT Channel
 
   // This must be called on the creation thread before any other methods are
   // called, and before references to this object are given to any other
-  // threads. |handle| should be a handle to a (platform-appropriate)
-  // bidirectional communication channel (e.g., a socket on POSIX, a named pipe
-  // on Windows). Returns true on success. On failure, no other methods should
-  // be called (including |Shutdown()|).
-  bool Init(embedder::ScopedPlatformHandle handle);
+  // threads. |raw_channel| should be uninitialized. Returns true on success. On
+  // failure, no other methods should be called (including |Shutdown()|).
+  bool Init(scoped_ptr<RawChannel> raw_channel);
 
   // This must be called on the creation thread before destruction (which can
   // happen on any thread).
@@ -74,10 +72,19 @@ class MOJO_SYSTEM_IMPL_EXPORT Channel
   // which it returns. The first message pipe endpoint attached will always have
   // |kBootstrapEndpointId| as its local ID. (For bootstrapping, this occurs on
   // both sides, so one should use |kBootstrapEndpointId| for the remote ID for
-  // the first message pipe across a channel.)
+  // the first message pipe across a channel.) Returns |kInvalidEndpointId| on
+  // failure.
+  // TODO(vtl): Maybe limit the number of attached message pipes.
   MessageInTransit::EndpointId AttachMessagePipeEndpoint(
-      scoped_refptr<MessagePipe> message_pipe, unsigned port);
-  void RunMessagePipeEndpoint(MessageInTransit::EndpointId local_id,
+      scoped_refptr<MessagePipe> message_pipe,
+      unsigned port);
+
+  // Runs the message pipe with the given |local_id| (previously attached), with
+  // the given |remote_id| (negotiated using some other means, e.g., over an
+  // existing message pipe; see comments above for the bootstrap case). Returns
+  // false on failure, in particular if no message pipe with |local_id| is
+  // attached.
+  bool RunMessagePipeEndpoint(MessageInTransit::EndpointId local_id,
                               MessageInTransit::EndpointId remote_id);
 
   // Tells the other side of the channel to run a message pipe endpoint (which
@@ -97,12 +104,40 @@ class MOJO_SYSTEM_IMPL_EXPORT Channel
   // |FlushWriteBufferAndShutdown()| or something like that.
   bool IsWriteBufferEmpty();
 
-  // This removes the message pipe/port's endpoint (with the given local ID,
+  // This removes the message pipe/port's endpoint (with the given local ID and
+  // given remote ID, which should be |kInvalidEndpointId| if not yet running),
   // returned by |AttachMessagePipeEndpoint()| from this channel. After this is
   // called, |local_id| may be reused for another message pipe.
-  void DetachMessagePipeEndpoint(MessageInTransit::EndpointId local_id);
+  void DetachMessagePipeEndpoint(MessageInTransit::EndpointId local_id,
+                                 MessageInTransit::EndpointId remote_id);
+
+  // See |RawChannel::GetSerializedPlatformHandleSize()|.
+  size_t GetSerializedPlatformHandleSize() const;
 
  private:
+  struct EndpointInfo {
+    enum State {
+      // Attached, possibly running or not.
+      STATE_NORMAL,
+      // "Zombie" states:
+      // Waiting for |DetachMessagePipeEndpoint()| before removing.
+      STATE_WAIT_LOCAL_DETACH,
+      // Waiting for a |kSubtypeChannelRemoveMessagePipeEndpointAck| before
+      // removing.
+      STATE_WAIT_REMOTE_REMOVE_ACK,
+      // Waiting for both of the above conditions before removing.
+      STATE_WAIT_LOCAL_DETACH_AND_REMOTE_REMOVE_ACK,
+    };
+
+    EndpointInfo();
+    EndpointInfo(scoped_refptr<MessagePipe> message_pipe, unsigned port);
+    ~EndpointInfo();
+
+    State state;
+    scoped_refptr<MessagePipe> message_pipe;
+    unsigned port;
+  };
+
   friend class base::RefCountedThreadSafe<Channel>;
   virtual ~Channel();
 
@@ -116,19 +151,24 @@ class MOJO_SYSTEM_IMPL_EXPORT Channel
   void OnReadMessageForDownstream(const MessageInTransit::View& message_view);
   void OnReadMessageForChannel(const MessageInTransit::View& message_view);
 
+  // Removes the message pipe endpoint with the given local ID, which must exist
+  // and be a zombie, and given remote ID. Returns false on failure, in
+  // particular if no message pipe with |local_id| is attached.
+  bool RemoveMessagePipeEndpoint(MessageInTransit::EndpointId local_id,
+                                 MessageInTransit::EndpointId remote_id);
+
   // Handles errors (e.g., invalid messages) from the remote side.
   void HandleRemoteError(const base::StringPiece& error_message);
   // Handles internal errors/failures from the local side.
   void HandleLocalError(const base::StringPiece& error_message);
 
-  struct EndpointInfo {
-    EndpointInfo();
-    EndpointInfo(scoped_refptr<MessagePipe> message_pipe, unsigned port);
-    ~EndpointInfo();
+  // Helper to send channel control messages. Returns true on success. Should be
+  // called *without* |lock_| held.
+  bool SendControlMessage(MessageInTransit::Subtype subtype,
+                          MessageInTransit::EndpointId source_id,
+                          MessageInTransit::EndpointId destination_id);
 
-    scoped_refptr<MessagePipe> message_pipe;
-    unsigned port;
-  };
+  bool is_running_no_lock() const { return is_running_; }
 
   base::ThreadChecker creation_thread_checker_;
 
@@ -140,6 +180,7 @@ class MOJO_SYSTEM_IMPL_EXPORT Channel
   base::Lock lock_;  // Protects the members below.
 
   scoped_ptr<RawChannel> raw_channel_;
+  bool is_running_;
 
   typedef base::hash_map<MessageInTransit::EndpointId, EndpointInfo>
       IdToEndpointInfoMap;