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_MESSAGE_PIPE_DISPATCHER_H_ 6 #define MOJO_SYSTEM_MESSAGE_PIPE_DISPATCHER_H_ 7 8 #include <utility> 9 10 #include "base/basictypes.h" 11 #include "base/compiler_specific.h" 12 #include "base/memory/ref_counted.h" 13 #include "mojo/system/dispatcher.h" 14 #include "mojo/system/system_impl_export.h" 15 16 namespace mojo { 17 namespace system { 18 19 class MessagePipe; 20 class MessagePipeDispatcherTransport; 21 22 // This is the |Dispatcher| implementation for message pipes (created by the 23 // Mojo primitive |MojoCreateMessagePipe()|). This class is thread-safe. 24 class MOJO_SYSTEM_IMPL_EXPORT MessagePipeDispatcher : public Dispatcher { 25 public: 26 // The default options to use for |MojoCreateMessagePipe()|. (Real uses 27 // should obtain this via |ValidateCreateOptions()| with a null |in_options|; 28 // this is exposed directly for testing convenience.) 29 static const MojoCreateMessagePipeOptions kDefaultCreateOptions; 30 31 MessagePipeDispatcher( 32 const MojoCreateMessagePipeOptions& /*validated_options*/); 33 34 // Validates and/or sets default options for |MojoCreateMessagePipeOptions|. 35 // If non-null, |in_options| must point to a struct of at least 36 // |in_options->struct_size| bytes. |out_options| must point to a (current) 37 // |MojoCreateMessagePipeOptions| and will be entirely overwritten on success 38 // (it may be partly overwritten on failure). 39 static MojoResult ValidateCreateOptions( 40 const MojoCreateMessagePipeOptions* in_options, 41 MojoCreateMessagePipeOptions* out_options); 42 43 // Must be called before any other methods. (This method is not thread-safe.) 44 void Init(scoped_refptr<MessagePipe> message_pipe, unsigned port); 45 46 // |Dispatcher| public methods: 47 virtual Type GetType() const OVERRIDE; 48 49 // Creates a |MessagePipe| with a local endpoint (at port 0) and a proxy 50 // endpoint, and creates/initializes a |MessagePipeDispatcher| (attached to 51 // the message pipe, port 0). 52 // TODO(vtl): This currently uses |kDefaultCreateOptions|, which is okay since 53 // there aren't any options, but eventually options should be plumbed through. 54 static std::pair<scoped_refptr<MessagePipeDispatcher>, 55 scoped_refptr<MessagePipe> > CreateRemoteMessagePipe(); 56 57 // The "opposite" of |SerializeAndClose()|. (Typically this is called by 58 // |Dispatcher::Deserialize()|.) 59 static scoped_refptr<MessagePipeDispatcher> Deserialize(Channel* channel, 60 const void* source, 61 size_t size); 62 63 private: 64 friend class MessagePipeDispatcherTransport; 65 66 virtual ~MessagePipeDispatcher(); 67 68 // Gets a dumb pointer to |message_pipe_|. This must be called under the 69 // |Dispatcher| lock (that it's a dumb pointer is okay since it's under lock). 70 // This is needed when sending handles across processes, where nontrivial, 71 // invasive work needs to be done. 72 MessagePipe* GetMessagePipeNoLock() const; 73 // Similarly for the port. 74 unsigned GetPortNoLock() const; 75 76 // |Dispatcher| protected methods: 77 virtual void CancelAllWaitersNoLock() OVERRIDE; 78 virtual void CloseImplNoLock() OVERRIDE; 79 virtual scoped_refptr<Dispatcher> 80 CreateEquivalentDispatcherAndCloseImplNoLock() OVERRIDE; 81 virtual MojoResult WriteMessageImplNoLock( 82 const void* bytes, 83 uint32_t num_bytes, 84 std::vector<DispatcherTransport>* transports, 85 MojoWriteMessageFlags flags) OVERRIDE; 86 virtual MojoResult ReadMessageImplNoLock(void* bytes, 87 uint32_t* num_bytes, 88 DispatcherVector* dispatchers, 89 uint32_t* num_dispatchers, 90 MojoReadMessageFlags flags) OVERRIDE; 91 virtual MojoResult AddWaiterImplNoLock(Waiter* waiter, 92 MojoHandleSignals signals, 93 uint32_t context) OVERRIDE; 94 virtual void RemoveWaiterImplNoLock(Waiter* waiter) OVERRIDE; 95 virtual void StartSerializeImplNoLock(Channel* channel, 96 size_t* max_size, 97 size_t* max_platform_handles) OVERRIDE; 98 virtual bool EndSerializeAndCloseImplNoLock( 99 Channel* channel, 100 void* destination, 101 size_t* actual_size, 102 embedder::PlatformHandleVector* platform_handles) OVERRIDE; 103 104 // Protected by |lock()|: 105 scoped_refptr<MessagePipe> message_pipe_; // This will be null if closed. 106 unsigned port_; 107 108 DISALLOW_COPY_AND_ASSIGN(MessagePipeDispatcher); 109 }; 110 111 class MessagePipeDispatcherTransport : public DispatcherTransport { 112 public: 113 explicit MessagePipeDispatcherTransport(DispatcherTransport transport); 114 115 MessagePipe* GetMessagePipe() { 116 return message_pipe_dispatcher()->GetMessagePipeNoLock(); 117 } 118 unsigned GetPort() { return message_pipe_dispatcher()->GetPortNoLock(); } 119 120 private: 121 MessagePipeDispatcher* message_pipe_dispatcher() { 122 return static_cast<MessagePipeDispatcher*>(dispatcher()); 123 } 124 125 // Copy and assign allowed. 126 }; 127 128 } // namespace system 129 } // namespace mojo 130 131 #endif // MOJO_SYSTEM_MESSAGE_PIPE_DISPATCHER_H_ 132