14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file.
44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifndef MOJO_SYSTEM_MESSAGE_PIPE_H_
64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#define MOJO_SYSTEM_MESSAGE_PIPE_H_
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <stdint.h>
9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <vector>
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/macros.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/memory/ref_counted.h"
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/synchronization/lock.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "mojo/public/c/system/message_pipe.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "mojo/public/c/system/types.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "mojo/system/dispatcher.h"
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "mojo/system/handle_signals_state.h"
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "mojo/system/memory.h"
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "mojo/system/message_in_transit.h"
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "mojo/system/message_pipe_endpoint.h"
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "mojo/system/system_impl_export.h"
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace mojo {
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace system {
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass ChannelEndpoint;
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class Waiter;
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// |MessagePipe| is the secondary object implementing a message pipe (see the
32a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// explanatory comment in core.cc). It is typically owned by the dispatcher(s)
33a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// corresponding to the local endpoints. This class is thread-safe.
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class MOJO_SYSTEM_IMPL_EXPORT MessagePipe
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : public base::RefCountedThreadSafe<MessagePipe> {
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Creates a |MessagePipe| with two new |LocalMessagePipeEndpoint|s.
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static MessagePipe* CreateLocalLocal();
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Creates a |MessagePipe| with a |LocalMessagePipeEndpoint| on port 0 and a
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |ProxyMessagePipeEndpoint| on port 1. |*channel_endpoint| is set to the
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // (newly-created) |ChannelEndpoint| for the latter.
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static MessagePipe* CreateLocalProxy(
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      scoped_refptr<ChannelEndpoint>* channel_endpoint);
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Creates a |MessagePipe| with a |ProxyMessagePipeEndpoint| on port 0 and a
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |LocalMessagePipeEndpoint| on port 1. |*channel_endpoint| is set to the
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // (newly-created) |ChannelEndpoint| for the former.
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Note: This is really only needed in tests (outside of tests, this
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // configuration arises from a local message pipe having its port 0
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // "converted" using |ConvertLocalToProxy()|).
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static MessagePipe* CreateProxyLocal(
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      scoped_refptr<ChannelEndpoint>* channel_endpoint);
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Gets the other port number (i.e., 0 -> 1, 1 -> 0).
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static unsigned GetPeerPort(unsigned port);
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Gets the type of the endpoint (used for assertions, etc.).
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MessagePipeEndpoint::Type GetType(unsigned port);
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // These are called by the dispatcher to implement its methods of
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // corresponding names. In all cases, the port |port| must be open.
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void CancelAllWaiters(unsigned port);
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void Close(unsigned port);
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Unlike |MessagePipeDispatcher::WriteMessage()|, this does not validate its
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // arguments.
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MojoResult WriteMessage(unsigned port,
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          UserPointer<const void> bytes,
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          uint32_t num_bytes,
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          std::vector<DispatcherTransport>* transports,
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          MojoWriteMessageFlags flags);
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MojoResult ReadMessage(unsigned port,
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         UserPointer<void> bytes,
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         UserPointer<uint32_t> num_bytes,
75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                         DispatcherVector* dispatchers,
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         uint32_t* num_dispatchers,
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                         MojoReadMessageFlags flags);
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  HandleSignalsState GetHandleSignalsState(unsigned port) const;
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MojoResult AddWaiter(unsigned port,
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       Waiter* waiter,
81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       MojoHandleSignals signals,
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       uint32_t context,
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       HandleSignalsState* signals_state);
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void RemoveWaiter(unsigned port,
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    Waiter* waiter,
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    HandleSignalsState* signals_state);
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // This is called by the dispatcher to convert a local endpoint to a proxy
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // endpoint.
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<ChannelEndpoint> ConvertLocalToProxy(unsigned port);
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // This is used by |Channel| to enqueue messages (typically to a
935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // |LocalMessagePipeEndpoint|). Unlike |WriteMessage()|, |port| is the
945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // *destination* port.
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MojoResult EnqueueMessage(unsigned port,
965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                            scoped_ptr<MessageInTransit> message);
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // This is used by |Channel|. TODO(vtl): Rename it (and have the
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |ChannelEndpoint| call it instead).
1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void OnRemove(unsigned port);
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MessagePipe();
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  friend class base::RefCountedThreadSafe<MessagePipe>;
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual ~MessagePipe();
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // This is used internally by |WriteMessage()| and by |EnqueueMessage()|.
1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // |transports| may be non-null only if it's nonempty and |message| has no
1105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // dispatchers attached.
1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  MojoResult EnqueueMessageInternal(
1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      unsigned port,
1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      scoped_ptr<MessageInTransit> message,
1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      std::vector<DispatcherTransport>* transports);
1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Helper for |EnqueueMessageInternal()|. Must be called with |lock_| held.
1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  MojoResult AttachTransportsNoLock(
1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      unsigned port,
1195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      MessageInTransit* message,
1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      std::vector<DispatcherTransport>* transports);
1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Used by |EnqueueMessageInternal()| to handle control messages that are
1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // actually meant for us.
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MojoResult HandleControlMessage(unsigned port,
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                  scoped_ptr<MessageInTransit> message);
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::Lock lock_;  // Protects the following members.
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<MessagePipeEndpoint> endpoints_[2];
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MessagePipe);
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace system
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace mojo
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif  // MOJO_SYSTEM_MESSAGE_PIPE_H_
137