diff options
author | jrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-05 19:04:34 +0000 |
---|---|---|
committer | jrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-05 19:04:34 +0000 |
commit | ec031eb72100175a7577948b4062432df362fafe (patch) | |
tree | 46a39fd13e468a542422e0a7b74de27d69fd9e90 /base/shared_memory_unittest.cc | |
parent | 9a98651859b42474865234e53c861f75b63e70a1 (diff) | |
download | chromium_src-ec031eb72100175a7577948b4062432df362fafe.zip chromium_src-ec031eb72100175a7577948b4062432df362fafe.tar.gz chromium_src-ec031eb72100175a7577948b4062432df362fafe.tar.bz2 |
Transition POSIX shmem to use lockf(), not semaphores. Eliminates
resource leak possibility; allows complete sharing of shmem by fd
without name.
Add actual multiprocess shmem/locking unit test.
Fix flaky shmem unit test.
agl: please review.
Amanda: please look over as you've been here before.
Review URL: http://codereview.chromium.org/21063
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9235 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/shared_memory_unittest.cc')
-rw-r--r-- | base/shared_memory_unittest.cc | 125 |
1 files changed, 105 insertions, 20 deletions
diff --git a/base/shared_memory_unittest.cc b/base/shared_memory_unittest.cc index bdb6c86..4b1e088 100644 --- a/base/shared_memory_unittest.cc +++ b/base/shared_memory_unittest.cc @@ -3,12 +3,15 @@ // found in the LICENSE file. #include "base/basictypes.h" +#include "base/multiprocess_test.h" #include "base/platform_thread.h" #include "base/scoped_nsautorelease_pool.h" #include "base/shared_memory.h" +#include "base/scoped_ptr.h" #include "testing/gtest/include/gtest/gtest.h" static const int kNumThreads = 5; +static const int kNumTasks = 5; namespace base { @@ -158,27 +161,40 @@ TEST(SharedMemoryTest, OpenClose) { EXPECT_TRUE(rv); } -// Create a set of 5 threads to each open a shared memory segment and write to +// Create a set of N threads to each open a shared memory segment and write to // it. Verify that they are always reading/writing consistent data. TEST(SharedMemoryTest, MultipleThreads) { MultipleThreadMain::CleanUp(); - PlatformThreadHandle thread_handles[kNumThreads]; - MultipleThreadMain* thread_delegates[kNumThreads]; - - // Spawn the threads. - for (int16 index = 0; index < kNumThreads; index++) { - PlatformThreadHandle pth; - thread_delegates[index] = new MultipleThreadMain(index); - EXPECT_TRUE(PlatformThread::Create(0, thread_delegates[index], &pth)); - thread_handles[index] = pth; - } + // On POSIX we have a problem when 2 threads try to create the shmem + // (a file) at exactly the same time, since create both creates the + // file and zerofills it. We solve the problem for this unit test + // (make it not flaky) by starting with 1 thread, then + // intentionally don't clean up its shmem before running with + // kNumThreads. + + int threadcounts[] = { 1, kNumThreads }; + for (size_t i = 0; i < sizeof(threadcounts) / sizeof(threadcounts); i++) { + int numthreads = threadcounts[i]; + scoped_array<PlatformThreadHandle> thread_handles; + scoped_array<MultipleThreadMain*> thread_delegates; + + thread_handles.reset(new PlatformThreadHandle[numthreads]); + thread_delegates.reset(new MultipleThreadMain*[numthreads]); + + // Spawn the threads. + for (int16 index = 0; index < numthreads; index++) { + PlatformThreadHandle pth; + thread_delegates[index] = new MultipleThreadMain(index); + EXPECT_TRUE(PlatformThread::Create(0, thread_delegates[index], &pth)); + thread_handles[index] = pth; + } - // Wait for the threads to finish. - for (int index = 0; index < kNumThreads; index++) { - PlatformThread::Join(thread_handles[index]); - delete thread_delegates[index]; + // Wait for the threads to finish. + for (int index = 0; index < numthreads; index++) { + PlatformThread::Join(thread_handles[index]); + delete thread_delegates[index]; + } } - MultipleThreadMain::CleanUp(); } @@ -219,10 +235,10 @@ TEST(SharedMemoryTest, AnonymousPrivate) { bool rv; const int kDataSize = 8192; - SharedMemory* memories = new SharedMemory[count]; - int **pointers = new int*[count]; - ASSERT_TRUE(memories); - ASSERT_TRUE(pointers); + scoped_array<SharedMemory> memories(new SharedMemory[count]); + scoped_array<int*> pointers(new int*[count]); + ASSERT_TRUE(memories.get()); + ASSERT_TRUE(pointers.get()); for (i = 0; i < count; i++) { rv = memories[i].Create(L"", false, true, kDataSize); @@ -254,6 +270,75 @@ TEST(SharedMemoryTest, AnonymousPrivate) { for (int i = 0; i < count; i++) { memories[i].Close(); } + +} + + +// On POSIX it is especially important we test shmem across processes, +// not just across threads. But the test is enabled on all platforms. +class SharedMemoryProcessTest : public MultiProcessTest { + public: + + static void CleanUp() { + SharedMemory memory; + memory.Delete(test_name_); + } + + static int TaskTestMain() { + int errors = 0; + ScopedNSAutoreleasePool pool; // noop if not OSX + const int kDataSize = 1024; + SharedMemory memory; + bool rv = memory.Create(test_name_, false, true, kDataSize); + EXPECT_TRUE(rv); + if (rv != true) + errors++; + rv = memory.Map(kDataSize); + EXPECT_TRUE(rv); + if (rv != true) + errors++; + int *ptr = static_cast<int*>(memory.memory()); + + for (int idx = 0; idx < 20; idx++) { + memory.Lock(); + int i = (1 << 16) + idx; + *ptr = i; + PlatformThread::Sleep(10); // Short wait. + if (*ptr != i) + errors++; + memory.Unlock(); + } + + memory.Close(); + return errors; + } + + private: + static const std::wstring test_name_; +}; + +const std::wstring SharedMemoryProcessTest::test_name_ = L"MPMem"; + + +TEST_F(SharedMemoryProcessTest, Tasks) { + SharedMemoryProcessTest::CleanUp(); + + base::ProcessHandle handles[kNumTasks]; + for (int index = 0; index < kNumTasks; ++index) { + handles[index] = SpawnChild(L"SharedMemoryTestMain"); + } + + int exit_code = 0; + for (int index = 0; index < kNumTasks; ++index) { + EXPECT_TRUE(base::WaitForExitCode(handles[index], &exit_code)); + EXPECT_TRUE(exit_code == 0); + } + + SharedMemoryProcessTest::CleanUp(); +} + +MULTIPROCESS_TEST_MAIN(SharedMemoryTestMain) { + return SharedMemoryProcessTest::TaskTestMain(); } |