Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2501)

Unified Diff: base/memory/shared_memory_mac_unittest.cc

Issue 1418113003: mac: Add auto-close and share-read-only functionality to SharedMemory. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comments from mark. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/memory/shared_memory_mac.cc ('k') | ipc/attachment_broker_mac_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/memory/shared_memory_mac_unittest.cc
diff --git a/base/memory/shared_memory_mac_unittest.cc b/base/memory/shared_memory_mac_unittest.cc
index e4c5e8b19b8d0dd6b426a77c895b16324ee9b5e1..c29302f490b4bf5d5e8d151a7a603a375d9d8192 100644
--- a/base/memory/shared_memory_mac_unittest.cc
+++ b/base/memory/shared_memory_mac_unittest.cc
@@ -7,6 +7,7 @@
#include <servers/bootstrap.h>
#include "base/command_line.h"
+#include "base/mac/mac_util.h"
#include "base/mac/mach_logging.h"
#include "base/mac/scoped_mach_port.h"
#include "base/memory/shared_memory.h"
@@ -22,6 +23,46 @@ namespace base {
namespace {
+// Gets the current and maximum protection levels of the memory region.
+// Returns whether the operation was successful.
+// |current| and |max| are output variables only populated on success.
+bool GetProtections(void* address, size_t size, int* current, int* max) {
+ vm_region_info_t region_info;
+ mach_vm_address_t mem_address = reinterpret_cast<mach_vm_address_t>(address);
+ mach_vm_size_t mem_size = size;
+ vm_region_basic_info_64 basic_info;
+
+ region_info = reinterpret_cast<vm_region_recurse_info_t>(&basic_info);
+ vm_region_flavor_t flavor = VM_REGION_BASIC_INFO_64;
+ memory_object_name_t memory_object;
+ mach_port_t ctype;
+
+ kern_return_t kr =
+ mach_vm_region(mach_task_self(), &mem_address, &mem_size, flavor,
+ region_info, &memory_object, &ctype);
+ if (kr != KERN_SUCCESS) {
+ LOG(ERROR) << "Failed to get region info.";
+ return false;
+ }
+
+ *current = basic_info.protection;
+ *max = basic_info.max_protection;
+ return true;
+}
+
+// Creates a new SharedMemory with the given |size|, filled with 'a'.
+scoped_ptr<SharedMemory> CreateSharedMemory(int size) {
+ SharedMemoryHandle shm(size);
+ if (!shm.IsValid()) {
+ LOG(ERROR) << "Failed to make SharedMemoryHandle";
+ return nullptr;
+ }
+ scoped_ptr<SharedMemory> shared_memory(new SharedMemory(shm, false));
+ shared_memory->Map(size);
+ memset(shared_memory->memory(), 'a', size);
+ return shared_memory;
+}
+
static const std::string g_service_switch_name = "service_name";
// Structs used to pass a mach port from client to server.
@@ -184,17 +225,18 @@ class SharedMemoryMacMultiProcessTest : public MultiProcessTest {
// Tests that content written to shared memory in the server process can be read
// by the child process.
TEST_F(SharedMemoryMacMultiProcessTest, MachBasedSharedMemory) {
+ // Mach-based SharedMemory isn't support on OSX 10.6.
+ if (mac::IsOSSnowLeopard())
+ return;
+
SetUpChild("MachBasedSharedMemoryClient");
- SharedMemoryHandle shm(s_memory_size);
- ASSERT_TRUE(shm.IsValid());
- SharedMemory shared_memory(shm, false);
- shared_memory.Map(s_memory_size);
- memset(shared_memory.memory(), 'a', s_memory_size);
+ scoped_ptr<SharedMemory> shared_memory(
+ CreateSharedMemory(s_memory_size).Pass());
// Send the underlying memory object to the client process.
- SendMachPort(
- client_port_.get(), shm.GetMemoryObject(), MACH_MSG_TYPE_COPY_SEND);
+ SendMachPort(client_port_.get(), shared_memory->handle().GetMemoryObject(),
+ MACH_MSG_TYPE_COPY_SEND);
int rv = -1;
ASSERT_TRUE(child_process_.WaitForExitWithTimeout(
TestTimeouts::action_timeout(), &rv));
@@ -219,6 +261,10 @@ MULTIPROCESS_TEST_MAIN(MachBasedSharedMemoryClient) {
// Tests that mapping shared memory with an offset works correctly.
TEST_F(SharedMemoryMacMultiProcessTest, MachBasedSharedMemoryWithOffset) {
+ // Mach-based SharedMemory isn't support on OSX 10.6.
+ if (mac::IsOSSnowLeopard())
+ return;
+
SetUpChild("MachBasedSharedMemoryWithOffsetClient");
SharedMemoryHandle shm(s_memory_size);
@@ -264,6 +310,10 @@ MULTIPROCESS_TEST_MAIN(MachBasedSharedMemoryWithOffsetClient) {
// Tests that duplication and closing has the right effect on Mach reference
// counts.
TEST_F(SharedMemoryMacMultiProcessTest, MachDuplicateAndClose) {
+ // Mach-based SharedMemory isn't support on OSX 10.6.
+ if (mac::IsOSSnowLeopard())
+ return;
+
mach_msg_type_number_t active_name_count = GetActiveNameCount();
// Making a new SharedMemoryHandle increments the name count.
@@ -291,6 +341,10 @@ TEST_F(SharedMemoryMacMultiProcessTest, MachDuplicateAndClose) {
// ownership, and that destroying the SharedMemory closes the SharedMemoryHandle
// as well.
TEST_F(SharedMemoryMacMultiProcessTest, MachSharedMemoryTakesOwnership) {
+ // Mach-based SharedMemory isn't support on OSX 10.6.
+ if (mac::IsOSSnowLeopard())
+ return;
+
mach_msg_type_number_t active_name_count = GetActiveNameCount();
// Making a new SharedMemoryHandle increments the name count.
@@ -310,17 +364,113 @@ TEST_F(SharedMemoryMacMultiProcessTest, MachSharedMemoryTakesOwnership) {
// Tests that the read-only flag works.
TEST_F(SharedMemoryMacMultiProcessTest, MachReadOnly) {
- SharedMemoryHandle shm(s_memory_size);
- ASSERT_TRUE(shm.IsValid());
- SharedMemory shared_memory(shm, false);
- shared_memory.Map(s_memory_size);
- memset(shared_memory.memory(), 'a', s_memory_size);
+ // Mach-based SharedMemory isn't support on OSX 10.6.
+ if (mac::IsOSSnowLeopard())
+ return;
+
+ scoped_ptr<SharedMemory> shared_memory(
+ CreateSharedMemory(s_memory_size).Pass());
- SharedMemoryHandle shm2 = shm.Duplicate();
+ SharedMemoryHandle shm2 = shared_memory->handle().Duplicate();
ASSERT_TRUE(shm2.IsValid());
- SharedMemory shared_memory2(shm, true);
+ SharedMemory shared_memory2(shm2, true);
shared_memory2.Map(s_memory_size);
ASSERT_DEATH(memset(shared_memory2.memory(), 'b', s_memory_size), "");
}
+// Tests that the method ShareToProcess() works.
+TEST_F(SharedMemoryMacMultiProcessTest, MachShareToProcess) {
+ // Mach-based SharedMemory isn't support on OSX 10.6.
+ if (mac::IsOSSnowLeopard())
+ return;
+
+ mach_msg_type_number_t active_name_count = GetActiveNameCount();
+
+ {
+ scoped_ptr<SharedMemory> shared_memory(
+ CreateSharedMemory(s_memory_size).Pass());
+
+ SharedMemoryHandle shm2;
+ ASSERT_TRUE(shared_memory->ShareToProcess(GetCurrentProcId(), &shm2));
+ ASSERT_TRUE(shm2.IsValid());
+ SharedMemory shared_memory2(shm2, true);
+ shared_memory2.Map(s_memory_size);
+
+ ASSERT_EQ(0, memcmp(shared_memory->memory(), shared_memory2.memory(),
+ s_memory_size));
+ }
+
+ EXPECT_EQ(active_name_count, GetActiveNameCount());
+}
+
+// Tests that the method ShareReadOnlyToProcess() creates a memory object that
+// is read only.
+TEST_F(SharedMemoryMacMultiProcessTest, MachShareToProcessReadonly) {
+ // Mach-based SharedMemory isn't support on OSX 10.6.
+ if (mac::IsOSSnowLeopard())
+ return;
+
+ scoped_ptr<SharedMemory> shared_memory(
+ CreateSharedMemory(s_memory_size).Pass());
+
+ // Check the protection levels.
+ int current_prot, max_prot;
+ ASSERT_TRUE(GetProtections(shared_memory->memory(),
+ shared_memory->mapped_size(), &current_prot,
+ &max_prot));
+ ASSERT_EQ(VM_PROT_READ | VM_PROT_WRITE, current_prot);
+ ASSERT_EQ(VM_PROT_READ | VM_PROT_WRITE, max_prot);
+
+ // Make a new memory object.
+ SharedMemoryHandle shm2;
+ ASSERT_TRUE(shared_memory->ShareReadOnlyToProcess(GetCurrentProcId(), &shm2));
+ ASSERT_TRUE(shm2.IsValid());
+
+ // Mapping with |readonly| set to |false| should fail.
+ SharedMemory shared_memory2(shm2, false);
+ shared_memory2.Map(s_memory_size);
+ ASSERT_EQ(nullptr, shared_memory2.memory());
+
+ // Now trying mapping with |readonly| set to |true|.
+ SharedMemory shared_memory3(shm2.Duplicate(), true);
+ shared_memory3.Map(s_memory_size);
+ ASSERT_NE(nullptr, shared_memory3.memory());
+
+ // Check the protection levels.
+ ASSERT_TRUE(GetProtections(shared_memory3.memory(),
+ shared_memory3.mapped_size(), &current_prot,
+ &max_prot));
+ ASSERT_EQ(VM_PROT_READ, current_prot);
+ ASSERT_EQ(VM_PROT_READ, max_prot);
+
+ // The memory should still be readonly, since the underlying memory object
+ // is readonly.
+ ASSERT_DEATH(memset(shared_memory2.memory(), 'b', s_memory_size), "");
+}
+
+// Tests that the method ShareReadOnlyToProcess() doesn't leak.
+TEST_F(SharedMemoryMacMultiProcessTest, MachShareToProcessReadonlyLeak) {
+ // Mach-based SharedMemory isn't support on OSX 10.6.
+ if (mac::IsOSSnowLeopard())
+ return;
+
+ mach_msg_type_number_t active_name_count = GetActiveNameCount();
+
+ {
+ scoped_ptr<SharedMemory> shared_memory(
+ CreateSharedMemory(s_memory_size).Pass());
+
+ SharedMemoryHandle shm2;
+ ASSERT_TRUE(
+ shared_memory->ShareReadOnlyToProcess(GetCurrentProcId(), &shm2));
+ ASSERT_TRUE(shm2.IsValid());
+
+ // Intentionally map with |readonly| set to |false|.
+ SharedMemory shared_memory2(shm2, false);
+ shared_memory2.Map(s_memory_size);
+ }
+
+ EXPECT_EQ(active_name_count, GetActiveNameCount());
+}
+
} // namespace base
« no previous file with comments | « base/memory/shared_memory_mac.cc ('k') | ipc/attachment_broker_mac_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698