Upstream version 7.35.139.0
[platform/framework/web/crosswalk.git] / src / base / memory / shared_memory_unittest.cc
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
3 // found in the LICENSE file.
4
5 #include "base/basictypes.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/memory/shared_memory.h"
8 #include "base/process/kill.h"
9 #include "base/rand_util.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/sys_info.h"
12 #include "base/test/multiprocess_test.h"
13 #include "base/threading/platform_thread.h"
14 #include "base/time/time.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "testing/multiprocess_func_list.h"
17
18 #if defined(OS_MACOSX)
19 #include "base/mac/scoped_nsautorelease_pool.h"
20 #endif
21
22 #if defined(OS_POSIX)
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <sys/mman.h>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <unistd.h>
29 #endif
30
31 #if defined(OS_WIN)
32 #include "base/win/scoped_handle.h"
33 #endif
34
35 static const int kNumThreads = 5;
36 #if !defined(OS_IOS)  // iOS does not allow multiple processes.
37 static const int kNumTasks = 5;
38 #endif
39
40 namespace base {
41
42 namespace {
43
44 // Each thread will open the shared memory.  Each thread will take a different 4
45 // byte int pointer, and keep changing it, with some small pauses in between.
46 // Verify that each thread's value in the shared memory is always correct.
47 class MultipleThreadMain : public PlatformThread::Delegate {
48  public:
49   explicit MultipleThreadMain(int16 id) : id_(id) {}
50   virtual ~MultipleThreadMain() {}
51
52   static void CleanUp() {
53     SharedMemory memory;
54     memory.Delete(s_test_name_);
55   }
56
57   // PlatformThread::Delegate interface.
58   virtual void ThreadMain() OVERRIDE {
59 #if defined(OS_MACOSX)
60     mac::ScopedNSAutoreleasePool pool;
61 #endif
62     const uint32 kDataSize = 1024;
63     SharedMemory memory;
64     bool rv = memory.CreateNamedDeprecated(s_test_name_, true, kDataSize);
65     EXPECT_TRUE(rv);
66     rv = memory.Map(kDataSize);
67     EXPECT_TRUE(rv);
68     int *ptr = static_cast<int*>(memory.memory()) + id_;
69     EXPECT_EQ(0, *ptr);
70
71     for (int idx = 0; idx < 100; idx++) {
72       *ptr = idx;
73       PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
74       EXPECT_EQ(*ptr, idx);
75     }
76     // Reset back to 0 for the next test that uses the same name.
77     *ptr = 0;
78
79     memory.Close();
80   }
81
82  private:
83   int16 id_;
84
85   static const char* const s_test_name_;
86
87   DISALLOW_COPY_AND_ASSIGN(MultipleThreadMain);
88 };
89
90 const char* const MultipleThreadMain::s_test_name_ =
91     "SharedMemoryOpenThreadTest";
92
93 // TODO(port):
94 // This test requires the ability to pass file descriptors between processes.
95 // We haven't done that yet in Chrome for POSIX.
96 #if defined(OS_WIN)
97 // Each thread will open the shared memory.  Each thread will take the memory,
98 // and keep changing it while trying to lock it, with some small pauses in
99 // between. Verify that each thread's value in the shared memory is always
100 // correct.
101 class MultipleLockThread : public PlatformThread::Delegate {
102  public:
103   explicit MultipleLockThread(int id) : id_(id) {}
104   virtual ~MultipleLockThread() {}
105
106   // PlatformThread::Delegate interface.
107   virtual void ThreadMain() OVERRIDE {
108     const uint32 kDataSize = sizeof(int);
109     SharedMemoryHandle handle = NULL;
110     {
111       SharedMemory memory1;
112       EXPECT_TRUE(memory1.CreateNamedDeprecated(
113           "SharedMemoryMultipleLockThreadTest", true, kDataSize));
114       EXPECT_TRUE(memory1.ShareToProcess(GetCurrentProcess(), &handle));
115       // TODO(paulg): Implement this once we have a posix version of
116       // SharedMemory::ShareToProcess.
117       EXPECT_TRUE(true);
118     }
119
120     SharedMemory memory2(handle, false);
121     EXPECT_TRUE(memory2.Map(kDataSize));
122     volatile int* const ptr = static_cast<int*>(memory2.memory());
123
124     for (int idx = 0; idx < 20; idx++) {
125       memory2.LockDeprecated();
126       int i = (id_ << 16) + idx;
127       *ptr = i;
128       PlatformThread::Sleep(TimeDelta::FromMilliseconds(1));
129       EXPECT_EQ(*ptr, i);
130       memory2.UnlockDeprecated();
131     }
132
133     memory2.Close();
134   }
135
136  private:
137   int id_;
138
139   DISALLOW_COPY_AND_ASSIGN(MultipleLockThread);
140 };
141 #endif
142
143 }  // namespace
144
145 // Android doesn't support SharedMemory::Open/Delete/
146 // CreateNamedDeprecated(openExisting=true)
147 #if !defined(OS_ANDROID)
148 TEST(SharedMemoryTest, OpenClose) {
149   const uint32 kDataSize = 1024;
150   std::string test_name = "SharedMemoryOpenCloseTest";
151
152   // Open two handles to a memory segment, confirm that they are mapped
153   // separately yet point to the same space.
154   SharedMemory memory1;
155   bool rv = memory1.Delete(test_name);
156   EXPECT_TRUE(rv);
157   rv = memory1.Delete(test_name);
158   EXPECT_TRUE(rv);
159   rv = memory1.Open(test_name, false);
160   EXPECT_FALSE(rv);
161   rv = memory1.CreateNamedDeprecated(test_name, false, kDataSize);
162   EXPECT_TRUE(rv);
163   rv = memory1.Map(kDataSize);
164   EXPECT_TRUE(rv);
165   SharedMemory memory2;
166   rv = memory2.Open(test_name, false);
167   EXPECT_TRUE(rv);
168   rv = memory2.Map(kDataSize);
169   EXPECT_TRUE(rv);
170   EXPECT_NE(memory1.memory(), memory2.memory());  // Compare the pointers.
171
172   // Make sure we don't segfault. (it actually happened!)
173   ASSERT_NE(memory1.memory(), static_cast<void*>(NULL));
174   ASSERT_NE(memory2.memory(), static_cast<void*>(NULL));
175
176   // Write data to the first memory segment, verify contents of second.
177   memset(memory1.memory(), '1', kDataSize);
178   EXPECT_EQ(memcmp(memory1.memory(), memory2.memory(), kDataSize), 0);
179
180   // Close the first memory segment, and verify the second has the right data.
181   memory1.Close();
182   char *start_ptr = static_cast<char *>(memory2.memory());
183   char *end_ptr = start_ptr + kDataSize;
184   for (char* ptr = start_ptr; ptr < end_ptr; ptr++)
185     EXPECT_EQ(*ptr, '1');
186
187   // Close the second memory segment.
188   memory2.Close();
189
190   rv = memory1.Delete(test_name);
191   EXPECT_TRUE(rv);
192   rv = memory2.Delete(test_name);
193   EXPECT_TRUE(rv);
194 }
195
196 TEST(SharedMemoryTest, OpenExclusive) {
197   const uint32 kDataSize = 1024;
198   const uint32 kDataSize2 = 2048;
199   std::ostringstream test_name_stream;
200   test_name_stream << "SharedMemoryOpenExclusiveTest."
201                    << Time::Now().ToDoubleT();
202   std::string test_name = test_name_stream.str();
203
204   // Open two handles to a memory segment and check that
205   // open_existing_deprecated works as expected.
206   SharedMemory memory1;
207   bool rv = memory1.CreateNamedDeprecated(test_name, false, kDataSize);
208   EXPECT_TRUE(rv);
209
210   // Memory1 knows it's size because it created it.
211   EXPECT_EQ(memory1.requested_size(), kDataSize);
212
213   rv = memory1.Map(kDataSize);
214   EXPECT_TRUE(rv);
215
216   // The mapped memory1 must be at least the size we asked for.
217   EXPECT_GE(memory1.mapped_size(), kDataSize);
218
219   // The mapped memory1 shouldn't exceed rounding for allocation granularity.
220   EXPECT_LT(memory1.mapped_size(),
221             kDataSize + base::SysInfo::VMAllocationGranularity());
222
223   memset(memory1.memory(), 'G', kDataSize);
224
225   SharedMemory memory2;
226   // Should not be able to create if openExisting is false.
227   rv = memory2.CreateNamedDeprecated(test_name, false, kDataSize2);
228   EXPECT_FALSE(rv);
229
230   // Should be able to create with openExisting true.
231   rv = memory2.CreateNamedDeprecated(test_name, true, kDataSize2);
232   EXPECT_TRUE(rv);
233
234   // Memory2 shouldn't know the size because we didn't create it.
235   EXPECT_EQ(memory2.requested_size(), 0U);
236
237   // We should be able to map the original size.
238   rv = memory2.Map(kDataSize);
239   EXPECT_TRUE(rv);
240
241   // The mapped memory2 must be at least the size of the original.
242   EXPECT_GE(memory2.mapped_size(), kDataSize);
243
244   // The mapped memory2 shouldn't exceed rounding for allocation granularity.
245   EXPECT_LT(memory2.mapped_size(),
246             kDataSize2 + base::SysInfo::VMAllocationGranularity());
247
248   // Verify that opening memory2 didn't truncate or delete memory 1.
249   char *start_ptr = static_cast<char *>(memory2.memory());
250   char *end_ptr = start_ptr + kDataSize;
251   for (char* ptr = start_ptr; ptr < end_ptr; ptr++) {
252     EXPECT_EQ(*ptr, 'G');
253   }
254
255   memory1.Close();
256   memory2.Close();
257
258   rv = memory1.Delete(test_name);
259   EXPECT_TRUE(rv);
260 }
261 #endif
262
263 // Create a set of N threads to each open a shared memory segment and write to
264 // it. Verify that they are always reading/writing consistent data.
265 TEST(SharedMemoryTest, MultipleThreads) {
266   MultipleThreadMain::CleanUp();
267   // On POSIX we have a problem when 2 threads try to create the shmem
268   // (a file) at exactly the same time, since create both creates the
269   // file and zerofills it.  We solve the problem for this unit test
270   // (make it not flaky) by starting with 1 thread, then
271   // intentionally don't clean up its shmem before running with
272   // kNumThreads.
273
274   int threadcounts[] = { 1, kNumThreads };
275   for (size_t i = 0; i < arraysize(threadcounts); i++) {
276     int numthreads = threadcounts[i];
277     scoped_ptr<PlatformThreadHandle[]> thread_handles;
278     scoped_ptr<MultipleThreadMain*[]> thread_delegates;
279
280     thread_handles.reset(new PlatformThreadHandle[numthreads]);
281     thread_delegates.reset(new MultipleThreadMain*[numthreads]);
282
283     // Spawn the threads.
284     for (int16 index = 0; index < numthreads; index++) {
285       PlatformThreadHandle pth;
286       thread_delegates[index] = new MultipleThreadMain(index);
287       EXPECT_TRUE(PlatformThread::Create(0, thread_delegates[index], &pth));
288       thread_handles[index] = pth;
289     }
290
291     // Wait for the threads to finish.
292     for (int index = 0; index < numthreads; index++) {
293       PlatformThread::Join(thread_handles[index]);
294       delete thread_delegates[index];
295     }
296   }
297   MultipleThreadMain::CleanUp();
298 }
299
300 // TODO(port): this test requires the MultipleLockThread class
301 // (defined above), which requires the ability to pass file
302 // descriptors between processes.  We haven't done that yet in Chrome
303 // for POSIX.
304 #if defined(OS_WIN)
305 // Create a set of threads to each open a shared memory segment and write to it
306 // with the lock held. Verify that they are always reading/writing consistent
307 // data.
308 TEST(SharedMemoryTest, Lock) {
309   PlatformThreadHandle thread_handles[kNumThreads];
310   MultipleLockThread* thread_delegates[kNumThreads];
311
312   // Spawn the threads.
313   for (int index = 0; index < kNumThreads; ++index) {
314     PlatformThreadHandle pth;
315     thread_delegates[index] = new MultipleLockThread(index);
316     EXPECT_TRUE(PlatformThread::Create(0, thread_delegates[index], &pth));
317     thread_handles[index] = pth;
318   }
319
320   // Wait for the threads to finish.
321   for (int index = 0; index < kNumThreads; ++index) {
322     PlatformThread::Join(thread_handles[index]);
323     delete thread_delegates[index];
324   }
325 }
326 #endif
327
328 // Allocate private (unique) shared memory with an empty string for a
329 // name.  Make sure several of them don't point to the same thing as
330 // we might expect if the names are equal.
331 TEST(SharedMemoryTest, AnonymousPrivate) {
332   int i, j;
333   int count = 4;
334   bool rv;
335   const uint32 kDataSize = 8192;
336
337   scoped_ptr<SharedMemory[]> memories(new SharedMemory[count]);
338   scoped_ptr<int*[]> pointers(new int*[count]);
339   ASSERT_TRUE(memories.get());
340   ASSERT_TRUE(pointers.get());
341
342   for (i = 0; i < count; i++) {
343     rv = memories[i].CreateAndMapAnonymous(kDataSize);
344     EXPECT_TRUE(rv);
345     int *ptr = static_cast<int*>(memories[i].memory());
346     EXPECT_TRUE(ptr);
347     pointers[i] = ptr;
348   }
349
350   for (i = 0; i < count; i++) {
351     // zero out the first int in each except for i; for that one, make it 100.
352     for (j = 0; j < count; j++) {
353       if (i == j)
354         pointers[j][0] = 100;
355       else
356         pointers[j][0] = 0;
357     }
358     // make sure there is no bleeding of the 100 into the other pointers
359     for (j = 0; j < count; j++) {
360       if (i == j)
361         EXPECT_EQ(100, pointers[j][0]);
362       else
363         EXPECT_EQ(0, pointers[j][0]);
364     }
365   }
366
367   for (int i = 0; i < count; i++) {
368     memories[i].Close();
369   }
370 }
371
372 TEST(SharedMemoryTest, ShareReadOnly) {
373   StringPiece contents = "Hello World";
374
375   SharedMemory writable_shmem;
376   SharedMemoryCreateOptions options;
377   options.size = contents.size();
378   options.share_read_only = true;
379   ASSERT_TRUE(writable_shmem.Create(options));
380   ASSERT_TRUE(writable_shmem.Map(options.size));
381   memcpy(writable_shmem.memory(), contents.data(), contents.size());
382   EXPECT_TRUE(writable_shmem.Unmap());
383
384   SharedMemoryHandle readonly_handle;
385   ASSERT_TRUE(writable_shmem.ShareReadOnlyToProcess(GetCurrentProcessHandle(),
386                                                     &readonly_handle));
387   SharedMemory readonly_shmem(readonly_handle, /*readonly=*/true);
388
389   ASSERT_TRUE(readonly_shmem.Map(contents.size()));
390   EXPECT_EQ(contents,
391             StringPiece(static_cast<const char*>(readonly_shmem.memory()),
392                         contents.size()));
393   EXPECT_TRUE(readonly_shmem.Unmap());
394
395   // Make sure the writable instance is still writable.
396   ASSERT_TRUE(writable_shmem.Map(contents.size()));
397   StringPiece new_contents = "Goodbye";
398   memcpy(writable_shmem.memory(), new_contents.data(), new_contents.size());
399   EXPECT_EQ(new_contents,
400             StringPiece(static_cast<const char*>(writable_shmem.memory()),
401                         new_contents.size()));
402
403   // We'd like to check that if we send the read-only segment to another
404   // process, then that other process can't reopen it read/write.  (Since that
405   // would be a security hole.)  Setting up multiple processes is hard in a
406   // unittest, so this test checks that the *current* process can't reopen the
407   // segment read/write.  I think the test here is stronger than we actually
408   // care about, but there's a remote possibility that sending a file over a
409   // pipe would transform it into read/write.
410   SharedMemoryHandle handle = readonly_shmem.handle();
411
412 #if defined(OS_ANDROID)
413   // The "read-only" handle is still writable on Android:
414   // http://crbug.com/320865
415   (void)handle;
416 #elif defined(OS_POSIX)
417   EXPECT_EQ(O_RDONLY, fcntl(handle.fd, F_GETFL) & O_ACCMODE)
418       << "The descriptor itself should be read-only.";
419
420   errno = 0;
421   void* writable = mmap(
422       NULL, contents.size(), PROT_READ | PROT_WRITE, MAP_SHARED, handle.fd, 0);
423   int mmap_errno = errno;
424   EXPECT_EQ(MAP_FAILED, writable)
425       << "It shouldn't be possible to re-mmap the descriptor writable.";
426   EXPECT_EQ(EACCES, mmap_errno) << strerror(mmap_errno);
427   if (writable != MAP_FAILED)
428     EXPECT_EQ(0, munmap(writable, readonly_shmem.mapped_size()));
429
430 #elif defined(OS_WIN)
431   EXPECT_EQ(NULL, MapViewOfFile(handle, FILE_MAP_WRITE, 0, 0, 0))
432       << "Shouldn't be able to map memory writable.";
433
434   HANDLE temp_handle;
435   BOOL rv = ::DuplicateHandle(GetCurrentProcess(),
436                               handle,
437                               GetCurrentProcess,
438                               &temp_handle,
439                               FILE_MAP_ALL_ACCESS,
440                               false,
441                               0);
442   EXPECT_EQ(FALSE, rv)
443       << "Shouldn't be able to duplicate the handle into a writable one.";
444   if (rv)
445     base::win::ScopedHandle writable_handle(temp_handle);
446 #else
447 #error Unexpected platform; write a test that tries to make 'handle' writable.
448 #endif  // defined(OS_POSIX) || defined(OS_WIN)
449 }
450
451 TEST(SharedMemoryTest, ShareToSelf) {
452   StringPiece contents = "Hello World";
453
454   SharedMemory shmem;
455   ASSERT_TRUE(shmem.CreateAndMapAnonymous(contents.size()));
456   memcpy(shmem.memory(), contents.data(), contents.size());
457   EXPECT_TRUE(shmem.Unmap());
458
459   SharedMemoryHandle shared_handle;
460   ASSERT_TRUE(shmem.ShareToProcess(GetCurrentProcessHandle(), &shared_handle));
461   SharedMemory shared(shared_handle, /*readonly=*/false);
462
463   ASSERT_TRUE(shared.Map(contents.size()));
464   EXPECT_EQ(
465       contents,
466       StringPiece(static_cast<const char*>(shared.memory()), contents.size()));
467
468   ASSERT_TRUE(shmem.ShareToProcess(GetCurrentProcessHandle(), &shared_handle));
469   SharedMemory readonly(shared_handle, /*readonly=*/true);
470
471   ASSERT_TRUE(readonly.Map(contents.size()));
472   EXPECT_EQ(contents,
473             StringPiece(static_cast<const char*>(readonly.memory()),
474                         contents.size()));
475 }
476
477 TEST(SharedMemoryTest, MapAt) {
478   ASSERT_TRUE(SysInfo::VMAllocationGranularity() >= sizeof(uint32));
479   const size_t kCount = SysInfo::VMAllocationGranularity();
480   const size_t kDataSize = kCount * sizeof(uint32);
481
482   SharedMemory memory;
483   ASSERT_TRUE(memory.CreateAndMapAnonymous(kDataSize));
484   uint32* ptr = static_cast<uint32*>(memory.memory());
485   ASSERT_NE(ptr, static_cast<void*>(NULL));
486
487   for (size_t i = 0; i < kCount; ++i) {
488     ptr[i] = i;
489   }
490
491   memory.Unmap();
492
493   off_t offset = SysInfo::VMAllocationGranularity();
494   ASSERT_TRUE(memory.MapAt(offset, kDataSize - offset));
495   offset /= sizeof(uint32);
496   ptr = static_cast<uint32*>(memory.memory());
497   ASSERT_NE(ptr, static_cast<void*>(NULL));
498   for (size_t i = offset; i < kCount; ++i) {
499     EXPECT_EQ(ptr[i - offset], i);
500   }
501 }
502
503 TEST(SharedMemoryTest, MapTwice) {
504   const uint32 kDataSize = 1024;
505   SharedMemory memory;
506   bool rv = memory.CreateAndMapAnonymous(kDataSize);
507   EXPECT_TRUE(rv);
508
509   void* old_address = memory.memory();
510
511   rv = memory.Map(kDataSize);
512   EXPECT_FALSE(rv);
513   EXPECT_EQ(old_address, memory.memory());
514 }
515
516 #if defined(OS_POSIX)
517 // Create a shared memory object, mmap it, and mprotect it to PROT_EXEC.
518 TEST(SharedMemoryTest, AnonymousExecutable) {
519   const uint32 kTestSize = 1 << 16;
520
521   SharedMemory shared_memory;
522   SharedMemoryCreateOptions options;
523   options.size = kTestSize;
524   options.executable = true;
525
526   EXPECT_TRUE(shared_memory.Create(options));
527   EXPECT_TRUE(shared_memory.Map(shared_memory.requested_size()));
528
529   EXPECT_EQ(0, mprotect(shared_memory.memory(), shared_memory.requested_size(),
530                         PROT_READ | PROT_EXEC));
531 }
532
533 // Android supports a different permission model than POSIX for its "ashmem"
534 // shared memory implementation. So the tests about file permissions are not
535 // included on Android.
536 #if !defined(OS_ANDROID)
537
538 // Set a umask and restore the old mask on destruction.
539 class ScopedUmaskSetter {
540  public:
541   explicit ScopedUmaskSetter(mode_t target_mask) {
542     old_umask_ = umask(target_mask);
543   }
544   ~ScopedUmaskSetter() { umask(old_umask_); }
545  private:
546   mode_t old_umask_;
547   DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedUmaskSetter);
548 };
549
550 // Create a shared memory object, check its permissions.
551 TEST(SharedMemoryTest, FilePermissionsAnonymous) {
552   const uint32 kTestSize = 1 << 8;
553
554   SharedMemory shared_memory;
555   SharedMemoryCreateOptions options;
556   options.size = kTestSize;
557   // Set a file mode creation mask that gives all permissions.
558   ScopedUmaskSetter permissive_mask(S_IWGRP | S_IWOTH);
559
560   EXPECT_TRUE(shared_memory.Create(options));
561
562   int shm_fd = shared_memory.handle().fd;
563   struct stat shm_stat;
564   EXPECT_EQ(0, fstat(shm_fd, &shm_stat));
565   // Neither the group, nor others should be able to read the shared memory
566   // file.
567   EXPECT_FALSE(shm_stat.st_mode & S_IRWXO);
568   EXPECT_FALSE(shm_stat.st_mode & S_IRWXG);
569 }
570
571 // Create a shared memory object, check its permissions.
572 TEST(SharedMemoryTest, FilePermissionsNamed) {
573   const uint32 kTestSize = 1 << 8;
574
575   SharedMemory shared_memory;
576   SharedMemoryCreateOptions options;
577   options.size = kTestSize;
578   std::string shared_mem_name = "shared_perm_test-" + IntToString(getpid()) +
579       "-" + Uint64ToString(RandUint64());
580   options.name_deprecated = &shared_mem_name;
581   // Set a file mode creation mask that gives all permissions.
582   ScopedUmaskSetter permissive_mask(S_IWGRP | S_IWOTH);
583
584   EXPECT_TRUE(shared_memory.Create(options));
585   // Clean-up the backing file name immediately, we don't need it.
586   EXPECT_TRUE(shared_memory.Delete(shared_mem_name));
587
588   int shm_fd = shared_memory.handle().fd;
589   struct stat shm_stat;
590   EXPECT_EQ(0, fstat(shm_fd, &shm_stat));
591   // Neither the group, nor others should have been able to open the shared
592   // memory file while its name existed.
593   EXPECT_FALSE(shm_stat.st_mode & S_IRWXO);
594   EXPECT_FALSE(shm_stat.st_mode & S_IRWXG);
595 }
596 #endif  // !defined(OS_ANDROID)
597
598 #endif  // defined(OS_POSIX)
599
600 // Map() will return addresses which are aligned to the platform page size, this
601 // varies from platform to platform though.  Since we'd like to advertise a
602 // minimum alignment that callers can count on, test for it here.
603 TEST(SharedMemoryTest, MapMinimumAlignment) {
604   static const int kDataSize = 8192;
605
606   SharedMemory shared_memory;
607   ASSERT_TRUE(shared_memory.CreateAndMapAnonymous(kDataSize));
608   EXPECT_EQ(0U, reinterpret_cast<uintptr_t>(
609       shared_memory.memory()) & (SharedMemory::MAP_MINIMUM_ALIGNMENT - 1));
610   shared_memory.Close();
611 }
612
613 #if !defined(OS_IOS)  // iOS does not allow multiple processes.
614
615 // On POSIX it is especially important we test shmem across processes,
616 // not just across threads.  But the test is enabled on all platforms.
617 class SharedMemoryProcessTest : public MultiProcessTest {
618  public:
619
620   static void CleanUp() {
621     SharedMemory memory;
622     memory.Delete(s_test_name_);
623   }
624
625   static int TaskTestMain() {
626     int errors = 0;
627 #if defined(OS_MACOSX)
628     mac::ScopedNSAutoreleasePool pool;
629 #endif
630     const uint32 kDataSize = 1024;
631     SharedMemory memory;
632     bool rv = memory.CreateNamedDeprecated(s_test_name_, true, kDataSize);
633     EXPECT_TRUE(rv);
634     if (rv != true)
635       errors++;
636     rv = memory.Map(kDataSize);
637     EXPECT_TRUE(rv);
638     if (rv != true)
639       errors++;
640     int *ptr = static_cast<int*>(memory.memory());
641
642     for (int idx = 0; idx < 20; idx++) {
643       memory.LockDeprecated();
644       int i = (1 << 16) + idx;
645       *ptr = i;
646       PlatformThread::Sleep(TimeDelta::FromMilliseconds(10));
647       if (*ptr != i)
648         errors++;
649       memory.UnlockDeprecated();
650     }
651
652     memory.Close();
653     return errors;
654   }
655
656  private:
657   static const char* const s_test_name_;
658 };
659
660 const char* const SharedMemoryProcessTest::s_test_name_ = "MPMem";
661
662 TEST_F(SharedMemoryProcessTest, Tasks) {
663   SharedMemoryProcessTest::CleanUp();
664
665   ProcessHandle handles[kNumTasks];
666   for (int index = 0; index < kNumTasks; ++index) {
667     handles[index] = SpawnChild("SharedMemoryTestMain");
668     ASSERT_TRUE(handles[index]);
669   }
670
671   int exit_code = 0;
672   for (int index = 0; index < kNumTasks; ++index) {
673     EXPECT_TRUE(WaitForExitCode(handles[index], &exit_code));
674     EXPECT_EQ(0, exit_code);
675   }
676
677   SharedMemoryProcessTest::CleanUp();
678 }
679
680 MULTIPROCESS_TEST_MAIN(SharedMemoryTestMain) {
681   return SharedMemoryProcessTest::TaskTestMain();
682 }
683
684 #endif  // !OS_IOS
685
686 }  // namespace base