| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/edk/system/shared_buffer_dispatcher.h" | 5 #include "mojo/edk/system/shared_buffer_dispatcher.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <limits> | 10 #include <limits> |
| 11 #include <utility> | 11 #include <utility> |
| 12 | 12 |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
| 15 #include "mojo/edk/embedder/embedder_internal.h" | 15 #include "mojo/edk/embedder/embedder_internal.h" |
| 16 #include "mojo/edk/system/configuration.h" | 16 #include "mojo/edk/system/configuration.h" |
| 17 #include "mojo/edk/system/node_controller.h" | 17 #include "mojo/edk/system/node_controller.h" |
| 18 #include "mojo/edk/system/options_validation.h" | 18 #include "mojo/edk/system/options_validation.h" |
| 19 | 19 |
| 20 namespace mojo { | 20 namespace mojo { |
| 21 namespace edk { | 21 namespace edk { |
| 22 | 22 |
| 23 namespace { | 23 namespace { |
| 24 | 24 |
| 25 #pragma pack(push, 1) | 25 #pragma pack(push, 1) |
| 26 | 26 |
| 27 struct SerializedState { | 27 struct SerializedState { |
| 28 uint64_t num_bytes; | 28 uint64_t num_bytes; |
| 29 uint32_t flags; |
| 30 uint32_t padding; |
| 29 }; | 31 }; |
| 30 | 32 |
| 33 const uint32_t kSerializedStateFlagsReadOnly = 1 << 0; |
| 34 |
| 31 #pragma pack(pop) | 35 #pragma pack(pop) |
| 32 | 36 |
| 33 static_assert(sizeof(SerializedState) % 8 == 0, | 37 static_assert(sizeof(SerializedState) % 8 == 0, |
| 34 "Invalid SerializedState size."); | 38 "Invalid SerializedState size."); |
| 35 | 39 |
| 36 } // namespace | 40 } // namespace |
| 37 | 41 |
| 38 // static | 42 // static |
| 39 const MojoCreateSharedBufferOptions | 43 const MojoCreateSharedBufferOptions |
| 40 SharedBufferDispatcher::kDefaultCreateOptions = { | 44 SharedBufferDispatcher::kDefaultCreateOptions = { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 } | 138 } |
| 135 | 139 |
| 136 // Starts off invalid, which is what we want. | 140 // Starts off invalid, which is what we want. |
| 137 PlatformHandle platform_handle; | 141 PlatformHandle platform_handle; |
| 138 // We take ownership of the handle, so we have to invalidate the one in | 142 // We take ownership of the handle, so we have to invalidate the one in |
| 139 // |platform_handles|. | 143 // |platform_handles|. |
| 140 std::swap(platform_handle, *platform_handles); | 144 std::swap(platform_handle, *platform_handles); |
| 141 | 145 |
| 142 // Wrapping |platform_handle| in a |ScopedPlatformHandle| means that it'll be | 146 // Wrapping |platform_handle| in a |ScopedPlatformHandle| means that it'll be |
| 143 // closed even if creation fails. | 147 // closed even if creation fails. |
| 148 bool read_only = (serialization->flags & kSerializedStateFlagsReadOnly); |
| 144 scoped_refptr<PlatformSharedBuffer> shared_buffer( | 149 scoped_refptr<PlatformSharedBuffer> shared_buffer( |
| 145 PlatformSharedBuffer::CreateFromPlatformHandle( | 150 PlatformSharedBuffer::CreateFromPlatformHandle( |
| 146 static_cast<size_t>(serialization->num_bytes), | 151 static_cast<size_t>(serialization->num_bytes), read_only, |
| 147 ScopedPlatformHandle(platform_handle))); | 152 ScopedPlatformHandle(platform_handle))); |
| 148 if (!shared_buffer) { | 153 if (!shared_buffer) { |
| 149 LOG(ERROR) | 154 LOG(ERROR) |
| 150 << "Invalid serialized shared buffer dispatcher (invalid num_bytes?)"; | 155 << "Invalid serialized shared buffer dispatcher (invalid num_bytes?)"; |
| 151 return nullptr; | 156 return nullptr; |
| 152 } | 157 } |
| 153 | 158 |
| 154 return CreateInternal(std::move(shared_buffer)); | 159 return CreateInternal(std::move(shared_buffer)); |
| 155 } | 160 } |
| 156 | 161 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 183 scoped_refptr<Dispatcher>* new_dispatcher) { | 188 scoped_refptr<Dispatcher>* new_dispatcher) { |
| 184 MojoDuplicateBufferHandleOptions validated_options; | 189 MojoDuplicateBufferHandleOptions validated_options; |
| 185 MojoResult result = ValidateDuplicateOptions(options, &validated_options); | 190 MojoResult result = ValidateDuplicateOptions(options, &validated_options); |
| 186 if (result != MOJO_RESULT_OK) | 191 if (result != MOJO_RESULT_OK) |
| 187 return result; | 192 return result; |
| 188 | 193 |
| 189 // Note: Since this is "duplicate", we keep our ref to |shared_buffer_|. | 194 // Note: Since this is "duplicate", we keep our ref to |shared_buffer_|. |
| 190 base::AutoLock lock(lock_); | 195 base::AutoLock lock(lock_); |
| 191 if (in_transit_) | 196 if (in_transit_) |
| 192 return MOJO_RESULT_INVALID_ARGUMENT; | 197 return MOJO_RESULT_INVALID_ARGUMENT; |
| 198 |
| 199 if ((validated_options.flags & |
| 200 MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_READ_ONLY) && |
| 201 (!shared_buffer_->IsReadOnly())) { |
| 202 // If a read-only duplicate is requested and |shared_buffer_| is not |
| 203 // read-only, make a read-only duplicate of |shared_buffer_|. |
| 204 scoped_refptr<PlatformSharedBuffer> read_only_buffer = |
| 205 shared_buffer_->CreateReadOnlyDuplicate(); |
| 206 if (!read_only_buffer) |
| 207 return MOJO_RESULT_FAILED_PRECONDITION; |
| 208 DCHECK(read_only_buffer->IsReadOnly()); |
| 209 *new_dispatcher = CreateInternal(std::move(read_only_buffer)); |
| 210 return MOJO_RESULT_OK; |
| 211 } |
| 212 |
| 193 *new_dispatcher = CreateInternal(shared_buffer_); | 213 *new_dispatcher = CreateInternal(shared_buffer_); |
| 194 return MOJO_RESULT_OK; | 214 return MOJO_RESULT_OK; |
| 195 } | 215 } |
| 196 | 216 |
| 197 MojoResult SharedBufferDispatcher::MapBuffer( | 217 MojoResult SharedBufferDispatcher::MapBuffer( |
| 198 uint64_t offset, | 218 uint64_t offset, |
| 199 uint64_t num_bytes, | 219 uint64_t num_bytes, |
| 200 MojoMapBufferFlags flags, | 220 MojoMapBufferFlags flags, |
| 201 scoped_ptr<PlatformSharedBufferMapping>* mapping) { | 221 scoped_ptr<PlatformSharedBufferMapping>* mapping) { |
| 202 if (offset > static_cast<uint64_t>(std::numeric_limits<size_t>::max())) | 222 if (offset > static_cast<uint64_t>(std::numeric_limits<size_t>::max())) |
| 203 return MOJO_RESULT_INVALID_ARGUMENT; | 223 return MOJO_RESULT_INVALID_ARGUMENT; |
| 204 if (num_bytes > static_cast<uint64_t>(std::numeric_limits<size_t>::max())) | 224 if (num_bytes > static_cast<uint64_t>(std::numeric_limits<size_t>::max())) |
| 205 return MOJO_RESULT_INVALID_ARGUMENT; | 225 return MOJO_RESULT_INVALID_ARGUMENT; |
| 206 | 226 |
| 207 base::AutoLock lock(lock_); | 227 base::AutoLock lock(lock_); |
| 208 DCHECK(shared_buffer_); | 228 DCHECK(shared_buffer_); |
| 209 if (in_transit_ || | 229 if (in_transit_ || |
| 210 !shared_buffer_->IsValidMap(static_cast<size_t>(offset), | 230 !shared_buffer_->IsValidMap(static_cast<size_t>(offset), |
| 211 static_cast<size_t>(num_bytes))) { | 231 static_cast<size_t>(num_bytes))) { |
| 212 return MOJO_RESULT_INVALID_ARGUMENT; | 232 return MOJO_RESULT_INVALID_ARGUMENT; |
| 213 } | 233 } |
| 214 | 234 |
| 215 DCHECK(mapping); | 235 DCHECK(mapping); |
| 216 *mapping = shared_buffer_->MapNoCheck(static_cast<size_t>(offset), | 236 *mapping = shared_buffer_->MapNoCheck(static_cast<size_t>(offset), |
| 217 static_cast<size_t>(num_bytes)); | 237 static_cast<size_t>(num_bytes)); |
| 218 if (!*mapping) | 238 if (!*mapping) { |
| 239 LOG(ERROR) << "Unable to map: read_only" << shared_buffer_->IsReadOnly(); |
| 219 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 240 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 241 } |
| 220 | 242 |
| 221 return MOJO_RESULT_OK; | 243 return MOJO_RESULT_OK; |
| 222 } | 244 } |
| 223 | 245 |
| 224 void SharedBufferDispatcher::StartSerialize(uint32_t* num_bytes, | 246 void SharedBufferDispatcher::StartSerialize(uint32_t* num_bytes, |
| 225 uint32_t* num_ports, | 247 uint32_t* num_ports, |
| 226 uint32_t* num_platform_handles) { | 248 uint32_t* num_platform_handles) { |
| 227 *num_bytes = sizeof(SerializedState); | 249 *num_bytes = sizeof(SerializedState); |
| 228 *num_ports = 0; | 250 *num_ports = 0; |
| 229 *num_platform_handles = 1; | 251 *num_platform_handles = 1; |
| 230 } | 252 } |
| 231 | 253 |
| 232 bool SharedBufferDispatcher::EndSerialize(void* destination, | 254 bool SharedBufferDispatcher::EndSerialize(void* destination, |
| 233 ports::PortName* ports, | 255 ports::PortName* ports, |
| 234 PlatformHandle* handles) { | 256 PlatformHandle* handles) { |
| 235 SerializedState* serialization = | 257 SerializedState* serialization = |
| 236 static_cast<SerializedState*>(destination); | 258 static_cast<SerializedState*>(destination); |
| 237 base::AutoLock lock(lock_); | 259 base::AutoLock lock(lock_); |
| 238 serialization->num_bytes = | 260 serialization->num_bytes = |
| 239 static_cast<uint64_t>(shared_buffer_->GetNumBytes()); | 261 static_cast<uint64_t>(shared_buffer_->GetNumBytes()); |
| 262 serialization->flags = |
| 263 (shared_buffer_->IsReadOnly() ? kSerializedStateFlagsReadOnly : 0); |
| 264 serialization->padding = 0; |
| 240 | 265 |
| 241 handle_for_transit_ = shared_buffer_->DuplicatePlatformHandle(); | 266 handle_for_transit_ = shared_buffer_->DuplicatePlatformHandle(); |
| 242 if (!handle_for_transit_.is_valid()) { | 267 if (!handle_for_transit_.is_valid()) { |
| 243 shared_buffer_ = nullptr; | 268 shared_buffer_ = nullptr; |
| 244 return false; | 269 return false; |
| 245 } | 270 } |
| 246 handles[0] = handle_for_transit_.get(); | 271 handles[0] = handle_for_transit_.get(); |
| 247 return true; | 272 return true; |
| 248 } | 273 } |
| 249 | 274 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 276 | 301 |
| 277 SharedBufferDispatcher::~SharedBufferDispatcher() { | 302 SharedBufferDispatcher::~SharedBufferDispatcher() { |
| 278 DCHECK(!shared_buffer_ && !in_transit_); | 303 DCHECK(!shared_buffer_ && !in_transit_); |
| 279 } | 304 } |
| 280 | 305 |
| 281 // static | 306 // static |
| 282 MojoResult SharedBufferDispatcher::ValidateDuplicateOptions( | 307 MojoResult SharedBufferDispatcher::ValidateDuplicateOptions( |
| 283 const MojoDuplicateBufferHandleOptions* in_options, | 308 const MojoDuplicateBufferHandleOptions* in_options, |
| 284 MojoDuplicateBufferHandleOptions* out_options) { | 309 MojoDuplicateBufferHandleOptions* out_options) { |
| 285 const MojoDuplicateBufferHandleOptionsFlags kKnownFlags = | 310 const MojoDuplicateBufferHandleOptionsFlags kKnownFlags = |
| 286 MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE; | 311 MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_READ_ONLY; |
| 287 static const MojoDuplicateBufferHandleOptions kDefaultOptions = { | 312 static const MojoDuplicateBufferHandleOptions kDefaultOptions = { |
| 288 static_cast<uint32_t>(sizeof(MojoDuplicateBufferHandleOptions)), | 313 static_cast<uint32_t>(sizeof(MojoDuplicateBufferHandleOptions)), |
| 289 MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE}; | 314 MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE}; |
| 290 | 315 |
| 291 *out_options = kDefaultOptions; | 316 *out_options = kDefaultOptions; |
| 292 if (!in_options) | 317 if (!in_options) |
| 293 return MOJO_RESULT_OK; | 318 return MOJO_RESULT_OK; |
| 294 | 319 |
| 295 UserOptionsReader<MojoDuplicateBufferHandleOptions> reader(in_options); | 320 UserOptionsReader<MojoDuplicateBufferHandleOptions> reader(in_options); |
| 296 if (!reader.is_valid()) | 321 if (!reader.is_valid()) |
| 297 return MOJO_RESULT_INVALID_ARGUMENT; | 322 return MOJO_RESULT_INVALID_ARGUMENT; |
| 298 | 323 |
| 299 if (!OPTIONS_STRUCT_HAS_MEMBER(MojoDuplicateBufferHandleOptions, flags, | 324 if (!OPTIONS_STRUCT_HAS_MEMBER(MojoDuplicateBufferHandleOptions, flags, |
| 300 reader)) | 325 reader)) |
| 301 return MOJO_RESULT_OK; | 326 return MOJO_RESULT_OK; |
| 302 if ((reader.options().flags & ~kKnownFlags)) | 327 if ((reader.options().flags & ~kKnownFlags)) |
| 303 return MOJO_RESULT_UNIMPLEMENTED; | 328 return MOJO_RESULT_UNIMPLEMENTED; |
| 304 out_options->flags = reader.options().flags; | 329 out_options->flags = reader.options().flags; |
| 305 | 330 |
| 306 // Checks for fields beyond |flags|: | 331 // Checks for fields beyond |flags|: |
| 307 | 332 |
| 308 // (Nothing here yet.) | 333 // (Nothing here yet.) |
| 309 | 334 |
| 310 return MOJO_RESULT_OK; | 335 return MOJO_RESULT_OK; |
| 311 } | 336 } |
| 312 | 337 |
| 313 } // namespace edk | 338 } // namespace edk |
| 314 } // namespace mojo | 339 } // namespace mojo |
| OLD | NEW |