// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef MOJO_SYSTEM_PROXY_MESSAGE_PIPE_ENDPOINT_H_ #define MOJO_SYSTEM_PROXY_MESSAGE_PIPE_ENDPOINT_H_ #include #include "base/compiler_specific.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "mojo/public/c/system/core.h" #include "mojo/system/message_in_transit.h" #include "mojo/system/message_in_transit_queue.h" #include "mojo/system/message_pipe_endpoint.h" #include "mojo/system/system_impl_export.h" namespace mojo { namespace system { class Channel; class LocalMessagePipeEndpoint; class MessagePipe; // A |ProxyMessagePipeEndpoint| connects an end of a |MessagePipe| to a // |Channel|, over which it transmits and receives data (to/from another // |ProxyMessagePipeEndpoint|). So a |MessagePipe| with one endpoint local and // the other endpoint remote consists of a |LocalMessagePipeEndpoint| and a // |ProxyMessagePipeEndpoint|, with only the local endpoint being accessible via // a |MessagePipeDispatcher|. // // Like any |MessagePipeEndpoint|, a |ProxyMessagePipeEndpoint| is owned by a // |MessagePipe|. // - A |ProxyMessagePipeEndpoint| starts out *detached*, i.e., not associated // to any |Channel|. When *attached*, it gets a reference to a |Channel| and // is assigned a local ID. A |ProxyMessagePipeEndpoint| must be detached // before destruction; this is done inside |Close()|. // - When attached, a |ProxyMessagePipeEndpoint| starts out not running. When // run, it gets a remote ID. class MOJO_SYSTEM_IMPL_EXPORT ProxyMessagePipeEndpoint : public MessagePipeEndpoint { public: ProxyMessagePipeEndpoint(); // Constructs a |ProxyMessagePipeEndpoint| that replaces the given // |LocalMessagePipeEndpoint| (which this constructor will close), taking its // message queue's contents. This is done when transferring a message pipe // handle over a remote message pipe. ProxyMessagePipeEndpoint( LocalMessagePipeEndpoint* local_message_pipe_endpoint, bool is_peer_open); virtual ~ProxyMessagePipeEndpoint(); // |MessagePipeEndpoint| implementation: virtual Type GetType() const OVERRIDE; virtual bool OnPeerClose() OVERRIDE; virtual void EnqueueMessage(scoped_ptr message) OVERRIDE; virtual void Attach(scoped_refptr channel, MessageInTransit::EndpointId local_id) OVERRIDE; virtual bool Run(MessageInTransit::EndpointId remote_id) OVERRIDE; virtual void OnRemove() OVERRIDE; private: void Detach(); #ifdef NDEBUG void AssertConsistentState() const {} #else void AssertConsistentState() const; #endif bool is_attached() const { return !!channel_.get(); } bool is_running() const { return remote_id_ != MessageInTransit::kInvalidEndpointId; } // This should only be set if we're attached. scoped_refptr channel_; // |local_id_| should be set to something other than // |MessageInTransit::kInvalidEndpointId| when we're attached. MessageInTransit::EndpointId local_id_; // |remote_id_| being set to anything other than // |MessageInTransit::kInvalidEndpointId| indicates that we're "running", // i.e., actively able to send messages. We should only ever be running if // we're attached. MessageInTransit::EndpointId remote_id_; bool is_peer_open_; // This queue is only used while we're detached, to store messages while we're // not ready to send them yet. MessageInTransitQueue paused_message_queue_; DISALLOW_COPY_AND_ASSIGN(ProxyMessagePipeEndpoint); }; } // namespace system } // namespace mojo #endif // MOJO_SYSTEM_PROXY_MESSAGE_PIPE_ENDPOINT_H_