1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file. 4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "mojo/system/platform_handle_dispatcher.h" 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <algorithm> 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/logging.h" 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace mojo { 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace system { 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace { 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const size_t kInvalidPlatformHandleIndex = static_cast<size_t>(-1); 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)struct SerializedPlatformHandleDispatcher { 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t platform_handle_index; // (Or |kInvalidPlatformHandleIndex|.) 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)PlatformHandleDispatcher::PlatformHandleDispatcher( 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) embedder::ScopedPlatformHandle platform_handle) 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : platform_handle_(platform_handle.Pass()) { 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)embedder::ScopedPlatformHandle PlatformHandleDispatcher::PassPlatformHandle() { 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::AutoLock locker(lock()); 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return platform_handle_.Pass(); 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)Dispatcher::Type PlatformHandleDispatcher::GetType() const { 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return kTypePlatformHandle; 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_refptr<PlatformHandleDispatcher> PlatformHandleDispatcher::Deserialize( 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Channel* channel, 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const void* source, 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t size, 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) embedder::PlatformHandleVector* platform_handles) { 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (size != sizeof(SerializedPlatformHandleDispatcher)) { 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG(ERROR) << "Invalid serialized platform handle dispatcher (bad size)"; 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_refptr<PlatformHandleDispatcher>(); 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const SerializedPlatformHandleDispatcher* serialization = 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static_cast<const SerializedPlatformHandleDispatcher*>(source); 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t platform_handle_index = serialization->platform_handle_index; 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Starts off invalid, which is what we want. 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) embedder::PlatformHandle platform_handle; 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (platform_handle_index != kInvalidPlatformHandleIndex) { 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!platform_handles || 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) platform_handle_index >= platform_handles->size()) { 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG(ERROR) 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << "Invalid serialized platform handle dispatcher (missing handles)"; 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_refptr<PlatformHandleDispatcher>(); 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // We take ownership of the handle, so we have to invalidate the one in 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // |platform_handles|. 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::swap(platform_handle, (*platform_handles)[platform_handle_index]); 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_refptr<PlatformHandleDispatcher>(new PlatformHandleDispatcher( 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) embedder::ScopedPlatformHandle(platform_handle))); 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)PlatformHandleDispatcher::~PlatformHandleDispatcher() { 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PlatformHandleDispatcher::CloseImplNoLock() { 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) lock().AssertAcquired(); 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) platform_handle_.reset(); 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_refptr<Dispatcher> 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)PlatformHandleDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() { 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) lock().AssertAcquired(); 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_refptr<Dispatcher>( 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new PlatformHandleDispatcher(platform_handle_.Pass())); 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PlatformHandleDispatcher::StartSerializeImplNoLock( 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Channel* /*channel*/, 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t* max_size, 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t* max_platform_handles) { 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(HasOneRef()); // Only one ref => no need to take the lock. 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *max_size = sizeof(SerializedPlatformHandleDispatcher); 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *max_platform_handles = 1; 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool PlatformHandleDispatcher::EndSerializeAndCloseImplNoLock( 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Channel* /*channel*/, 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void* destination, 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t* actual_size, 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) embedder::PlatformHandleVector* platform_handles) { 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(HasOneRef()); // Only one ref => no need to take the lock. 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SerializedPlatformHandleDispatcher* serialization = 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static_cast<SerializedPlatformHandleDispatcher*>(destination); 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (platform_handle_.is_valid()) { 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) serialization->platform_handle_index = platform_handles->size(); 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) platform_handles->push_back(platform_handle_.release()); 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) serialization->platform_handle_index = kInvalidPlatformHandleIndex; 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *actual_size = sizeof(SerializedPlatformHandleDispatcher); 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return true; 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace system 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace mojo 119