OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "mojo/edk/system/core.h" | 5 #include "mojo/edk/system/core.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 | 52 |
53 void CallWatchCallback(MojoWatchCallback callback, | 53 void CallWatchCallback(MojoWatchCallback callback, |
54 uintptr_t context, | 54 uintptr_t context, |
55 MojoResult result, | 55 MojoResult result, |
56 const HandleSignalsState& signals_state, | 56 const HandleSignalsState& signals_state, |
57 MojoWatchNotificationFlags flags) { | 57 MojoWatchNotificationFlags flags) { |
58 callback(context, result, static_cast<MojoHandleSignalsState>(signals_state), | 58 callback(context, result, static_cast<MojoHandleSignalsState>(signals_state), |
59 flags); | 59 flags); |
60 } | 60 } |
61 | 61 |
| 62 MojoResult MojoPlatformHandleToScopedPlatformHandle( |
| 63 const MojoPlatformHandle* platform_handle, |
| 64 ScopedPlatformHandle* out_handle) { |
| 65 if (platform_handle->struct_size != sizeof(MojoPlatformHandle)) |
| 66 return MOJO_RESULT_INVALID_ARGUMENT; |
| 67 |
| 68 if (platform_handle->type == MOJO_PLATFORM_HANDLE_TYPE_INVALID) { |
| 69 out_handle->reset(); |
| 70 return MOJO_RESULT_OK; |
| 71 } |
| 72 |
| 73 PlatformHandle handle; |
| 74 switch (platform_handle->type) { |
| 75 #if defined(OS_POSIX) |
| 76 case MOJO_PLATFORM_HANDLE_TYPE_FILE_DESCRIPTOR: |
| 77 handle.handle = static_cast<int>(platform_handle->value); |
| 78 break; |
| 79 #endif |
| 80 |
| 81 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 82 case MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT: |
| 83 handle.type = PlatformHandle::Type::MACH; |
| 84 handle.port = static_cast<mach_port_t>(platform_handle->value); |
| 85 break; |
| 86 #endif |
| 87 |
| 88 #if defined(OS_WIN) |
| 89 case MOJO_PLATFORM_HANDLE_TYPE_WINDOWS_HANDLE: |
| 90 handle.handle = reinterpret_cast<HANDLE>(platform_handle->value); |
| 91 break; |
| 92 #endif |
| 93 |
| 94 default: |
| 95 return MOJO_RESULT_INVALID_ARGUMENT; |
| 96 } |
| 97 |
| 98 out_handle->reset(handle); |
| 99 return MOJO_RESULT_OK; |
| 100 } |
| 101 |
| 102 MojoResult ScopedPlatformHandleToMojoPlatformHandle( |
| 103 ScopedPlatformHandle handle, |
| 104 MojoPlatformHandle* platform_handle) { |
| 105 if (platform_handle->struct_size != sizeof(MojoPlatformHandle)) |
| 106 return MOJO_RESULT_INVALID_ARGUMENT; |
| 107 |
| 108 if (!handle.is_valid()) { |
| 109 platform_handle->type = MOJO_PLATFORM_HANDLE_TYPE_INVALID; |
| 110 return MOJO_RESULT_OK; |
| 111 } |
| 112 |
| 113 #if defined(OS_POSIX) |
| 114 switch (handle.get().type) { |
| 115 case PlatformHandle::Type::POSIX: |
| 116 platform_handle->type = MOJO_PLATFORM_HANDLE_TYPE_FILE_DESCRIPTOR; |
| 117 platform_handle->value = static_cast<uint64_t>(handle.release().handle); |
| 118 break; |
| 119 |
| 120 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 121 case PlatformHandle::Type::MACH: |
| 122 platform_handle->type = MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT; |
| 123 platform_handle->value = static_cast<uint64_t>(handle.release().port); |
| 124 break; |
| 125 #endif // defined(OS_MACOSX) && !defined(OS_IOS) |
| 126 |
| 127 default: |
| 128 return MOJO_RESULT_INVALID_ARGUMENT; |
| 129 } |
| 130 #elif defined(OS_WIN) |
| 131 platform_handle->type = MOJO_PLATFORM_HANDLE_TYPE_WINDOWS_HANDLE; |
| 132 platform_handle->value = reinterpret_cast<uint64_t>(handle.release().handle); |
| 133 #endif // defined(OS_WIN) |
| 134 |
| 135 return MOJO_RESULT_OK; |
| 136 } |
| 137 |
62 } // namespace | 138 } // namespace |
63 | 139 |
64 Core::Core() {} | 140 Core::Core() {} |
65 | 141 |
66 Core::~Core() { | 142 Core::~Core() { |
67 if (node_controller_ && node_controller_->io_task_runner()) { | 143 if (node_controller_ && node_controller_->io_task_runner()) { |
68 // If this races with IO thread shutdown the callback will be dropped and | 144 // If this races with IO thread shutdown the callback will be dropped and |
69 // the NodeController will be shutdown on this thread anyway, which is also | 145 // the NodeController will be shutdown on this thread anyway, which is also |
70 // just fine. | 146 // just fine. |
71 scoped_refptr<base::TaskRunner> io_task_runner = | 147 scoped_refptr<base::TaskRunner> io_task_runner = |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 } | 218 } |
143 | 219 |
144 MojoResult Core::PassWrappedPlatformHandle( | 220 MojoResult Core::PassWrappedPlatformHandle( |
145 MojoHandle wrapper_handle, | 221 MojoHandle wrapper_handle, |
146 ScopedPlatformHandle* platform_handle) { | 222 ScopedPlatformHandle* platform_handle) { |
147 base::AutoLock lock(handles_lock_); | 223 base::AutoLock lock(handles_lock_); |
148 scoped_refptr<Dispatcher> d; | 224 scoped_refptr<Dispatcher> d; |
149 MojoResult result = handles_.GetAndRemoveDispatcher(wrapper_handle, &d); | 225 MojoResult result = handles_.GetAndRemoveDispatcher(wrapper_handle, &d); |
150 if (result != MOJO_RESULT_OK) | 226 if (result != MOJO_RESULT_OK) |
151 return result; | 227 return result; |
152 PlatformHandleDispatcher* phd = | 228 if (d->GetType() == Dispatcher::Type::PLATFORM_HANDLE) { |
153 static_cast<PlatformHandleDispatcher*>(d.get()); | 229 PlatformHandleDispatcher* phd = |
154 *platform_handle = phd->PassPlatformHandle(); | 230 static_cast<PlatformHandleDispatcher*>(d.get()); |
155 phd->Close(); | 231 *platform_handle = phd->PassPlatformHandle(); |
156 return MOJO_RESULT_OK; | 232 } else { |
| 233 result = MOJO_RESULT_INVALID_ARGUMENT; |
| 234 } |
| 235 d->Close(); |
| 236 return result; |
157 } | 237 } |
158 | 238 |
159 MojoResult Core::CreateSharedBufferWrapper( | 239 MojoResult Core::CreateSharedBufferWrapper( |
160 base::SharedMemoryHandle shared_memory_handle, | 240 base::SharedMemoryHandle shared_memory_handle, |
161 size_t num_bytes, | 241 size_t num_bytes, |
162 bool read_only, | 242 bool read_only, |
163 MojoHandle* mojo_wrapper_handle) { | 243 MojoHandle* mojo_wrapper_handle) { |
164 DCHECK(num_bytes); | 244 DCHECK(num_bytes); |
165 scoped_refptr<PlatformSharedBuffer> platform_buffer = | 245 scoped_refptr<PlatformSharedBuffer> platform_buffer = |
166 PlatformSharedBuffer::CreateFromSharedMemoryHandle(num_bytes, read_only, | 246 PlatformSharedBuffer::CreateFromSharedMemoryHandle(num_bytes, read_only, |
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
873 *buffer = address; | 953 *buffer = address; |
874 return MOJO_RESULT_OK; | 954 return MOJO_RESULT_OK; |
875 } | 955 } |
876 | 956 |
877 MojoResult Core::UnmapBuffer(void* buffer) { | 957 MojoResult Core::UnmapBuffer(void* buffer) { |
878 RequestContext request_context; | 958 RequestContext request_context; |
879 base::AutoLock lock(mapping_table_lock_); | 959 base::AutoLock lock(mapping_table_lock_); |
880 return mapping_table_.RemoveMapping(buffer); | 960 return mapping_table_.RemoveMapping(buffer); |
881 } | 961 } |
882 | 962 |
| 963 MojoResult Core::WrapPlatformHandle(const MojoPlatformHandle* platform_handle, |
| 964 MojoHandle* mojo_handle) { |
| 965 ScopedPlatformHandle handle; |
| 966 MojoResult result = MojoPlatformHandleToScopedPlatformHandle(platform_handle, |
| 967 &handle); |
| 968 if (result != MOJO_RESULT_OK) |
| 969 return result; |
| 970 |
| 971 return CreatePlatformHandleWrapper(std::move(handle), mojo_handle); |
| 972 } |
| 973 |
| 974 MojoResult Core::UnwrapPlatformHandle(MojoHandle mojo_handle, |
| 975 MojoPlatformHandle* platform_handle) { |
| 976 ScopedPlatformHandle handle; |
| 977 MojoResult result = PassWrappedPlatformHandle(mojo_handle, &handle); |
| 978 if (result != MOJO_RESULT_OK) |
| 979 return result; |
| 980 |
| 981 return ScopedPlatformHandleToMojoPlatformHandle(std::move(handle), |
| 982 platform_handle); |
| 983 } |
| 984 |
| 985 MojoResult Core::WrapPlatformSharedBufferHandle( |
| 986 const MojoPlatformHandle* platform_handle, |
| 987 size_t size, |
| 988 MojoPlatformSharedBufferHandleFlags flags, |
| 989 MojoHandle* mojo_handle) { |
| 990 DCHECK(size); |
| 991 ScopedPlatformHandle handle; |
| 992 MojoResult result = MojoPlatformHandleToScopedPlatformHandle(platform_handle, |
| 993 &handle); |
| 994 if (result != MOJO_RESULT_OK) |
| 995 return result; |
| 996 |
| 997 bool read_only = flags & MOJO_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_READ_ONLY; |
| 998 scoped_refptr<PlatformSharedBuffer> platform_buffer = |
| 999 PlatformSharedBuffer::CreateFromPlatformHandle(size, read_only, |
| 1000 std::move(handle)); |
| 1001 if (!platform_buffer) |
| 1002 return MOJO_RESULT_UNKNOWN; |
| 1003 |
| 1004 scoped_refptr<SharedBufferDispatcher> dispatcher; |
| 1005 result = SharedBufferDispatcher::CreateFromPlatformSharedBuffer( |
| 1006 platform_buffer, &dispatcher); |
| 1007 if (result != MOJO_RESULT_OK) |
| 1008 return result; |
| 1009 |
| 1010 MojoHandle h = AddDispatcher(dispatcher); |
| 1011 if (h == MOJO_HANDLE_INVALID) { |
| 1012 dispatcher->Close(); |
| 1013 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 1014 } |
| 1015 |
| 1016 *mojo_handle = h; |
| 1017 return MOJO_RESULT_OK; |
| 1018 } |
| 1019 |
| 1020 MojoResult Core::UnwrapPlatformSharedBufferHandle( |
| 1021 MojoHandle mojo_handle, |
| 1022 MojoPlatformHandle* platform_handle, |
| 1023 size_t* size, |
| 1024 MojoPlatformSharedBufferHandleFlags* flags) { |
| 1025 scoped_refptr<Dispatcher> dispatcher; |
| 1026 MojoResult result = MOJO_RESULT_OK; |
| 1027 { |
| 1028 base::AutoLock lock(handles_lock_); |
| 1029 result = handles_.GetAndRemoveDispatcher(mojo_handle, &dispatcher); |
| 1030 if (result != MOJO_RESULT_OK) |
| 1031 return result; |
| 1032 } |
| 1033 |
| 1034 if (dispatcher->GetType() != Dispatcher::Type::SHARED_BUFFER) { |
| 1035 dispatcher->Close(); |
| 1036 return MOJO_RESULT_INVALID_ARGUMENT; |
| 1037 } |
| 1038 |
| 1039 SharedBufferDispatcher* shm_dispatcher = |
| 1040 static_cast<SharedBufferDispatcher*>(dispatcher.get()); |
| 1041 scoped_refptr<PlatformSharedBuffer> platform_shared_buffer = |
| 1042 shm_dispatcher->PassPlatformSharedBuffer(); |
| 1043 CHECK(platform_shared_buffer); |
| 1044 |
| 1045 CHECK(size); |
| 1046 *size = platform_shared_buffer->GetNumBytes(); |
| 1047 |
| 1048 CHECK(flags); |
| 1049 *flags = MOJO_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_NONE; |
| 1050 if (platform_shared_buffer->IsReadOnly()) |
| 1051 *flags |= MOJO_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_READ_ONLY; |
| 1052 |
| 1053 ScopedPlatformHandle handle = platform_shared_buffer->PassPlatformHandle(); |
| 1054 return ScopedPlatformHandleToMojoPlatformHandle(std::move(handle), |
| 1055 platform_handle); |
| 1056 } |
| 1057 |
883 void Core::GetActiveHandlesForTest(std::vector<MojoHandle>* handles) { | 1058 void Core::GetActiveHandlesForTest(std::vector<MojoHandle>* handles) { |
884 base::AutoLock lock(handles_lock_); | 1059 base::AutoLock lock(handles_lock_); |
885 handles_.GetActiveHandlesForTest(handles); | 1060 handles_.GetActiveHandlesForTest(handles); |
886 } | 1061 } |
887 | 1062 |
888 MojoResult Core::WaitManyInternal(const MojoHandle* handles, | 1063 MojoResult Core::WaitManyInternal(const MojoHandle* handles, |
889 const MojoHandleSignals* signals, | 1064 const MojoHandleSignals* signals, |
890 uint32_t num_handles, | 1065 uint32_t num_handles, |
891 MojoDeadline deadline, | 1066 MojoDeadline deadline, |
892 uint32_t *result_index, | 1067 uint32_t *result_index, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
958 std::unique_ptr<NodeController> node_controller) { | 1133 std::unique_ptr<NodeController> node_controller) { |
959 // It's OK to leak this reference. At this point we know the IO loop is still | 1134 // It's OK to leak this reference. At this point we know the IO loop is still |
960 // running, and we know the NodeController will observe its eventual | 1135 // running, and we know the NodeController will observe its eventual |
961 // destruction. This tells the NodeController to delete itself when that | 1136 // destruction. This tells the NodeController to delete itself when that |
962 // happens. | 1137 // happens. |
963 node_controller.release()->DestroyOnIOThreadShutdown(); | 1138 node_controller.release()->DestroyOnIOThreadShutdown(); |
964 } | 1139 } |
965 | 1140 |
966 } // namespace edk | 1141 } // namespace edk |
967 } // namespace mojo | 1142 } // namespace mojo |
OLD | NEW |