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
Create(ScopedPlatformHandle platform_handle)14 scoped_refptr<PlatformHandleDispatcher> PlatformHandleDispatcher::Create(
15 ScopedPlatformHandle platform_handle) {
16 return new PlatformHandleDispatcher(std::move(platform_handle));
17 }
18
PassPlatformHandle()19 ScopedPlatformHandle PlatformHandleDispatcher::PassPlatformHandle() {
20 return std::move(platform_handle_);
21 }
22
GetType() const23 Dispatcher::Type PlatformHandleDispatcher::GetType() const {
24 return Type::PLATFORM_HANDLE;
25 }
26
Close()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
StartSerialize(uint32_t * num_bytes,uint32_t * num_ports,uint32_t * num_handles)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
EndSerialize(void * destination,ports::PortName * ports,PlatformHandle * handles)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
BeginTransit()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
CompleteTransitAndClose()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
CancelTransit()72 void PlatformHandleDispatcher::CancelTransit() {
73 base::AutoLock lock(lock_);
74 in_transit_ = false;
75 }
76
77 // static
Deserialize(const void * bytes,size_t num_bytes,const ports::PortName * ports,size_t num_ports,PlatformHandle * handles,size_t num_handles)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
PlatformHandleDispatcher(ScopedPlatformHandle platform_handle)94 PlatformHandleDispatcher::PlatformHandleDispatcher(
95 ScopedPlatformHandle platform_handle)
96 : platform_handle_(std::move(platform_handle)) {}
97
~PlatformHandleDispatcher()98 PlatformHandleDispatcher::~PlatformHandleDispatcher() {
99 DCHECK(is_closed_ && !in_transit_);
100 DCHECK(!platform_handle_.is_valid());
101 }
102
103 } // namespace edk
104 } // namespace mojo
105