1effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// found in the LICENSE file. 4effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 5effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/system/shared_buffer_dispatcher.h" 6effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include <limits> 8effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/logging.h" 10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/memory/scoped_ptr.h" 116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/embedder/platform_support.h" 1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "mojo/public/c/system/macros.h" 1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "mojo/system/channel.h" 14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/system/constants.h" 15effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/system/memory.h" 1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "mojo/system/options_validation.h" 17effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace mojo { 19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace system { 20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace { 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)struct SerializedSharedBufferDispatcher { 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t num_bytes; 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t platform_handle_index; 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// static 31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const MojoCreateSharedBufferOptions 32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SharedBufferDispatcher::kDefaultCreateOptions = { 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) static_cast<uint32_t>(sizeof(MojoCreateSharedBufferOptions)), 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE}; 35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// static 3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)MojoResult SharedBufferDispatcher::ValidateCreateOptions( 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UserPointer<const MojoCreateSharedBufferOptions> in_options, 39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch MojoCreateSharedBufferOptions* out_options) { 4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const MojoCreateSharedBufferOptionsFlags kKnownFlags = 4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE; 4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *out_options = kDefaultCreateOptions; 445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (in_options.IsNull()) 45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return MOJO_RESULT_OK; 46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UserOptionsReader<MojoCreateSharedBufferOptions> reader(in_options); 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!reader.is_valid()) 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return MOJO_RESULT_INVALID_ARGUMENT; 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!OPTIONS_STRUCT_HAS_MEMBER(MojoCreateSharedBufferOptions, flags, reader)) 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return MOJO_RESULT_OK; 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if ((reader.options().flags & ~kKnownFlags)) 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return MOJO_RESULT_UNIMPLEMENTED; 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) out_options->flags = reader.options().flags; 56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Checks for fields beyond |flags|: 5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // (Nothing here yet.) 60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return MOJO_RESULT_OK; 62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// static 65effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochMojoResult SharedBufferDispatcher::Create( 666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) embedder::PlatformSupport* platform_support, 67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const MojoCreateSharedBufferOptions& /*validated_options*/, 68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch uint64_t num_bytes, 69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_refptr<SharedBufferDispatcher>* result) { 70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!num_bytes) 71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return MOJO_RESULT_INVALID_ARGUMENT; 72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (num_bytes > kMaxSharedMemoryNumBytes) 73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return MOJO_RESULT_RESOURCE_EXHAUSTED; 74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_refptr<embedder::PlatformSharedBuffer> shared_buffer( 766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) platform_support->CreateSharedBuffer(static_cast<size_t>(num_bytes))); 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!shared_buffer.get()) 78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return MOJO_RESULT_RESOURCE_EXHAUSTED; 79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch *result = new SharedBufferDispatcher(shared_buffer); 81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return MOJO_RESULT_OK; 82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 84effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochDispatcher::Type SharedBufferDispatcher::GetType() const { 85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return kTypeSharedBuffer; 86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_refptr<SharedBufferDispatcher> SharedBufferDispatcher::Deserialize( 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Channel* channel, 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const void* source, 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t size, 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) embedder::PlatformHandleVector* platform_handles) { 9403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(channel); 9503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (size != sizeof(SerializedSharedBufferDispatcher)) { 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG(ERROR) << "Invalid serialized shared buffer dispatcher (bad size)"; 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_refptr<SharedBufferDispatcher>(); 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const SerializedSharedBufferDispatcher* serialization = 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static_cast<const SerializedSharedBufferDispatcher*>(source); 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t num_bytes = serialization->num_bytes; 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t platform_handle_index = serialization->platform_handle_index; 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!num_bytes) { 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG(ERROR) 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << "Invalid serialized shared buffer dispatcher (invalid num_bytes)"; 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_refptr<SharedBufferDispatcher>(); 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!platform_handles || platform_handle_index >= platform_handles->size()) { 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG(ERROR) 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << "Invalid serialized shared buffer dispatcher (missing handles)"; 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_refptr<SharedBufferDispatcher>(); 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Starts off invalid, which is what we want. 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) embedder::PlatformHandle platform_handle; 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // We take ownership of the handle, so we have to invalidate the one in 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // |platform_handles|. 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::swap(platform_handle, (*platform_handles)[platform_handle_index]); 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Wrapping |platform_handle| in a |ScopedPlatformHandle| means that it'll be 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // closed even if creation fails. 1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_refptr<embedder::PlatformSharedBuffer> shared_buffer( 12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) channel->platform_support()->CreateSharedBufferFromHandle( 1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) num_bytes, embedder::ScopedPlatformHandle(platform_handle))); 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!shared_buffer.get()) { 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG(ERROR) 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << "Invalid serialized shared buffer dispatcher (invalid num_bytes?)"; 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_refptr<SharedBufferDispatcher>(); 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return scoped_refptr<SharedBufferDispatcher>( 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new SharedBufferDispatcher(shared_buffer)); 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 139effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochSharedBufferDispatcher::SharedBufferDispatcher( 1406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_refptr<embedder::PlatformSharedBuffer> shared_buffer) 141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch : shared_buffer_(shared_buffer) { 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(shared_buffer_.get()); 143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 145effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochSharedBufferDispatcher::~SharedBufferDispatcher() { 146effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 147effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 14846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// static 14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)MojoResult SharedBufferDispatcher::ValidateDuplicateOptions( 1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UserPointer<const MojoDuplicateBufferHandleOptions> in_options, 15146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) MojoDuplicateBufferHandleOptions* out_options) { 15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const MojoDuplicateBufferHandleOptionsFlags kKnownFlags = 15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE; 15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) static const MojoDuplicateBufferHandleOptions kDefaultOptions = { 1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) static_cast<uint32_t>(sizeof(MojoDuplicateBufferHandleOptions)), 1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE}; 15746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 15846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) *out_options = kDefaultOptions; 1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (in_options.IsNull()) 16046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return MOJO_RESULT_OK; 16146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UserOptionsReader<MojoDuplicateBufferHandleOptions> reader(in_options); 1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!reader.is_valid()) 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return MOJO_RESULT_INVALID_ARGUMENT; 1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!OPTIONS_STRUCT_HAS_MEMBER( 1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MojoDuplicateBufferHandleOptions, flags, reader)) 1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return MOJO_RESULT_OK; 1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if ((reader.options().flags & ~kKnownFlags)) 1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return MOJO_RESULT_UNIMPLEMENTED; 1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) out_options->flags = reader.options().flags; 17246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Checks for fields beyond |flags|: 17446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 17546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // (Nothing here yet.) 17646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 17746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return MOJO_RESULT_OK; 17846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 17946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 180effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid SharedBufferDispatcher::CloseImplNoLock() { 181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch lock().AssertAcquired(); 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(shared_buffer_.get()); 1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci shared_buffer_ = nullptr; 184effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 185effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 186effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochscoped_refptr<Dispatcher> 1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SharedBufferDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() { 188c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch lock().AssertAcquired(); 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(shared_buffer_.get()); 1906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_refptr<embedder::PlatformSharedBuffer> shared_buffer; 191effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch shared_buffer.swap(shared_buffer_); 192effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return scoped_refptr<Dispatcher>(new SharedBufferDispatcher(shared_buffer)); 193effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 194effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 195effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochMojoResult SharedBufferDispatcher::DuplicateBufferHandleImplNoLock( 1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UserPointer<const MojoDuplicateBufferHandleOptions> options, 197effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_refptr<Dispatcher>* new_dispatcher) { 198c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch lock().AssertAcquired(); 19946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 20046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) MojoDuplicateBufferHandleOptions validated_options; 20146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) MojoResult result = ValidateDuplicateOptions(options, &validated_options); 20246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (result != MOJO_RESULT_OK) 20346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return result; 204effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 205effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch *new_dispatcher = new SharedBufferDispatcher(shared_buffer_); 206effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return MOJO_RESULT_OK; 207effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 208effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 209effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochMojoResult SharedBufferDispatcher::MapBufferImplNoLock( 210effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch uint64_t offset, 211effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch uint64_t num_bytes, 212effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch MojoMapBufferFlags flags, 2136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_ptr<embedder::PlatformSharedBufferMapping>* mapping) { 214c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch lock().AssertAcquired(); 2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(shared_buffer_.get()); 216effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 217effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (offset > static_cast<uint64_t>(std::numeric_limits<size_t>::max())) 218effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return MOJO_RESULT_INVALID_ARGUMENT; 219effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (num_bytes > static_cast<uint64_t>(std::numeric_limits<size_t>::max())) 220effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return MOJO_RESULT_INVALID_ARGUMENT; 221effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 222effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!shared_buffer_->IsValidMap(static_cast<size_t>(offset), 223effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch static_cast<size_t>(num_bytes))) 224effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return MOJO_RESULT_INVALID_ARGUMENT; 225effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 226effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(mapping); 227effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch *mapping = shared_buffer_->MapNoCheck(static_cast<size_t>(offset), 228effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch static_cast<size_t>(num_bytes)); 229effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!*mapping) 230effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return MOJO_RESULT_RESOURCE_EXHAUSTED; 231effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 232effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return MOJO_RESULT_OK; 233effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 234effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void SharedBufferDispatcher::StartSerializeImplNoLock( 236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Channel* /*channel*/, 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t* max_size, 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t* max_platform_handles) { 239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(HasOneRef()); // Only one ref => no need to take the lock. 240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *max_size = sizeof(SerializedSharedBufferDispatcher); 241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *max_platform_handles = 1; 242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool SharedBufferDispatcher::EndSerializeAndCloseImplNoLock( 245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Channel* /*channel*/, 246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void* destination, 247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t* actual_size, 248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) embedder::PlatformHandleVector* platform_handles) { 249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(HasOneRef()); // Only one ref => no need to take the lock. 2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(shared_buffer_.get()); 251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SerializedSharedBufferDispatcher* serialization = 253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static_cast<SerializedSharedBufferDispatcher*>(destination); 254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // If there's only one reference to |shared_buffer_|, then it's ours (and no 255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // one else can make any more references to it), so we can just take its 256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // handle. 257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) embedder::ScopedPlatformHandle platform_handle( 2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) shared_buffer_->HasOneRef() ? shared_buffer_->PassPlatformHandle() 2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : shared_buffer_->DuplicatePlatformHandle()); 260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!platform_handle.is_valid()) { 2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci shared_buffer_ = nullptr; 262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 2656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) serialization->num_bytes = shared_buffer_->GetNumBytes(); 266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) serialization->platform_handle_index = platform_handles->size(); 267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) platform_handles->push_back(platform_handle.release()); 268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *actual_size = sizeof(SerializedSharedBufferDispatcher); 269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci shared_buffer_ = nullptr; 271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return true; 273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 275effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} // namespace system 276effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} // namespace mojo 277