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

Side by Side Diff: base/memory/shared_memory_unittest.cc

Issue 1340223002: Remove named SharedMemory usage on Mac. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: self review Created 5 years, 3 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 unified diff | Download patch
« no previous file with comments | « base/memory/shared_memory_mac.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "base/atomicops.h" 5 #include "base/atomicops.h"
6 #include "base/basictypes.h" 6 #include "base/basictypes.h"
7 #include "base/memory/scoped_ptr.h" 7 #include "base/memory/scoped_ptr.h"
8 #include "base/memory/shared_memory.h" 8 #include "base/memory/shared_memory.h"
9 #include "base/process/kill.h" 9 #include "base/process/kill.h"
10 #include "base/rand_util.h" 10 #include "base/rand_util.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "base/sys_info.h" 12 #include "base/sys_info.h"
13 #include "base/test/multiprocess_test.h" 13 #include "base/test/multiprocess_test.h"
14 #include "base/threading/platform_thread.h" 14 #include "base/threading/platform_thread.h"
15 #include "base/time/time.h" 15 #include "base/time/time.h"
16 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "testing/multiprocess_func_list.h" 17 #include "testing/multiprocess_func_list.h"
18 18
19 #if defined(OS_MACOSX)
20 #include "base/mac/scoped_nsautorelease_pool.h"
21 #endif
22
23 #if defined(OS_POSIX) 19 #if defined(OS_POSIX)
24 #include <errno.h> 20 #include <errno.h>
25 #include <fcntl.h> 21 #include <fcntl.h>
26 #include <sys/mman.h> 22 #include <sys/mman.h>
27 #include <sys/stat.h> 23 #include <sys/stat.h>
28 #include <sys/types.h> 24 #include <sys/types.h>
29 #include <unistd.h> 25 #include <unistd.h>
30 #endif 26 #endif
31 27
32 #if defined(OS_WIN) 28 #if defined(OS_WIN)
33 #include "base/win/scoped_handle.h" 29 #include "base/win/scoped_handle.h"
34 #endif 30 #endif
35 31
36 static const int kNumThreads = 5;
37 #if !defined(OS_IOS) && !defined(OS_ANDROID)
38 static const int kNumTasks = 5;
39 #endif
40
41 namespace base { 32 namespace base {
42 33
43 namespace { 34 namespace {
44 35
36 #if !defined(OS_MACOSX)
45 // Each thread will open the shared memory. Each thread will take a different 4 37 // Each thread will open the shared memory. Each thread will take a different 4
46 // byte int pointer, and keep changing it, with some small pauses in between. 38 // byte int pointer, and keep changing it, with some small pauses in between.
47 // Verify that each thread's value in the shared memory is always correct. 39 // Verify that each thread's value in the shared memory is always correct.
48 class MultipleThreadMain : public PlatformThread::Delegate { 40 class MultipleThreadMain : public PlatformThread::Delegate {
49 public: 41 public:
50 explicit MultipleThreadMain(int16 id) : id_(id) {} 42 explicit MultipleThreadMain(int16 id) : id_(id) {}
51 ~MultipleThreadMain() override {} 43 ~MultipleThreadMain() override {}
52 44
53 static void CleanUp() { 45 static void CleanUp() {
54 SharedMemory memory; 46 SharedMemory memory;
55 memory.Delete(s_test_name_); 47 memory.Delete(s_test_name_);
56 } 48 }
57 49
58 // PlatformThread::Delegate interface. 50 // PlatformThread::Delegate interface.
59 void ThreadMain() override { 51 void ThreadMain() override {
60 #if defined(OS_MACOSX)
61 mac::ScopedNSAutoreleasePool pool;
62 #endif
63 const uint32 kDataSize = 1024; 52 const uint32 kDataSize = 1024;
64 SharedMemory memory; 53 SharedMemory memory;
65 bool rv = memory.CreateNamedDeprecated(s_test_name_, true, kDataSize); 54 bool rv = memory.CreateNamedDeprecated(s_test_name_, true, kDataSize);
66 EXPECT_TRUE(rv); 55 EXPECT_TRUE(rv);
67 rv = memory.Map(kDataSize); 56 rv = memory.Map(kDataSize);
68 EXPECT_TRUE(rv); 57 EXPECT_TRUE(rv);
69 int *ptr = static_cast<int*>(memory.memory()) + id_; 58 int* ptr = static_cast<int*>(memory.memory()) + id_;
70 EXPECT_EQ(0, *ptr); 59 EXPECT_EQ(0, *ptr);
71 60
72 for (int idx = 0; idx < 100; idx++) { 61 for (int idx = 0; idx < 100; idx++) {
73 *ptr = idx; 62 *ptr = idx;
74 PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); 63 PlatformThread::Sleep(TimeDelta::FromMilliseconds(1));
75 EXPECT_EQ(*ptr, idx); 64 EXPECT_EQ(*ptr, idx);
76 } 65 }
77 // Reset back to 0 for the next test that uses the same name. 66 // Reset back to 0 for the next test that uses the same name.
78 *ptr = 0; 67 *ptr = 0;
79 68
80 memory.Close(); 69 memory.Close();
81 } 70 }
82 71
83 private: 72 private:
84 int16 id_; 73 int16 id_;
85 74
86 static const char* const s_test_name_; 75 static const char* const s_test_name_;
87 76
88 DISALLOW_COPY_AND_ASSIGN(MultipleThreadMain); 77 DISALLOW_COPY_AND_ASSIGN(MultipleThreadMain);
89 }; 78 };
90 79
91 const char* const MultipleThreadMain::s_test_name_ = 80 const char* const MultipleThreadMain::s_test_name_ =
92 "SharedMemoryOpenThreadTest"; 81 "SharedMemoryOpenThreadTest";
82 #endif // !defined(OS_MACOSX)
93 83
94 } // namespace 84 } // namespace
95 85
96 // Android doesn't support SharedMemory::Open/Delete/ 86 // Android/Mac doesn't support SharedMemory::Open/Delete/
97 // CreateNamedDeprecated(openExisting=true) 87 // CreateNamedDeprecated(openExisting=true)
98 #if !defined(OS_ANDROID) 88 #if !defined(OS_ANDROID) && !defined(OS_MACOSX)
99 TEST(SharedMemoryTest, OpenClose) { 89 TEST(SharedMemoryTest, OpenClose) {
100 const uint32 kDataSize = 1024; 90 const uint32 kDataSize = 1024;
101 std::string test_name = "SharedMemoryOpenCloseTest"; 91 std::string test_name = "SharedMemoryOpenCloseTest";
102 92
103 // Open two handles to a memory segment, confirm that they are mapped 93 // Open two handles to a memory segment, confirm that they are mapped
104 // separately yet point to the same space. 94 // separately yet point to the same space.
105 SharedMemory memory1; 95 SharedMemory memory1;
106 bool rv = memory1.Delete(test_name); 96 bool rv = memory1.Delete(test_name);
107 EXPECT_TRUE(rv); 97 EXPECT_TRUE(rv);
108 rv = memory1.Delete(test_name); 98 rv = memory1.Delete(test_name);
(...skipping 14 matching lines...) Expand all
123 // Make sure we don't segfault. (it actually happened!) 113 // Make sure we don't segfault. (it actually happened!)
124 ASSERT_NE(memory1.memory(), static_cast<void*>(NULL)); 114 ASSERT_NE(memory1.memory(), static_cast<void*>(NULL));
125 ASSERT_NE(memory2.memory(), static_cast<void*>(NULL)); 115 ASSERT_NE(memory2.memory(), static_cast<void*>(NULL));
126 116
127 // Write data to the first memory segment, verify contents of second. 117 // Write data to the first memory segment, verify contents of second.
128 memset(memory1.memory(), '1', kDataSize); 118 memset(memory1.memory(), '1', kDataSize);
129 EXPECT_EQ(memcmp(memory1.memory(), memory2.memory(), kDataSize), 0); 119 EXPECT_EQ(memcmp(memory1.memory(), memory2.memory(), kDataSize), 0);
130 120
131 // Close the first memory segment, and verify the second has the right data. 121 // Close the first memory segment, and verify the second has the right data.
132 memory1.Close(); 122 memory1.Close();
133 char *start_ptr = static_cast<char *>(memory2.memory()); 123 char* start_ptr = static_cast<char*>(memory2.memory());
134 char *end_ptr = start_ptr + kDataSize; 124 char* end_ptr = start_ptr + kDataSize;
135 for (char* ptr = start_ptr; ptr < end_ptr; ptr++) 125 for (char* ptr = start_ptr; ptr < end_ptr; ptr++)
136 EXPECT_EQ(*ptr, '1'); 126 EXPECT_EQ(*ptr, '1');
137 127
138 // Close the second memory segment. 128 // Close the second memory segment.
139 memory2.Close(); 129 memory2.Close();
140 130
141 rv = memory1.Delete(test_name); 131 rv = memory1.Delete(test_name);
142 EXPECT_TRUE(rv); 132 EXPECT_TRUE(rv);
143 rv = memory2.Delete(test_name); 133 rv = memory2.Delete(test_name);
144 EXPECT_TRUE(rv); 134 EXPECT_TRUE(rv);
(...skipping 17 matching lines...) Expand all
162 EXPECT_EQ(memory1.requested_size(), kDataSize); 152 EXPECT_EQ(memory1.requested_size(), kDataSize);
163 153
164 rv = memory1.Map(kDataSize); 154 rv = memory1.Map(kDataSize);
165 EXPECT_TRUE(rv); 155 EXPECT_TRUE(rv);
166 156
167 // The mapped memory1 must be at least the size we asked for. 157 // The mapped memory1 must be at least the size we asked for.
168 EXPECT_GE(memory1.mapped_size(), kDataSize); 158 EXPECT_GE(memory1.mapped_size(), kDataSize);
169 159
170 // The mapped memory1 shouldn't exceed rounding for allocation granularity. 160 // The mapped memory1 shouldn't exceed rounding for allocation granularity.
171 EXPECT_LT(memory1.mapped_size(), 161 EXPECT_LT(memory1.mapped_size(),
172 kDataSize + base::SysInfo::VMAllocationGranularity()); 162 kDataSize + SysInfo::VMAllocationGranularity());
173 163
174 memset(memory1.memory(), 'G', kDataSize); 164 memset(memory1.memory(), 'G', kDataSize);
175 165
176 SharedMemory memory2; 166 SharedMemory memory2;
177 // Should not be able to create if openExisting is false. 167 // Should not be able to create if openExisting is false.
178 rv = memory2.CreateNamedDeprecated(test_name, false, kDataSize2); 168 rv = memory2.CreateNamedDeprecated(test_name, false, kDataSize2);
179 EXPECT_FALSE(rv); 169 EXPECT_FALSE(rv);
180 170
181 // Should be able to create with openExisting true. 171 // Should be able to create with openExisting true.
182 rv = memory2.CreateNamedDeprecated(test_name, true, kDataSize2); 172 rv = memory2.CreateNamedDeprecated(test_name, true, kDataSize2);
183 EXPECT_TRUE(rv); 173 EXPECT_TRUE(rv);
184 174
185 // Memory2 shouldn't know the size because we didn't create it. 175 // Memory2 shouldn't know the size because we didn't create it.
186 EXPECT_EQ(memory2.requested_size(), 0U); 176 EXPECT_EQ(memory2.requested_size(), 0U);
187 177
188 // We should be able to map the original size. 178 // We should be able to map the original size.
189 rv = memory2.Map(kDataSize); 179 rv = memory2.Map(kDataSize);
190 EXPECT_TRUE(rv); 180 EXPECT_TRUE(rv);
191 181
192 // The mapped memory2 must be at least the size of the original. 182 // The mapped memory2 must be at least the size of the original.
193 EXPECT_GE(memory2.mapped_size(), kDataSize); 183 EXPECT_GE(memory2.mapped_size(), kDataSize);
194 184
195 // The mapped memory2 shouldn't exceed rounding for allocation granularity. 185 // The mapped memory2 shouldn't exceed rounding for allocation granularity.
196 EXPECT_LT(memory2.mapped_size(), 186 EXPECT_LT(memory2.mapped_size(),
197 kDataSize2 + base::SysInfo::VMAllocationGranularity()); 187 kDataSize2 + SysInfo::VMAllocationGranularity());
198 188
199 // Verify that opening memory2 didn't truncate or delete memory 1. 189 // Verify that opening memory2 didn't truncate or delete memory 1.
200 char *start_ptr = static_cast<char *>(memory2.memory()); 190 char* start_ptr = static_cast<char*>(memory2.memory());
201 char *end_ptr = start_ptr + kDataSize; 191 char* end_ptr = start_ptr + kDataSize;
202 for (char* ptr = start_ptr; ptr < end_ptr; ptr++) { 192 for (char* ptr = start_ptr; ptr < end_ptr; ptr++) {
203 EXPECT_EQ(*ptr, 'G'); 193 EXPECT_EQ(*ptr, 'G');
204 } 194 }
205 195
206 memory1.Close(); 196 memory1.Close();
207 memory2.Close(); 197 memory2.Close();
208 198
209 rv = memory1.Delete(test_name); 199 rv = memory1.Delete(test_name);
210 EXPECT_TRUE(rv); 200 EXPECT_TRUE(rv);
211 } 201 }
212 #endif 202 #endif // !defined(OS_ANDROID) && !defined(OS_MACOSX)
213 203
214 // Check that memory is still mapped after its closed. 204 // Check that memory is still mapped after its closed.
215 TEST(SharedMemoryTest, CloseNoUnmap) { 205 TEST(SharedMemoryTest, CloseNoUnmap) {
216 const size_t kDataSize = 4096; 206 const size_t kDataSize = 4096;
217 207
218 SharedMemory memory; 208 SharedMemory memory;
219 ASSERT_TRUE(memory.CreateAndMapAnonymous(kDataSize)); 209 ASSERT_TRUE(memory.CreateAndMapAnonymous(kDataSize));
220 char* ptr = static_cast<char*>(memory.memory()); 210 char* ptr = static_cast<char*>(memory.memory());
221 ASSERT_NE(ptr, static_cast<void*>(NULL)); 211 ASSERT_NE(ptr, static_cast<void*>(NULL));
222 memset(ptr, 'G', kDataSize); 212 memset(ptr, 'G', kDataSize);
223 213
224 memory.Close(); 214 memory.Close();
225 215
226 EXPECT_EQ(ptr, memory.memory()); 216 EXPECT_EQ(ptr, memory.memory());
227 EXPECT_EQ(SharedMemory::NULLHandle(), memory.handle()); 217 EXPECT_EQ(SharedMemory::NULLHandle(), memory.handle());
228 218
229 for (size_t i = 0; i < kDataSize; i++) { 219 for (size_t i = 0; i < kDataSize; i++) {
230 EXPECT_EQ('G', ptr[i]); 220 EXPECT_EQ('G', ptr[i]);
231 } 221 }
232 222
233 memory.Unmap(); 223 memory.Unmap();
234 EXPECT_EQ(nullptr, memory.memory()); 224 EXPECT_EQ(nullptr, memory.memory());
235 } 225 }
236 226
227 #if !defined(OS_MACOSX)
237 // Create a set of N threads to each open a shared memory segment and write to 228 // Create a set of N threads to each open a shared memory segment and write to
238 // it. Verify that they are always reading/writing consistent data. 229 // it. Verify that they are always reading/writing consistent data.
239 TEST(SharedMemoryTest, MultipleThreads) { 230 TEST(SharedMemoryTest, MultipleThreads) {
231 const int kNumThreads = 5;
232
240 MultipleThreadMain::CleanUp(); 233 MultipleThreadMain::CleanUp();
241 // On POSIX we have a problem when 2 threads try to create the shmem 234 // On POSIX we have a problem when 2 threads try to create the shmem
242 // (a file) at exactly the same time, since create both creates the 235 // (a file) at exactly the same time, since create both creates the
243 // file and zerofills it. We solve the problem for this unit test 236 // file and zerofills it. We solve the problem for this unit test
244 // (make it not flaky) by starting with 1 thread, then 237 // (make it not flaky) by starting with 1 thread, then
245 // intentionally don't clean up its shmem before running with 238 // intentionally don't clean up its shmem before running with
246 // kNumThreads. 239 // kNumThreads.
247 240
248 int threadcounts[] = { 1, kNumThreads }; 241 int threadcounts[] = { 1, kNumThreads };
249 for (size_t i = 0; i < arraysize(threadcounts); i++) { 242 for (size_t i = 0; i < arraysize(threadcounts); i++) {
(...skipping 13 matching lines...) Expand all
263 } 256 }
264 257
265 // Wait for the threads to finish. 258 // Wait for the threads to finish.
266 for (int index = 0; index < numthreads; index++) { 259 for (int index = 0; index < numthreads; index++) {
267 PlatformThread::Join(thread_handles[index]); 260 PlatformThread::Join(thread_handles[index]);
268 delete thread_delegates[index]; 261 delete thread_delegates[index];
269 } 262 }
270 } 263 }
271 MultipleThreadMain::CleanUp(); 264 MultipleThreadMain::CleanUp();
272 } 265 }
266 #endif
273 267
274 // Allocate private (unique) shared memory with an empty string for a 268 // Allocate private (unique) shared memory with an empty string for a
275 // name. Make sure several of them don't point to the same thing as 269 // name. Make sure several of them don't point to the same thing as
276 // we might expect if the names are equal. 270 // we might expect if the names are equal.
277 TEST(SharedMemoryTest, AnonymousPrivate) { 271 TEST(SharedMemoryTest, AnonymousPrivate) {
278 int i, j; 272 int i, j;
279 int count = 4; 273 int count = 4;
280 bool rv; 274 bool rv;
281 const uint32 kDataSize = 8192; 275 const uint32 kDataSize = 8192;
282 276
283 scoped_ptr<SharedMemory[]> memories(new SharedMemory[count]); 277 scoped_ptr<SharedMemory[]> memories(new SharedMemory[count]);
284 scoped_ptr<int*[]> pointers(new int*[count]); 278 scoped_ptr<int*[]> pointers(new int*[count]);
285 ASSERT_TRUE(memories.get()); 279 ASSERT_TRUE(memories.get());
286 ASSERT_TRUE(pointers.get()); 280 ASSERT_TRUE(pointers.get());
287 281
288 for (i = 0; i < count; i++) { 282 for (i = 0; i < count; i++) {
289 rv = memories[i].CreateAndMapAnonymous(kDataSize); 283 rv = memories[i].CreateAndMapAnonymous(kDataSize);
290 EXPECT_TRUE(rv); 284 EXPECT_TRUE(rv);
291 int *ptr = static_cast<int*>(memories[i].memory()); 285 int* ptr = static_cast<int*>(memories[i].memory());
292 EXPECT_TRUE(ptr); 286 EXPECT_TRUE(ptr);
293 pointers[i] = ptr; 287 pointers[i] = ptr;
294 } 288 }
295 289
296 for (i = 0; i < count; i++) { 290 for (i = 0; i < count; i++) {
297 // zero out the first int in each except for i; for that one, make it 100. 291 // zero out the first int in each except for i; for that one, make it 100.
298 for (j = 0; j < count; j++) { 292 for (j = 0; j < count; j++) {
299 if (i == j) 293 if (i == j)
300 pointers[j][0] = 100; 294 pointers[j][0] = 100;
301 else 295 else
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 BOOL rv = ::DuplicateHandle(GetCurrentProcess(), 376 BOOL rv = ::DuplicateHandle(GetCurrentProcess(),
383 handle, 377 handle,
384 GetCurrentProcess(), 378 GetCurrentProcess(),
385 &temp_handle, 379 &temp_handle,
386 FILE_MAP_ALL_ACCESS, 380 FILE_MAP_ALL_ACCESS,
387 false, 381 false,
388 0); 382 0);
389 EXPECT_EQ(FALSE, rv) 383 EXPECT_EQ(FALSE, rv)
390 << "Shouldn't be able to duplicate the handle into a writable one."; 384 << "Shouldn't be able to duplicate the handle into a writable one.";
391 if (rv) 385 if (rv)
392 base::win::ScopedHandle writable_handle(temp_handle); 386 win::ScopedHandle writable_handle(temp_handle);
393 rv = ::DuplicateHandle(GetCurrentProcess(), 387 rv = ::DuplicateHandle(GetCurrentProcess(),
394 handle, 388 handle,
395 GetCurrentProcess(), 389 GetCurrentProcess(),
396 &temp_handle, 390 &temp_handle,
397 FILE_MAP_READ, 391 FILE_MAP_READ,
398 false, 392 false,
399 0); 393 0);
400 EXPECT_EQ(TRUE, rv) 394 EXPECT_EQ(TRUE, rv)
401 << "Should be able to duplicate the handle into a readable one."; 395 << "Should be able to duplicate the handle into a readable one.";
402 if (rv) 396 if (rv)
403 base::win::ScopedHandle writable_handle(temp_handle); 397 win::ScopedHandle writable_handle(temp_handle);
404 #else 398 #else
405 #error Unexpected platform; write a test that tries to make 'handle' writable. 399 #error Unexpected platform; write a test that tries to make 'handle' writable.
406 #endif // defined(OS_POSIX) || defined(OS_WIN) 400 #endif // defined(OS_POSIX) || defined(OS_WIN)
407 } 401 }
408 402
409 TEST(SharedMemoryTest, ShareToSelf) { 403 TEST(SharedMemoryTest, ShareToSelf) {
410 StringPiece contents = "Hello World"; 404 StringPiece contents = "Hello World";
411 405
412 SharedMemory shmem; 406 SharedMemory shmem;
413 ASSERT_TRUE(shmem.CreateAndMapAnonymous(contents.size())); 407 ASSERT_TRUE(shmem.CreateAndMapAnonymous(contents.size()));
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 struct stat shm_stat; 519 struct stat shm_stat;
526 EXPECT_EQ(0, fstat(shm_fd, &shm_stat)); 520 EXPECT_EQ(0, fstat(shm_fd, &shm_stat));
527 // Neither the group, nor others should be able to read the shared memory 521 // Neither the group, nor others should be able to read the shared memory
528 // file. 522 // file.
529 EXPECT_FALSE(shm_stat.st_mode & S_IRWXO); 523 EXPECT_FALSE(shm_stat.st_mode & S_IRWXO);
530 EXPECT_FALSE(shm_stat.st_mode & S_IRWXG); 524 EXPECT_FALSE(shm_stat.st_mode & S_IRWXG);
531 } 525 }
532 526
533 // Create a shared memory object, check its permissions. 527 // Create a shared memory object, check its permissions.
534 TEST(SharedMemoryTest, FilePermissionsNamed) { 528 TEST(SharedMemoryTest, FilePermissionsNamed) {
535 const uint32 kTestSize = 1 << 8; 529 const uint32_t kTestSize = 1 << 8;
536 530
537 SharedMemory shared_memory; 531 SharedMemory shared_memory;
538 SharedMemoryCreateOptions options; 532 SharedMemoryCreateOptions options;
539 options.size = kTestSize; 533 options.size = kTestSize;
540 std::string shared_mem_name = "shared_perm_test-" + IntToString(getpid()) + 534
541 "-" + Uint64ToString(RandUint64());
542 options.name_deprecated = &shared_mem_name;
543 // Set a file mode creation mask that gives all permissions. 535 // Set a file mode creation mask that gives all permissions.
544 ScopedUmaskSetter permissive_mask(S_IWGRP | S_IWOTH); 536 ScopedUmaskSetter permissive_mask(S_IWGRP | S_IWOTH);
545 537
546 EXPECT_TRUE(shared_memory.Create(options)); 538 EXPECT_TRUE(shared_memory.Create(options));
547 // Clean-up the backing file name immediately, we don't need it.
548 EXPECT_TRUE(shared_memory.Delete(shared_mem_name));
549 539
550 int shm_fd = 540 int fd = SharedMemory::GetFdFromSharedMemoryHandle(shared_memory.handle());
551 SharedMemory::GetFdFromSharedMemoryHandle(shared_memory.handle());
552 struct stat shm_stat; 541 struct stat shm_stat;
553 EXPECT_EQ(0, fstat(shm_fd, &shm_stat)); 542 EXPECT_EQ(0, fstat(fd, &shm_stat));
554 // Neither the group, nor others should have been able to open the shared 543 // Neither the group, nor others should have been able to open the shared
555 // memory file while its name existed. 544 // memory file while its name existed.
556 EXPECT_FALSE(shm_stat.st_mode & S_IRWXO); 545 EXPECT_FALSE(shm_stat.st_mode & S_IRWXO);
557 EXPECT_FALSE(shm_stat.st_mode & S_IRWXG); 546 EXPECT_FALSE(shm_stat.st_mode & S_IRWXG);
558 } 547 }
559 #endif // !defined(OS_ANDROID) 548 #endif // !defined(OS_ANDROID)
560 549
561 #endif // defined(OS_POSIX) 550 #endif // defined(OS_POSIX)
562 551
563 // Map() will return addresses which are aligned to the platform page size, this 552 // Map() will return addresses which are aligned to the platform page size, this
564 // varies from platform to platform though. Since we'd like to advertise a 553 // varies from platform to platform though. Since we'd like to advertise a
565 // minimum alignment that callers can count on, test for it here. 554 // minimum alignment that callers can count on, test for it here.
566 TEST(SharedMemoryTest, MapMinimumAlignment) { 555 TEST(SharedMemoryTest, MapMinimumAlignment) {
567 static const int kDataSize = 8192; 556 static const int kDataSize = 8192;
568 557
569 SharedMemory shared_memory; 558 SharedMemory shared_memory;
570 ASSERT_TRUE(shared_memory.CreateAndMapAnonymous(kDataSize)); 559 ASSERT_TRUE(shared_memory.CreateAndMapAnonymous(kDataSize));
571 EXPECT_EQ(0U, reinterpret_cast<uintptr_t>( 560 EXPECT_EQ(0U, reinterpret_cast<uintptr_t>(
572 shared_memory.memory()) & (SharedMemory::MAP_MINIMUM_ALIGNMENT - 1)); 561 shared_memory.memory()) & (SharedMemory::MAP_MINIMUM_ALIGNMENT - 1));
573 shared_memory.Close(); 562 shared_memory.Close();
574 } 563 }
575 564
576 // iOS does not allow multiple processes. 565 // iOS does not allow multiple processes.
577 // Android ashmem doesn't support named shared memory. 566 // Android ashmem does not support named shared memory.
578 #if !defined(OS_IOS) && !defined(OS_ANDROID) 567 // Mac SharedMemory does not support named shared memory. crbug.com/345734
579 568 #if !defined(OS_IOS) && !defined(OS_ANDROID) && !defined(OS_MACOSX)
580 // On POSIX it is especially important we test shmem across processes, 569 // On POSIX it is especially important we test shmem across processes,
581 // not just across threads. But the test is enabled on all platforms. 570 // not just across threads. But the test is enabled on all platforms.
582 class SharedMemoryProcessTest : public MultiProcessTest { 571 class SharedMemoryProcessTest : public MultiProcessTest {
583 public: 572 public:
584
585 static void CleanUp() { 573 static void CleanUp() {
586 SharedMemory memory; 574 SharedMemory memory;
587 memory.Delete(s_test_name_); 575 memory.Delete(s_test_name_);
588 } 576 }
589 577
590 static int TaskTestMain() { 578 static int TaskTestMain() {
591 int errors = 0; 579 int errors = 0;
592 #if defined(OS_MACOSX)
593 mac::ScopedNSAutoreleasePool pool;
594 #endif
595 SharedMemory memory; 580 SharedMemory memory;
596 bool rv = memory.CreateNamedDeprecated(s_test_name_, true, s_data_size_); 581 bool rv = memory.CreateNamedDeprecated(s_test_name_, true, s_data_size_);
597 EXPECT_TRUE(rv); 582 EXPECT_TRUE(rv);
598 if (rv != true) 583 if (rv != true)
599 errors++; 584 errors++;
600 rv = memory.Map(s_data_size_); 585 rv = memory.Map(s_data_size_);
601 EXPECT_TRUE(rv); 586 EXPECT_TRUE(rv);
602 if (rv != true) 587 if (rv != true)
603 errors++; 588 errors++;
604 int *ptr = static_cast<int*>(memory.memory()); 589 int* ptr = static_cast<int*>(memory.memory());
605 590
606 // This runs concurrently in multiple processes. Writes need to be atomic. 591 // This runs concurrently in multiple processes. Writes need to be atomic.
607 base::subtle::Barrier_AtomicIncrement(ptr, 1); 592 subtle::Barrier_AtomicIncrement(ptr, 1);
608 memory.Close(); 593 memory.Close();
609 return errors; 594 return errors;
610 } 595 }
611 596
612 static const char* const s_test_name_; 597 static const char* const s_test_name_;
613 static const uint32 s_data_size_; 598 static const uint32 s_data_size_;
614 }; 599 };
615 600
616 const char* const SharedMemoryProcessTest::s_test_name_ = "MPMem"; 601 const char* const SharedMemoryProcessTest::s_test_name_ = "MPMem";
617 const uint32 SharedMemoryProcessTest::s_data_size_ = 1024; 602 const uint32 SharedMemoryProcessTest::s_data_size_ = 1024;
618 603
619 TEST_F(SharedMemoryProcessTest, SharedMemoryAcrossProcesses) { 604 TEST_F(SharedMemoryProcessTest, SharedMemoryAcrossProcesses) {
605 const int kNumTasks = 5;
606
620 SharedMemoryProcessTest::CleanUp(); 607 SharedMemoryProcessTest::CleanUp();
621 608
622 // Create a shared memory region. Set the first word to 0. 609 // Create a shared memory region. Set the first word to 0.
623 SharedMemory memory; 610 SharedMemory memory;
624 bool rv = memory.CreateNamedDeprecated(s_test_name_, true, s_data_size_); 611 bool rv = memory.CreateNamedDeprecated(s_test_name_, true, s_data_size_);
625 ASSERT_TRUE(rv); 612 ASSERT_TRUE(rv);
626 rv = memory.Map(s_data_size_); 613 rv = memory.Map(s_data_size_);
627 ASSERT_TRUE(rv); 614 ASSERT_TRUE(rv);
628 int* ptr = static_cast<int*>(memory.memory()); 615 int* ptr = static_cast<int*>(memory.memory());
629 *ptr = 0; 616 *ptr = 0;
(...skipping 16 matching lines...) Expand all
646 // Check that the shared memory region reflects |kNumTasks| increments. 633 // Check that the shared memory region reflects |kNumTasks| increments.
647 ASSERT_EQ(kNumTasks, *ptr); 634 ASSERT_EQ(kNumTasks, *ptr);
648 635
649 memory.Close(); 636 memory.Close();
650 SharedMemoryProcessTest::CleanUp(); 637 SharedMemoryProcessTest::CleanUp();
651 } 638 }
652 639
653 MULTIPROCESS_TEST_MAIN(SharedMemoryTestMain) { 640 MULTIPROCESS_TEST_MAIN(SharedMemoryTestMain) {
654 return SharedMemoryProcessTest::TaskTestMain(); 641 return SharedMemoryProcessTest::TaskTestMain();
655 } 642 }
656 643 #endif // !defined(OS_IOS) && !defined(OS_ANDROID) && !defined(OS_MACOSX)
657 #endif // !defined(OS_IOS) && !defined(OS_ANDROID)
658 644
659 } // namespace base 645 } // namespace base
OLDNEW
« no previous file with comments | « base/memory/shared_memory_mac.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698