| OLD | NEW |
| (Empty) |
| 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 #include "mojo/edk/system/message_pipe_dispatcher.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "mojo/edk/system/configuration.h" | |
| 9 #include "mojo/edk/system/local_message_pipe_endpoint.h" | |
| 10 #include "mojo/edk/system/memory.h" | |
| 11 #include "mojo/edk/system/message_pipe.h" | |
| 12 #include "mojo/edk/system/options_validation.h" | |
| 13 #include "mojo/edk/system/proxy_message_pipe_endpoint.h" | |
| 14 | |
| 15 namespace mojo { | |
| 16 namespace system { | |
| 17 | |
| 18 const unsigned kInvalidPort = static_cast<unsigned>(-1); | |
| 19 | |
| 20 // MessagePipeDispatcher ------------------------------------------------------- | |
| 21 | |
| 22 // static | |
| 23 const MojoCreateMessagePipeOptions | |
| 24 MessagePipeDispatcher::kDefaultCreateOptions = { | |
| 25 static_cast<uint32_t>(sizeof(MojoCreateMessagePipeOptions)), | |
| 26 MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE}; | |
| 27 | |
| 28 MessagePipeDispatcher::MessagePipeDispatcher( | |
| 29 const MojoCreateMessagePipeOptions& /*validated_options*/) | |
| 30 : port_(kInvalidPort) { | |
| 31 } | |
| 32 | |
| 33 // static | |
| 34 MojoResult MessagePipeDispatcher::ValidateCreateOptions( | |
| 35 UserPointer<const MojoCreateMessagePipeOptions> in_options, | |
| 36 MojoCreateMessagePipeOptions* out_options) { | |
| 37 const MojoCreateMessagePipeOptionsFlags kKnownFlags = | |
| 38 MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE; | |
| 39 | |
| 40 *out_options = kDefaultCreateOptions; | |
| 41 if (in_options.IsNull()) | |
| 42 return MOJO_RESULT_OK; | |
| 43 | |
| 44 UserOptionsReader<MojoCreateMessagePipeOptions> reader(in_options); | |
| 45 if (!reader.is_valid()) | |
| 46 return MOJO_RESULT_INVALID_ARGUMENT; | |
| 47 | |
| 48 if (!OPTIONS_STRUCT_HAS_MEMBER(MojoCreateMessagePipeOptions, flags, reader)) | |
| 49 return MOJO_RESULT_OK; | |
| 50 if ((reader.options().flags & ~kKnownFlags)) | |
| 51 return MOJO_RESULT_UNIMPLEMENTED; | |
| 52 out_options->flags = reader.options().flags; | |
| 53 | |
| 54 // Checks for fields beyond |flags|: | |
| 55 | |
| 56 // (Nothing here yet.) | |
| 57 | |
| 58 return MOJO_RESULT_OK; | |
| 59 } | |
| 60 | |
| 61 void MessagePipeDispatcher::Init(scoped_refptr<MessagePipe> message_pipe, | |
| 62 unsigned port) { | |
| 63 DCHECK(message_pipe); | |
| 64 DCHECK(port == 0 || port == 1); | |
| 65 | |
| 66 message_pipe_ = message_pipe; | |
| 67 port_ = port; | |
| 68 } | |
| 69 | |
| 70 Dispatcher::Type MessagePipeDispatcher::GetType() const { | |
| 71 return kTypeMessagePipe; | |
| 72 } | |
| 73 | |
| 74 // static | |
| 75 scoped_refptr<MessagePipeDispatcher> | |
| 76 MessagePipeDispatcher::CreateRemoteMessagePipe( | |
| 77 scoped_refptr<ChannelEndpoint>* channel_endpoint) { | |
| 78 scoped_refptr<MessagePipe> message_pipe( | |
| 79 MessagePipe::CreateLocalProxy(channel_endpoint)); | |
| 80 scoped_refptr<MessagePipeDispatcher> dispatcher( | |
| 81 new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions)); | |
| 82 dispatcher->Init(message_pipe, 0); | |
| 83 return dispatcher; | |
| 84 } | |
| 85 | |
| 86 // static | |
| 87 scoped_refptr<MessagePipeDispatcher> MessagePipeDispatcher::Deserialize( | |
| 88 Channel* channel, | |
| 89 const void* source, | |
| 90 size_t size) { | |
| 91 unsigned port = kInvalidPort; | |
| 92 scoped_refptr<MessagePipe> message_pipe; | |
| 93 if (!MessagePipe::Deserialize(channel, source, size, &message_pipe, &port)) | |
| 94 return nullptr; | |
| 95 DCHECK(message_pipe); | |
| 96 DCHECK(port == 0 || port == 1); | |
| 97 | |
| 98 scoped_refptr<MessagePipeDispatcher> dispatcher( | |
| 99 new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions)); | |
| 100 dispatcher->Init(message_pipe, port); | |
| 101 return dispatcher; | |
| 102 } | |
| 103 | |
| 104 MessagePipeDispatcher::~MessagePipeDispatcher() { | |
| 105 // |Close()|/|CloseImplNoLock()| should have taken care of the pipe. | |
| 106 DCHECK(!message_pipe_); | |
| 107 } | |
| 108 | |
| 109 MessagePipe* MessagePipeDispatcher::GetMessagePipeNoLock() const { | |
| 110 lock().AssertAcquired(); | |
| 111 return message_pipe_.get(); | |
| 112 } | |
| 113 | |
| 114 unsigned MessagePipeDispatcher::GetPortNoLock() const { | |
| 115 lock().AssertAcquired(); | |
| 116 return port_; | |
| 117 } | |
| 118 | |
| 119 void MessagePipeDispatcher::CancelAllAwakablesNoLock() { | |
| 120 lock().AssertAcquired(); | |
| 121 message_pipe_->CancelAllAwakables(port_); | |
| 122 } | |
| 123 | |
| 124 void MessagePipeDispatcher::CloseImplNoLock() { | |
| 125 lock().AssertAcquired(); | |
| 126 message_pipe_->Close(port_); | |
| 127 message_pipe_ = nullptr; | |
| 128 port_ = kInvalidPort; | |
| 129 } | |
| 130 | |
| 131 scoped_refptr<Dispatcher> | |
| 132 MessagePipeDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() { | |
| 133 lock().AssertAcquired(); | |
| 134 | |
| 135 // TODO(vtl): Currently, there are no options, so we just use | |
| 136 // |kDefaultCreateOptions|. Eventually, we'll have to duplicate the options | |
| 137 // too. | |
| 138 scoped_refptr<MessagePipeDispatcher> rv = | |
| 139 new MessagePipeDispatcher(kDefaultCreateOptions); | |
| 140 rv->Init(message_pipe_, port_); | |
| 141 message_pipe_ = nullptr; | |
| 142 port_ = kInvalidPort; | |
| 143 return scoped_refptr<Dispatcher>(rv.get()); | |
| 144 } | |
| 145 | |
| 146 MojoResult MessagePipeDispatcher::WriteMessageImplNoLock( | |
| 147 UserPointer<const void> bytes, | |
| 148 uint32_t num_bytes, | |
| 149 std::vector<DispatcherTransport>* transports, | |
| 150 MojoWriteMessageFlags flags) { | |
| 151 DCHECK(!transports || | |
| 152 (transports->size() > 0 && | |
| 153 transports->size() <= GetConfiguration().max_message_num_handles)); | |
| 154 | |
| 155 lock().AssertAcquired(); | |
| 156 | |
| 157 if (num_bytes > GetConfiguration().max_message_num_bytes) | |
| 158 return MOJO_RESULT_RESOURCE_EXHAUSTED; | |
| 159 | |
| 160 return message_pipe_->WriteMessage(port_, bytes, num_bytes, transports, | |
| 161 flags); | |
| 162 } | |
| 163 | |
| 164 MojoResult MessagePipeDispatcher::ReadMessageImplNoLock( | |
| 165 UserPointer<void> bytes, | |
| 166 UserPointer<uint32_t> num_bytes, | |
| 167 DispatcherVector* dispatchers, | |
| 168 uint32_t* num_dispatchers, | |
| 169 MojoReadMessageFlags flags) { | |
| 170 lock().AssertAcquired(); | |
| 171 return message_pipe_->ReadMessage(port_, bytes, num_bytes, dispatchers, | |
| 172 num_dispatchers, flags); | |
| 173 } | |
| 174 | |
| 175 HandleSignalsState MessagePipeDispatcher::GetHandleSignalsStateImplNoLock() | |
| 176 const { | |
| 177 lock().AssertAcquired(); | |
| 178 return message_pipe_->GetHandleSignalsState(port_); | |
| 179 } | |
| 180 | |
| 181 MojoResult MessagePipeDispatcher::AddAwakableImplNoLock( | |
| 182 Awakable* awakable, | |
| 183 MojoHandleSignals signals, | |
| 184 uint32_t context, | |
| 185 HandleSignalsState* signals_state) { | |
| 186 lock().AssertAcquired(); | |
| 187 return message_pipe_->AddAwakable(port_, awakable, signals, context, | |
| 188 signals_state); | |
| 189 } | |
| 190 | |
| 191 void MessagePipeDispatcher::RemoveAwakableImplNoLock( | |
| 192 Awakable* awakable, | |
| 193 HandleSignalsState* signals_state) { | |
| 194 lock().AssertAcquired(); | |
| 195 message_pipe_->RemoveAwakable(port_, awakable, signals_state); | |
| 196 } | |
| 197 | |
| 198 void MessagePipeDispatcher::StartSerializeImplNoLock( | |
| 199 Channel* channel, | |
| 200 size_t* max_size, | |
| 201 size_t* max_platform_handles) { | |
| 202 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. | |
| 203 return message_pipe_->StartSerialize(port_, channel, max_size, | |
| 204 max_platform_handles); | |
| 205 } | |
| 206 | |
| 207 bool MessagePipeDispatcher::EndSerializeAndCloseImplNoLock( | |
| 208 Channel* channel, | |
| 209 void* destination, | |
| 210 size_t* actual_size, | |
| 211 embedder::PlatformHandleVector* platform_handles) { | |
| 212 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. | |
| 213 | |
| 214 bool rv = message_pipe_->EndSerialize(port_, channel, destination, | |
| 215 actual_size, platform_handles); | |
| 216 message_pipe_ = nullptr; | |
| 217 port_ = kInvalidPort; | |
| 218 return rv; | |
| 219 } | |
| 220 | |
| 221 // MessagePipeDispatcherTransport ---------------------------------------------- | |
| 222 | |
| 223 MessagePipeDispatcherTransport::MessagePipeDispatcherTransport( | |
| 224 DispatcherTransport transport) | |
| 225 : DispatcherTransport(transport) { | |
| 226 DCHECK_EQ(message_pipe_dispatcher()->GetType(), Dispatcher::kTypeMessagePipe); | |
| 227 } | |
| 228 | |
| 229 } // namespace system | |
| 230 } // namespace mojo | |
| OLD | NEW |