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.
5 #include "mojo/system/platform_handle_dispatcher.h"
9 #include "base/logging.h"
16 const size_t kInvalidPlatformHandleIndex = static_cast<size_t>(-1);
18 struct SerializedPlatformHandleDispatcher {
19 size_t platform_handle_index; // (Or |kInvalidPlatformHandleIndex|.)
24 PlatformHandleDispatcher::PlatformHandleDispatcher(
25 embedder::ScopedPlatformHandle platform_handle)
26 : platform_handle_(platform_handle.Pass()) {
29 embedder::ScopedPlatformHandle PlatformHandleDispatcher::PassPlatformHandle() {
30 base::AutoLock locker(lock());
31 return platform_handle_.Pass();
34 Dispatcher::Type PlatformHandleDispatcher::GetType() const {
35 return kTypePlatformHandle;
39 scoped_refptr<PlatformHandleDispatcher> PlatformHandleDispatcher::Deserialize(
43 embedder::PlatformHandleVector* platform_handles) {
44 if (size != sizeof(SerializedPlatformHandleDispatcher)) {
45 LOG(ERROR) << "Invalid serialized platform handle dispatcher (bad size)";
46 return scoped_refptr<PlatformHandleDispatcher>();
49 const SerializedPlatformHandleDispatcher* serialization =
50 static_cast<const SerializedPlatformHandleDispatcher*>(source);
51 size_t platform_handle_index = serialization->platform_handle_index;
53 // Starts off invalid, which is what we want.
54 embedder::PlatformHandle platform_handle;
56 if (platform_handle_index != kInvalidPlatformHandleIndex) {
57 if (!platform_handles ||
58 platform_handle_index >= platform_handles->size()) {
60 << "Invalid serialized platform handle dispatcher (missing handles)";
61 return scoped_refptr<PlatformHandleDispatcher>();
64 // We take ownership of the handle, so we have to invalidate the one in
65 // |platform_handles|.
66 std::swap(platform_handle, (*platform_handles)[platform_handle_index]);
69 return scoped_refptr<PlatformHandleDispatcher>(new PlatformHandleDispatcher(
70 embedder::ScopedPlatformHandle(platform_handle)));
73 PlatformHandleDispatcher::~PlatformHandleDispatcher() {
76 void PlatformHandleDispatcher::CloseImplNoLock() {
77 lock().AssertAcquired();
78 platform_handle_.reset();
81 scoped_refptr<Dispatcher>
82 PlatformHandleDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() {
83 lock().AssertAcquired();
84 return scoped_refptr<Dispatcher>(
85 new PlatformHandleDispatcher(platform_handle_.Pass()));
88 void PlatformHandleDispatcher::StartSerializeImplNoLock(
91 size_t* max_platform_handles) {
92 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
93 *max_size = sizeof(SerializedPlatformHandleDispatcher);
94 *max_platform_handles = 1;
97 bool PlatformHandleDispatcher::EndSerializeAndCloseImplNoLock(
101 embedder::PlatformHandleVector* platform_handles) {
102 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
104 SerializedPlatformHandleDispatcher* serialization =
105 static_cast<SerializedPlatformHandleDispatcher*>(destination);
106 if (platform_handle_.is_valid()) {
107 serialization->platform_handle_index = platform_handles->size();
108 platform_handles->push_back(platform_handle_.release());
110 serialization->platform_handle_index = kInvalidPlatformHandleIndex;
113 *actual_size = sizeof(SerializedPlatformHandleDispatcher);
117 } // namespace system