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 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 MACH_LOG(ERROR, kr) << "Failed to get region info."; | 47 MACH_LOG(ERROR, kr) << "Failed to get region info."; |
48 return false; | 48 return false; |
49 } | 49 } |
50 | 50 |
51 *current = basic_info.protection; | 51 *current = basic_info.protection; |
52 *max = basic_info.max_protection; | 52 *max = basic_info.max_protection; |
53 return true; | 53 return true; |
54 } | 54 } |
55 | 55 |
56 // Creates a new SharedMemory with the given |size|, filled with 'a'. | 56 // Creates a new SharedMemory with the given |size|, filled with 'a'. |
57 scoped_ptr<SharedMemory> CreateSharedMemory(int size) { | 57 std::unique_ptr<SharedMemory> CreateSharedMemory(int size) { |
58 SharedMemoryHandle shm(size); | 58 SharedMemoryHandle shm(size); |
59 if (!shm.IsValid()) { | 59 if (!shm.IsValid()) { |
60 LOG(ERROR) << "Failed to make SharedMemoryHandle"; | 60 LOG(ERROR) << "Failed to make SharedMemoryHandle"; |
61 return nullptr; | 61 return nullptr; |
62 } | 62 } |
63 scoped_ptr<SharedMemory> shared_memory(new SharedMemory(shm, false)); | 63 std::unique_ptr<SharedMemory> shared_memory(new SharedMemory(shm, false)); |
64 shared_memory->Map(size); | 64 shared_memory->Map(size); |
65 memset(shared_memory->memory(), 'a', size); | 65 memset(shared_memory->memory(), 'a', size); |
66 return shared_memory; | 66 return shared_memory; |
67 } | 67 } |
68 | 68 |
69 static const std::string g_service_switch_name = "service_name"; | 69 static const std::string g_service_switch_name = "service_name"; |
70 | 70 |
71 // Structs used to pass a mach port from client to server. | 71 // Structs used to pass a mach port from client to server. |
72 struct MachSendPortMessage { | 72 struct MachSendPortMessage { |
73 mach_msg_header_t header; | 73 mach_msg_header_t header; |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 | 223 |
224 base::Process child_process_; | 224 base::Process child_process_; |
225 DISALLOW_COPY_AND_ASSIGN(SharedMemoryMacMultiProcessTest); | 225 DISALLOW_COPY_AND_ASSIGN(SharedMemoryMacMultiProcessTest); |
226 }; | 226 }; |
227 | 227 |
228 // Tests that content written to shared memory in the server process can be read | 228 // Tests that content written to shared memory in the server process can be read |
229 // by the child process. | 229 // by the child process. |
230 TEST_F(SharedMemoryMacMultiProcessTest, MachBasedSharedMemory) { | 230 TEST_F(SharedMemoryMacMultiProcessTest, MachBasedSharedMemory) { |
231 SetUpChild("MachBasedSharedMemoryClient"); | 231 SetUpChild("MachBasedSharedMemoryClient"); |
232 | 232 |
233 scoped_ptr<SharedMemory> shared_memory(CreateSharedMemory(s_memory_size)); | 233 std::unique_ptr<SharedMemory> shared_memory( |
| 234 CreateSharedMemory(s_memory_size)); |
234 | 235 |
235 // Send the underlying memory object to the client process. | 236 // Send the underlying memory object to the client process. |
236 SendMachPort(client_port_.get(), shared_memory->handle().GetMemoryObject(), | 237 SendMachPort(client_port_.get(), shared_memory->handle().GetMemoryObject(), |
237 MACH_MSG_TYPE_COPY_SEND); | 238 MACH_MSG_TYPE_COPY_SEND); |
238 int rv = -1; | 239 int rv = -1; |
239 ASSERT_TRUE(child_process_.WaitForExitWithTimeout( | 240 ASSERT_TRUE(child_process_.WaitForExitWithTimeout( |
240 TestTimeouts::action_timeout(), &rv)); | 241 TestTimeouts::action_timeout(), &rv)); |
241 EXPECT_EQ(0, rv); | 242 EXPECT_EQ(0, rv); |
242 } | 243 } |
243 | 244 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 // Closing the SharedMemoryHandle decrements the ref count. The second time | 325 // Closing the SharedMemoryHandle decrements the ref count. The second time |
325 // destroys the port. | 326 // destroys the port. |
326 shm.Close(); | 327 shm.Close(); |
327 EXPECT_EQ(active_name_count, GetActiveNameCount()); | 328 EXPECT_EQ(active_name_count, GetActiveNameCount()); |
328 } | 329 } |
329 | 330 |
330 // Tests that Mach shared memory can be mapped and unmapped. | 331 // Tests that Mach shared memory can be mapped and unmapped. |
331 TEST_F(SharedMemoryMacMultiProcessTest, MachUnmapMap) { | 332 TEST_F(SharedMemoryMacMultiProcessTest, MachUnmapMap) { |
332 mach_msg_type_number_t active_name_count = GetActiveNameCount(); | 333 mach_msg_type_number_t active_name_count = GetActiveNameCount(); |
333 | 334 |
334 scoped_ptr<SharedMemory> shared_memory = CreateSharedMemory(s_memory_size); | 335 std::unique_ptr<SharedMemory> shared_memory = |
| 336 CreateSharedMemory(s_memory_size); |
335 ASSERT_TRUE(shared_memory->Unmap()); | 337 ASSERT_TRUE(shared_memory->Unmap()); |
336 ASSERT_TRUE(shared_memory->Map(s_memory_size)); | 338 ASSERT_TRUE(shared_memory->Map(s_memory_size)); |
337 shared_memory.reset(); | 339 shared_memory.reset(); |
338 EXPECT_EQ(active_name_count, GetActiveNameCount()); | 340 EXPECT_EQ(active_name_count, GetActiveNameCount()); |
339 } | 341 } |
340 | 342 |
341 // Tests that passing a SharedMemoryHandle to a SharedMemory object also passes | 343 // Tests that passing a SharedMemoryHandle to a SharedMemory object also passes |
342 // ownership, and that destroying the SharedMemory closes the SharedMemoryHandle | 344 // ownership, and that destroying the SharedMemory closes the SharedMemoryHandle |
343 // as well. | 345 // as well. |
344 TEST_F(SharedMemoryMacMultiProcessTest, MachSharedMemoryTakesOwnership) { | 346 TEST_F(SharedMemoryMacMultiProcessTest, MachSharedMemoryTakesOwnership) { |
345 mach_msg_type_number_t active_name_count = GetActiveNameCount(); | 347 mach_msg_type_number_t active_name_count = GetActiveNameCount(); |
346 | 348 |
347 // Making a new SharedMemoryHandle increments the name count. | 349 // Making a new SharedMemoryHandle increments the name count. |
348 SharedMemoryHandle shm(s_memory_size); | 350 SharedMemoryHandle shm(s_memory_size); |
349 ASSERT_TRUE(shm.IsValid()); | 351 ASSERT_TRUE(shm.IsValid()); |
350 EXPECT_EQ(active_name_count + 1, GetActiveNameCount()); | 352 EXPECT_EQ(active_name_count + 1, GetActiveNameCount()); |
351 | 353 |
352 // Name count doesn't change when mapping the memory. | 354 // Name count doesn't change when mapping the memory. |
353 scoped_ptr<SharedMemory> shared_memory(new SharedMemory(shm, false)); | 355 std::unique_ptr<SharedMemory> shared_memory(new SharedMemory(shm, false)); |
354 shared_memory->Map(s_memory_size); | 356 shared_memory->Map(s_memory_size); |
355 EXPECT_EQ(active_name_count + 1, GetActiveNameCount()); | 357 EXPECT_EQ(active_name_count + 1, GetActiveNameCount()); |
356 | 358 |
357 // Destroying the SharedMemory object frees the resource. | 359 // Destroying the SharedMemory object frees the resource. |
358 shared_memory.reset(); | 360 shared_memory.reset(); |
359 EXPECT_EQ(active_name_count, GetActiveNameCount()); | 361 EXPECT_EQ(active_name_count, GetActiveNameCount()); |
360 } | 362 } |
361 | 363 |
362 // Tests that the read-only flag works. | 364 // Tests that the read-only flag works. |
363 TEST_F(SharedMemoryMacMultiProcessTest, MachReadOnly) { | 365 TEST_F(SharedMemoryMacMultiProcessTest, MachReadOnly) { |
364 scoped_ptr<SharedMemory> shared_memory(CreateSharedMemory(s_memory_size)); | 366 std::unique_ptr<SharedMemory> shared_memory( |
| 367 CreateSharedMemory(s_memory_size)); |
365 | 368 |
366 SharedMemoryHandle shm2 = shared_memory->handle().Duplicate(); | 369 SharedMemoryHandle shm2 = shared_memory->handle().Duplicate(); |
367 ASSERT_TRUE(shm2.IsValid()); | 370 ASSERT_TRUE(shm2.IsValid()); |
368 SharedMemory shared_memory2(shm2, true); | 371 SharedMemory shared_memory2(shm2, true); |
369 shared_memory2.Map(s_memory_size); | 372 shared_memory2.Map(s_memory_size); |
370 ASSERT_DEATH(memset(shared_memory2.memory(), 'b', s_memory_size), ""); | 373 ASSERT_DEATH(memset(shared_memory2.memory(), 'b', s_memory_size), ""); |
371 } | 374 } |
372 | 375 |
373 // Tests that the method ShareToProcess() works. | 376 // Tests that the method ShareToProcess() works. |
374 TEST_F(SharedMemoryMacMultiProcessTest, MachShareToProcess) { | 377 TEST_F(SharedMemoryMacMultiProcessTest, MachShareToProcess) { |
375 mach_msg_type_number_t active_name_count = GetActiveNameCount(); | 378 mach_msg_type_number_t active_name_count = GetActiveNameCount(); |
376 | 379 |
377 { | 380 { |
378 scoped_ptr<SharedMemory> shared_memory(CreateSharedMemory(s_memory_size)); | 381 std::unique_ptr<SharedMemory> shared_memory( |
| 382 CreateSharedMemory(s_memory_size)); |
379 | 383 |
380 SharedMemoryHandle shm2; | 384 SharedMemoryHandle shm2; |
381 ASSERT_TRUE(shared_memory->ShareToProcess(GetCurrentProcId(), &shm2)); | 385 ASSERT_TRUE(shared_memory->ShareToProcess(GetCurrentProcId(), &shm2)); |
382 ASSERT_TRUE(shm2.IsValid()); | 386 ASSERT_TRUE(shm2.IsValid()); |
383 SharedMemory shared_memory2(shm2, true); | 387 SharedMemory shared_memory2(shm2, true); |
384 shared_memory2.Map(s_memory_size); | 388 shared_memory2.Map(s_memory_size); |
385 | 389 |
386 ASSERT_EQ(0, memcmp(shared_memory->memory(), shared_memory2.memory(), | 390 ASSERT_EQ(0, memcmp(shared_memory->memory(), shared_memory2.memory(), |
387 s_memory_size)); | 391 s_memory_size)); |
388 } | 392 } |
389 | 393 |
390 EXPECT_EQ(active_name_count, GetActiveNameCount()); | 394 EXPECT_EQ(active_name_count, GetActiveNameCount()); |
391 } | 395 } |
392 | 396 |
393 // Tests that the method ShareReadOnlyToProcess() creates a memory object that | 397 // Tests that the method ShareReadOnlyToProcess() creates a memory object that |
394 // is read only. | 398 // is read only. |
395 TEST_F(SharedMemoryMacMultiProcessTest, MachShareToProcessReadonly) { | 399 TEST_F(SharedMemoryMacMultiProcessTest, MachShareToProcessReadonly) { |
396 scoped_ptr<SharedMemory> shared_memory(CreateSharedMemory(s_memory_size)); | 400 std::unique_ptr<SharedMemory> shared_memory( |
| 401 CreateSharedMemory(s_memory_size)); |
397 | 402 |
398 // Check the protection levels. | 403 // Check the protection levels. |
399 int current_prot, max_prot; | 404 int current_prot, max_prot; |
400 ASSERT_TRUE(GetProtections(shared_memory->memory(), | 405 ASSERT_TRUE(GetProtections(shared_memory->memory(), |
401 shared_memory->mapped_size(), ¤t_prot, | 406 shared_memory->mapped_size(), ¤t_prot, |
402 &max_prot)); | 407 &max_prot)); |
403 ASSERT_EQ(VM_PROT_READ | VM_PROT_WRITE, current_prot); | 408 ASSERT_EQ(VM_PROT_READ | VM_PROT_WRITE, current_prot); |
404 ASSERT_EQ(VM_PROT_READ | VM_PROT_WRITE, max_prot); | 409 ASSERT_EQ(VM_PROT_READ | VM_PROT_WRITE, max_prot); |
405 | 410 |
406 // Make a new memory object. | 411 // Make a new memory object. |
(...skipping 21 matching lines...) Expand all Loading... |
428 // The memory should still be readonly, since the underlying memory object | 433 // The memory should still be readonly, since the underlying memory object |
429 // is readonly. | 434 // is readonly. |
430 ASSERT_DEATH(memset(shared_memory2.memory(), 'b', s_memory_size), ""); | 435 ASSERT_DEATH(memset(shared_memory2.memory(), 'b', s_memory_size), ""); |
431 } | 436 } |
432 | 437 |
433 // Tests that the method ShareReadOnlyToProcess() doesn't leak. | 438 // Tests that the method ShareReadOnlyToProcess() doesn't leak. |
434 TEST_F(SharedMemoryMacMultiProcessTest, MachShareToProcessReadonlyLeak) { | 439 TEST_F(SharedMemoryMacMultiProcessTest, MachShareToProcessReadonlyLeak) { |
435 mach_msg_type_number_t active_name_count = GetActiveNameCount(); | 440 mach_msg_type_number_t active_name_count = GetActiveNameCount(); |
436 | 441 |
437 { | 442 { |
438 scoped_ptr<SharedMemory> shared_memory(CreateSharedMemory(s_memory_size)); | 443 std::unique_ptr<SharedMemory> shared_memory( |
| 444 CreateSharedMemory(s_memory_size)); |
439 | 445 |
440 SharedMemoryHandle shm2; | 446 SharedMemoryHandle shm2; |
441 ASSERT_TRUE( | 447 ASSERT_TRUE( |
442 shared_memory->ShareReadOnlyToProcess(GetCurrentProcId(), &shm2)); | 448 shared_memory->ShareReadOnlyToProcess(GetCurrentProcId(), &shm2)); |
443 ASSERT_TRUE(shm2.IsValid()); | 449 ASSERT_TRUE(shm2.IsValid()); |
444 | 450 |
445 // Intentionally map with |readonly| set to |false|. | 451 // Intentionally map with |readonly| set to |false|. |
446 SharedMemory shared_memory2(shm2, false); | 452 SharedMemory shared_memory2(shm2, false); |
447 shared_memory2.Map(s_memory_size); | 453 shared_memory2.Map(s_memory_size); |
448 } | 454 } |
449 | 455 |
450 EXPECT_EQ(active_name_count, GetActiveNameCount()); | 456 EXPECT_EQ(active_name_count, GetActiveNameCount()); |
451 } | 457 } |
452 | 458 |
453 } // namespace base | 459 } // namespace base |
OLD | NEW |