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 3 // found in the LICENSE file. 4 5 #include "mojo/edk/system/platform_handle_dispatcher.h" 6 7 #include "base/synchronization/lock.h" 8 #include "mojo/edk/embedder/platform_handle_vector.h" 9 10 namespace mojo { 11 namespace edk { 12 13 // static 14 scoped_refptr<PlatformHandleDispatcher> PlatformHandleDispatcher::Create( 15 ScopedPlatformHandle platform_handle) { 16 return new PlatformHandleDispatcher(std::move(platform_handle)); 17 } 18 19 ScopedPlatformHandle PlatformHandleDispatcher::PassPlatformHandle() { 20 return std::move(platform_handle_); 21 } 22 23 Dispatcher::Type PlatformHandleDispatcher::GetType() const { 24 return Type::PLATFORM_HANDLE; 25 } 26 27 MojoResult PlatformHandleDispatcher::Close() { 28 base::AutoLock lock(lock_); 29 if (is_closed_ || in_transit_) 30 return MOJO_RESULT_INVALID_ARGUMENT; 31 is_closed_ = true; 32 platform_handle_.reset(); 33 return MOJO_RESULT_OK; 34 } 35 36 void PlatformHandleDispatcher::StartSerialize(uint32_t* num_bytes, 37 uint32_t* num_ports, 38 uint32_t* num_handles) { 39 *num_bytes = 0; 40 *num_ports = 0; 41 *num_handles = 1; 42 } 43 44 bool PlatformHandleDispatcher::EndSerialize(void* destination, 45 ports::PortName* ports, 46 PlatformHandle* handles) { 47 base::AutoLock lock(lock_); 48 if (is_closed_) 49 return false; 50 handles[0] = platform_handle_.get(); 51 return true; 52 } 53 54 bool PlatformHandleDispatcher::BeginTransit() { 55 base::AutoLock lock(lock_); 56 if (in_transit_) 57 return false; 58 in_transit_ = !is_closed_; 59 return in_transit_; 60 } 61 62 void PlatformHandleDispatcher::CompleteTransitAndClose() { 63 base::AutoLock lock(lock_); 64 65 in_transit_ = false; 66 is_closed_ = true; 67 68 // The system has taken ownership of our handle. 69 ignore_result(platform_handle_.release()); 70 } 71 72 void PlatformHandleDispatcher::CancelTransit() { 73 base::AutoLock lock(lock_); 74 in_transit_ = false; 75 } 76 77 // static 78 scoped_refptr<PlatformHandleDispatcher> PlatformHandleDispatcher::Deserialize( 79 const void* bytes, 80 size_t num_bytes, 81 const ports::PortName* ports, 82 size_t num_ports, 83 PlatformHandle* handles, 84 size_t num_handles) { 85 if (num_bytes || num_ports || num_handles != 1) 86 return nullptr; 87 88 PlatformHandle handle; 89 std::swap(handle, handles[0]); 90 91 return PlatformHandleDispatcher::Create(ScopedPlatformHandle(handle)); 92 } 93 94 PlatformHandleDispatcher::PlatformHandleDispatcher( 95 ScopedPlatformHandle platform_handle) 96 : platform_handle_(std::move(platform_handle)) {} 97 98 PlatformHandleDispatcher::~PlatformHandleDispatcher() { 99 DCHECK(is_closed_ && !in_transit_); 100 DCHECK(!platform_handle_.is_valid()); 101 } 102 103 } // namespace edk 104 } // namespace mojo 105