Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / mojo / system / platform_handle_dispatcher.cc
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/system/platform_handle_dispatcher.h"
6
7 #include <algorithm>
8
9 #include "base/logging.h"
10
11 namespace mojo {
12 namespace system {
13
14 namespace {
15
16 const size_t kInvalidPlatformHandleIndex = static_cast<size_t>(-1);
17
18 struct SerializedPlatformHandleDispatcher {
19   size_t platform_handle_index;  // (Or |kInvalidPlatformHandleIndex|.)
20 };
21
22 }  // namespace
23
24 PlatformHandleDispatcher::PlatformHandleDispatcher(
25     embedder::ScopedPlatformHandle platform_handle)
26     : platform_handle_(platform_handle.Pass()) {
27 }
28
29 embedder::ScopedPlatformHandle PlatformHandleDispatcher::PassPlatformHandle() {
30   base::AutoLock locker(lock());
31   return platform_handle_.Pass();
32 }
33
34 Dispatcher::Type PlatformHandleDispatcher::GetType() const {
35   return kTypePlatformHandle;
36 }
37
38 // static
39 scoped_refptr<PlatformHandleDispatcher> PlatformHandleDispatcher::Deserialize(
40     Channel* channel,
41     const void* source,
42     size_t size,
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>();
47   }
48
49   const SerializedPlatformHandleDispatcher* serialization =
50       static_cast<const SerializedPlatformHandleDispatcher*>(source);
51   size_t platform_handle_index = serialization->platform_handle_index;
52
53   // Starts off invalid, which is what we want.
54   embedder::PlatformHandle platform_handle;
55
56   if (platform_handle_index != kInvalidPlatformHandleIndex) {
57     if (!platform_handles ||
58         platform_handle_index >= platform_handles->size()) {
59       LOG(ERROR)
60           << "Invalid serialized platform handle dispatcher (missing handles)";
61       return scoped_refptr<PlatformHandleDispatcher>();
62     }
63
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]);
67   }
68
69   return scoped_refptr<PlatformHandleDispatcher>(new PlatformHandleDispatcher(
70       embedder::ScopedPlatformHandle(platform_handle)));
71 }
72
73 PlatformHandleDispatcher::~PlatformHandleDispatcher() {
74 }
75
76 void PlatformHandleDispatcher::CloseImplNoLock() {
77   lock().AssertAcquired();
78   platform_handle_.reset();
79 }
80
81 scoped_refptr<Dispatcher>
82 PlatformHandleDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() {
83   lock().AssertAcquired();
84   return scoped_refptr<Dispatcher>(
85       new PlatformHandleDispatcher(platform_handle_.Pass()));
86 }
87
88 void PlatformHandleDispatcher::StartSerializeImplNoLock(
89     Channel* /*channel*/,
90     size_t* max_size,
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;
95 }
96
97 bool PlatformHandleDispatcher::EndSerializeAndCloseImplNoLock(
98     Channel* /*channel*/,
99     void* destination,
100     size_t* actual_size,
101     embedder::PlatformHandleVector* platform_handles) {
102   DCHECK(HasOneRef());  // Only one ref => no need to take the lock.
103
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());
109   } else {
110     serialization->platform_handle_index = kInvalidPlatformHandleIndex;
111   }
112
113   *actual_size = sizeof(SerializedPlatformHandleDispatcher);
114   return true;
115 }
116
117 }  // namespace system
118 }  // namespace mojo