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_PROXY_MESSAGE_PIPE_ENDPOINT_H_ 6 #define MOJO_SYSTEM_PROXY_MESSAGE_PIPE_ENDPOINT_H_ 7 8 #include <stdint.h> 9 10 #include "base/compiler_specific.h" 11 #include "base/macros.h" 12 #include "base/memory/ref_counted.h" 13 #include "mojo/system/message_in_transit.h" 14 #include "mojo/system/message_in_transit_queue.h" 15 #include "mojo/system/message_pipe_endpoint.h" 16 #include "mojo/system/system_impl_export.h" 17 18 namespace mojo { 19 namespace system { 20 21 class Channel; 22 class LocalMessagePipeEndpoint; 23 class MessagePipe; 24 25 // A |ProxyMessagePipeEndpoint| connects an end of a |MessagePipe| to a 26 // |Channel|, over which it transmits and receives data (to/from another 27 // |ProxyMessagePipeEndpoint|). So a |MessagePipe| with one endpoint local and 28 // the other endpoint remote consists of a |LocalMessagePipeEndpoint| and a 29 // |ProxyMessagePipeEndpoint|, with only the local endpoint being accessible via 30 // a |MessagePipeDispatcher|. 31 // 32 // Like any |MessagePipeEndpoint|, a |ProxyMessagePipeEndpoint| is owned by a 33 // |MessagePipe|. 34 // - A |ProxyMessagePipeEndpoint| starts out *detached*, i.e., not associated 35 // to any |Channel|. When *attached*, it gets a reference to a |Channel| and 36 // is assigned a local ID. A |ProxyMessagePipeEndpoint| must be detached 37 // before destruction; this is done inside |Close()|. 38 // - When attached, a |ProxyMessagePipeEndpoint| starts out not running. When 39 // run, it gets a remote ID. 40 class MOJO_SYSTEM_IMPL_EXPORT ProxyMessagePipeEndpoint 41 : public MessagePipeEndpoint { 42 public: 43 ProxyMessagePipeEndpoint(); 44 // Constructs a |ProxyMessagePipeEndpoint| that replaces the given 45 // |LocalMessagePipeEndpoint| (which this constructor will close), taking its 46 // message queue's contents. This is done when transferring a message pipe 47 // handle over a remote message pipe. 48 ProxyMessagePipeEndpoint( 49 LocalMessagePipeEndpoint* local_message_pipe_endpoint, 50 bool is_peer_open); 51 virtual ~ProxyMessagePipeEndpoint(); 52 53 // |MessagePipeEndpoint| implementation: 54 virtual Type GetType() const OVERRIDE; 55 virtual bool OnPeerClose() OVERRIDE; 56 virtual void EnqueueMessage(scoped_ptr<MessageInTransit> message) OVERRIDE; 57 virtual void Attach(scoped_refptr<Channel> channel, 58 MessageInTransit::EndpointId local_id) OVERRIDE; 59 virtual bool Run(MessageInTransit::EndpointId remote_id) OVERRIDE; 60 virtual void OnRemove() OVERRIDE; 61 62 private: 63 void Detach(); 64 65 #ifdef NDEBUG 66 void AssertConsistentState() const {} 67 #else 68 void AssertConsistentState() const; 69 #endif 70 71 bool is_attached() const { 72 return !!channel_; 73 } 74 75 bool is_running() const { 76 return remote_id_ != MessageInTransit::kInvalidEndpointId; 77 } 78 79 // This should only be set if we're attached. 80 scoped_refptr<Channel> channel_; 81 82 // |local_id_| should be set to something other than 83 // |MessageInTransit::kInvalidEndpointId| when we're attached. 84 MessageInTransit::EndpointId local_id_; 85 86 // |remote_id_| being set to anything other than 87 // |MessageInTransit::kInvalidEndpointId| indicates that we're "running", 88 // i.e., actively able to send messages. We should only ever be running if 89 // we're attached. 90 MessageInTransit::EndpointId remote_id_; 91 92 bool is_peer_open_; 93 94 // This queue is only used while we're detached, to store messages while we're 95 // not ready to send them yet. 96 MessageInTransitQueue paused_message_queue_; 97 98 DISALLOW_COPY_AND_ASSIGN(ProxyMessagePipeEndpoint); 99 }; 100 101 } // namespace system 102 } // namespace mojo 103 104 #endif // MOJO_SYSTEM_PROXY_MESSAGE_PIPE_ENDPOINT_H_ 105