OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 <mach/mach.h> | 5 #include <mach/mach.h> |
6 #include <mach/mach_vm.h> | 6 #include <mach/mach_vm.h> |
7 #include <servers/bootstrap.h> | 7 #include <servers/bootstrap.h> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/mac/mach_logging.h" | 10 #include "base/mac/mach_logging.h" |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 // Sets up the mach communication ports with the server. Returns a port to which | 119 // Sets up the mach communication ports with the server. Returns a port to which |
120 // the server will send mach objects. | 120 // the server will send mach objects. |
121 mach_port_t CommonChildProcessSetUp() { | 121 mach_port_t CommonChildProcessSetUp() { |
122 CommandLine cmd_line = *CommandLine::ForCurrentProcess(); | 122 CommandLine cmd_line = *CommandLine::ForCurrentProcess(); |
123 std::string service_name = | 123 std::string service_name = |
124 cmd_line.GetSwitchValueASCII(g_service_switch_name); | 124 cmd_line.GetSwitchValueASCII(g_service_switch_name); |
125 mac::ScopedMachSendRight server_port(LookupServer(service_name.c_str())); | 125 mac::ScopedMachSendRight server_port(LookupServer(service_name.c_str())); |
126 mach_port_t client_port = MakeReceivingPort(); | 126 mach_port_t client_port = MakeReceivingPort(); |
127 | 127 |
128 // Send the port that this process is listening on to the server. | 128 // Send the port that this process is listening on to the server. |
129 SendMachPort(server_port, client_port, MACH_MSG_TYPE_MAKE_SEND); | 129 SendMachPort(server_port.get(), client_port, MACH_MSG_TYPE_MAKE_SEND); |
130 return client_port; | 130 return client_port; |
131 } | 131 } |
132 | 132 |
133 // The number of active names in the current task's port name space. | 133 // The number of active names in the current task's port name space. |
134 mach_msg_type_number_t GetActiveNameCount() { | 134 mach_msg_type_number_t GetActiveNameCount() { |
135 mach_port_name_array_t name_array; | 135 mach_port_name_array_t name_array; |
136 mach_msg_type_number_t names_count; | 136 mach_msg_type_number_t names_count; |
137 mach_port_type_array_t type_array; | 137 mach_port_type_array_t type_array; |
138 mach_msg_type_number_t types_count; | 138 mach_msg_type_number_t types_count; |
139 kern_return_t kr = mach_port_names(mach_task_self(), &name_array, | 139 kern_return_t kr = mach_port_names(mach_task_self(), &name_array, |
(...skipping 14 matching lines...) Expand all Loading... |
154 command_line.AppendSwitchASCII(g_service_switch_name, service_name_); | 154 command_line.AppendSwitchASCII(g_service_switch_name, service_name_); |
155 return command_line; | 155 return command_line; |
156 } | 156 } |
157 | 157 |
158 void SetUpChild(const std::string& name) { | 158 void SetUpChild(const std::string& name) { |
159 // Make a random service name so that this test doesn't conflict with other | 159 // Make a random service name so that this test doesn't conflict with other |
160 // similar tests. | 160 // similar tests. |
161 service_name_ = CreateRandomServiceName(); | 161 service_name_ = CreateRandomServiceName(); |
162 server_port_.reset(BecomeMachServer(service_name_.c_str())); | 162 server_port_.reset(BecomeMachServer(service_name_.c_str())); |
163 child_process_ = SpawnChild(name); | 163 child_process_ = SpawnChild(name); |
164 client_port_.reset(ReceiveMachPort(server_port_)); | 164 client_port_.reset(ReceiveMachPort(server_port_.get())); |
165 } | 165 } |
166 | 166 |
167 static const int s_memory_size = 99999; | 167 static const int s_memory_size = 99999; |
168 | 168 |
169 protected: | 169 protected: |
170 std::string service_name_; | 170 std::string service_name_; |
171 | 171 |
172 // A port on which the main process listens for mach messages from the child | 172 // A port on which the main process listens for mach messages from the child |
173 // process. | 173 // process. |
174 mac::ScopedMachReceiveRight server_port_; | 174 mac::ScopedMachReceiveRight server_port_; |
(...skipping 11 matching lines...) Expand all Loading... |
186 TEST_F(SharedMemoryMacMultiProcessTest, MachBasedSharedMemory) { | 186 TEST_F(SharedMemoryMacMultiProcessTest, MachBasedSharedMemory) { |
187 SetUpChild("MachBasedSharedMemoryClient"); | 187 SetUpChild("MachBasedSharedMemoryClient"); |
188 | 188 |
189 SharedMemoryHandle shm(s_memory_size); | 189 SharedMemoryHandle shm(s_memory_size); |
190 ASSERT_TRUE(shm.IsValid()); | 190 ASSERT_TRUE(shm.IsValid()); |
191 SharedMemory shared_memory(shm, false); | 191 SharedMemory shared_memory(shm, false); |
192 shared_memory.Map(s_memory_size); | 192 shared_memory.Map(s_memory_size); |
193 memset(shared_memory.memory(), 'a', s_memory_size); | 193 memset(shared_memory.memory(), 'a', s_memory_size); |
194 | 194 |
195 // Send the underlying memory object to the client process. | 195 // Send the underlying memory object to the client process. |
196 SendMachPort(client_port_, shm.GetMemoryObject(), MACH_MSG_TYPE_COPY_SEND); | 196 SendMachPort( |
| 197 client_port_.get(), shm.GetMemoryObject(), MACH_MSG_TYPE_COPY_SEND); |
197 int rv = -1; | 198 int rv = -1; |
198 ASSERT_TRUE(child_process_.WaitForExitWithTimeout( | 199 ASSERT_TRUE(child_process_.WaitForExitWithTimeout( |
199 TestTimeouts::action_timeout(), &rv)); | 200 TestTimeouts::action_timeout(), &rv)); |
200 EXPECT_EQ(0, rv); | 201 EXPECT_EQ(0, rv); |
201 } | 202 } |
202 | 203 |
203 MULTIPROCESS_TEST_MAIN(MachBasedSharedMemoryClient) { | 204 MULTIPROCESS_TEST_MAIN(MachBasedSharedMemoryClient) { |
204 mac::ScopedMachReceiveRight client_port(CommonChildProcessSetUp()); | 205 mac::ScopedMachReceiveRight client_port(CommonChildProcessSetUp()); |
205 // The next mach port should be for a memory object. | 206 // The next mach port should be for a memory object. |
206 mach_port_t memory_object = ReceiveMachPort(client_port); | 207 mach_port_t memory_object = ReceiveMachPort(client_port.get()); |
207 SharedMemoryHandle shm(memory_object, | 208 SharedMemoryHandle shm(memory_object, |
208 SharedMemoryMacMultiProcessTest::s_memory_size, | 209 SharedMemoryMacMultiProcessTest::s_memory_size, |
209 GetCurrentProcId()); | 210 GetCurrentProcId()); |
210 SharedMemory shared_memory(shm, false); | 211 SharedMemory shared_memory(shm, false); |
211 shared_memory.Map(SharedMemoryMacMultiProcessTest::s_memory_size); | 212 shared_memory.Map(SharedMemoryMacMultiProcessTest::s_memory_size); |
212 const char* start = static_cast<const char*>(shared_memory.memory()); | 213 const char* start = static_cast<const char*>(shared_memory.memory()); |
213 for (int i = 0; i < SharedMemoryMacMultiProcessTest::s_memory_size; ++i) { | 214 for (int i = 0; i < SharedMemoryMacMultiProcessTest::s_memory_size; ++i) { |
214 DCHECK_EQ(start[i], 'a'); | 215 DCHECK_EQ(start[i], 'a'); |
215 } | 216 } |
216 return 0; | 217 return 0; |
217 } | 218 } |
218 | 219 |
219 // Tests that mapping shared memory with an offset works correctly. | 220 // Tests that mapping shared memory with an offset works correctly. |
220 TEST_F(SharedMemoryMacMultiProcessTest, MachBasedSharedMemoryWithOffset) { | 221 TEST_F(SharedMemoryMacMultiProcessTest, MachBasedSharedMemoryWithOffset) { |
221 SetUpChild("MachBasedSharedMemoryWithOffsetClient"); | 222 SetUpChild("MachBasedSharedMemoryWithOffsetClient"); |
222 | 223 |
223 SharedMemoryHandle shm(s_memory_size); | 224 SharedMemoryHandle shm(s_memory_size); |
224 ASSERT_TRUE(shm.IsValid()); | 225 ASSERT_TRUE(shm.IsValid()); |
225 SharedMemory shared_memory(shm, false); | 226 SharedMemory shared_memory(shm, false); |
226 shared_memory.Map(s_memory_size); | 227 shared_memory.Map(s_memory_size); |
227 | 228 |
228 size_t page_size = SysInfo::VMAllocationGranularity(); | 229 size_t page_size = SysInfo::VMAllocationGranularity(); |
229 char* start = static_cast<char*>(shared_memory.memory()); | 230 char* start = static_cast<char*>(shared_memory.memory()); |
230 memset(start, 'a', page_size); | 231 memset(start, 'a', page_size); |
231 memset(start + page_size, 'b', page_size); | 232 memset(start + page_size, 'b', page_size); |
232 memset(start + 2 * page_size, 'c', page_size); | 233 memset(start + 2 * page_size, 'c', page_size); |
233 | 234 |
234 // Send the underlying memory object to the client process. | 235 // Send the underlying memory object to the client process. |
235 SendMachPort(client_port_, shm.GetMemoryObject(), MACH_MSG_TYPE_COPY_SEND); | 236 SendMachPort( |
| 237 client_port_.get(), shm.GetMemoryObject(), MACH_MSG_TYPE_COPY_SEND); |
236 int rv = -1; | 238 int rv = -1; |
237 ASSERT_TRUE(child_process_.WaitForExitWithTimeout( | 239 ASSERT_TRUE(child_process_.WaitForExitWithTimeout( |
238 TestTimeouts::action_timeout(), &rv)); | 240 TestTimeouts::action_timeout(), &rv)); |
239 EXPECT_EQ(0, rv); | 241 EXPECT_EQ(0, rv); |
240 } | 242 } |
241 | 243 |
242 MULTIPROCESS_TEST_MAIN(MachBasedSharedMemoryWithOffsetClient) { | 244 MULTIPROCESS_TEST_MAIN(MachBasedSharedMemoryWithOffsetClient) { |
243 mac::ScopedMachReceiveRight client_port(CommonChildProcessSetUp()); | 245 mac::ScopedMachReceiveRight client_port(CommonChildProcessSetUp()); |
244 // The next mach port should be for a memory object. | 246 // The next mach port should be for a memory object. |
245 mach_port_t memory_object = ReceiveMachPort(client_port); | 247 mach_port_t memory_object = ReceiveMachPort(client_port.get()); |
246 SharedMemoryHandle shm(memory_object, | 248 SharedMemoryHandle shm(memory_object, |
247 SharedMemoryMacMultiProcessTest::s_memory_size, | 249 SharedMemoryMacMultiProcessTest::s_memory_size, |
248 GetCurrentProcId()); | 250 GetCurrentProcId()); |
249 SharedMemory shared_memory(shm, false); | 251 SharedMemory shared_memory(shm, false); |
250 size_t page_size = SysInfo::VMAllocationGranularity(); | 252 size_t page_size = SysInfo::VMAllocationGranularity(); |
251 shared_memory.MapAt(page_size, 2 * page_size); | 253 shared_memory.MapAt(page_size, 2 * page_size); |
252 const char* start = static_cast<const char*>(shared_memory.memory()); | 254 const char* start = static_cast<const char*>(shared_memory.memory()); |
253 for (size_t i = 0; i < page_size; ++i) { | 255 for (size_t i = 0; i < page_size; ++i) { |
254 DCHECK_EQ(start[i], 'b'); | 256 DCHECK_EQ(start[i], 'b'); |
255 } | 257 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 memset(shared_memory.memory(), 'a', s_memory_size); | 317 memset(shared_memory.memory(), 'a', s_memory_size); |
316 | 318 |
317 SharedMemoryHandle shm2 = shm.Duplicate(); | 319 SharedMemoryHandle shm2 = shm.Duplicate(); |
318 ASSERT_TRUE(shm2.IsValid()); | 320 ASSERT_TRUE(shm2.IsValid()); |
319 SharedMemory shared_memory2(shm, true); | 321 SharedMemory shared_memory2(shm, true); |
320 shared_memory2.Map(s_memory_size); | 322 shared_memory2.Map(s_memory_size); |
321 ASSERT_DEATH(memset(shared_memory2.memory(), 'b', s_memory_size), ""); | 323 ASSERT_DEATH(memset(shared_memory2.memory(), 'b', s_memory_size), ""); |
322 } | 324 } |
323 | 325 |
324 } // namespace base | 326 } // namespace base |
OLD | NEW |