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

Side by Side Diff: base/shared_memory_unittest.cc

Issue 19724: Properly honor base::SharedMemory semantics for name="" to mean... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « base/shared_memory_posix.cc ('k') | base/shared_memory_win.cc » ('j') | 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) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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/basictypes.h" 5 #include "base/basictypes.h"
6 #include "base/platform_thread.h" 6 #include "base/platform_thread.h"
7 #include "base/scoped_nsautorelease_pool.h"
7 #include "base/shared_memory.h" 8 #include "base/shared_memory.h"
8 #include "testing/gtest/include/gtest/gtest.h" 9 #include "testing/gtest/include/gtest/gtest.h"
9 10
10 static const int kNumThreads = 5; 11 static const int kNumThreads = 5;
11 12
12 namespace base { 13 namespace base {
13 14
14 namespace { 15 namespace {
15 16
16 // Each thread will open the shared memory. Each thread will take a different 4 17 // Each thread will open the shared memory. Each thread will take a different 4
17 // byte int pointer, and keep changing it, with some small pauses in between. 18 // byte int pointer, and keep changing it, with some small pauses in between.
18 // Verify that each thread's value in the shared memory is always correct. 19 // Verify that each thread's value in the shared memory is always correct.
19 class MultipleThreadMain : public PlatformThread::Delegate { 20 class MultipleThreadMain : public PlatformThread::Delegate {
20 public: 21 public:
21 explicit MultipleThreadMain(int16 id) : id_(id) {} 22 explicit MultipleThreadMain(int16 id) : id_(id) {}
22 ~MultipleThreadMain() {} 23 ~MultipleThreadMain() {}
23 24
25 static void CleanUp() {
26 SharedMemory memory;
27 memory.Delete(test_name_);
28 }
29
24 // PlatformThread::Delegate interface. 30 // PlatformThread::Delegate interface.
25 void ThreadMain() { 31 void ThreadMain() {
32 ScopedNSAutoreleasePool pool; // noop if not OSX
26 const int kDataSize = 1024; 33 const int kDataSize = 1024;
27 std::wstring test_name = L"SharedMemoryOpenThreadTest";
28 SharedMemory memory; 34 SharedMemory memory;
29 bool rv = memory.Create(test_name, false, true, kDataSize); 35 bool rv = memory.Create(test_name_, false, true, kDataSize);
30 EXPECT_TRUE(rv); 36 EXPECT_TRUE(rv);
31 rv = memory.Map(kDataSize); 37 rv = memory.Map(kDataSize);
32 EXPECT_TRUE(rv); 38 EXPECT_TRUE(rv);
33 int *ptr = static_cast<int*>(memory.memory()) + id_; 39 int *ptr = static_cast<int*>(memory.memory()) + id_;
34 EXPECT_EQ(*ptr, 0); 40 EXPECT_EQ(*ptr, 0);
35 41
36 for (int idx = 0; idx < 100; idx++) { 42 for (int idx = 0; idx < 100; idx++) {
37 *ptr = idx; 43 *ptr = idx;
38 PlatformThread::Sleep(1); // Short wait. 44 PlatformThread::Sleep(1); // Short wait.
39 EXPECT_EQ(*ptr, idx); 45 EXPECT_EQ(*ptr, idx);
40 } 46 }
41 47
42 memory.Close(); 48 memory.Close();
43 } 49 }
44 50
45 private: 51 private:
46 int16 id_; 52 int16 id_;
47 53
54 static const std::wstring test_name_;
55
48 DISALLOW_COPY_AND_ASSIGN(MultipleThreadMain); 56 DISALLOW_COPY_AND_ASSIGN(MultipleThreadMain);
49 }; 57 };
50 58
59 const std::wstring MultipleThreadMain::test_name_ = L"SharedMemoryOpenThreadTest ";
60
61 // TODO(port):
62 // This test requires the ability to pass file descriptors between processes.
63 // We haven't done that yet in Chrome for POSIX.
51 #if defined(OS_WIN) 64 #if defined(OS_WIN)
52 // Each thread will open the shared memory. Each thread will take the memory, 65 // Each thread will open the shared memory. Each thread will take the memory,
53 // and keep changing it while trying to lock it, with some small pauses in 66 // and keep changing it while trying to lock it, with some small pauses in
54 // between. Verify that each thread's value in the shared memory is always 67 // between. Verify that each thread's value in the shared memory is always
55 // correct. 68 // correct.
56 class MultipleLockThread : public PlatformThread::Delegate { 69 class MultipleLockThread : public PlatformThread::Delegate {
57 public: 70 public:
58 explicit MultipleLockThread(int id) : id_(id) {} 71 explicit MultipleLockThread(int id) : id_(id) {}
59 ~MultipleLockThread() {} 72 ~MultipleLockThread() {}
60 73
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 110
98 } // namespace 111 } // namespace
99 112
100 TEST(SharedMemoryTest, OpenClose) { 113 TEST(SharedMemoryTest, OpenClose) {
101 const int kDataSize = 1024; 114 const int kDataSize = 1024;
102 std::wstring test_name = L"SharedMemoryOpenCloseTest"; 115 std::wstring test_name = L"SharedMemoryOpenCloseTest";
103 116
104 // Open two handles to a memory segment, confirm that they are mapped 117 // Open two handles to a memory segment, confirm that they are mapped
105 // separately yet point to the same space. 118 // separately yet point to the same space.
106 SharedMemory memory1; 119 SharedMemory memory1;
107 bool rv = memory1.Open(test_name, false); 120 bool rv = memory1.Delete(test_name);
121 EXPECT_TRUE(rv);
122 rv = memory1.Delete(test_name);
123 EXPECT_TRUE(rv);
124 rv = memory1.Open(test_name, false);
108 EXPECT_FALSE(rv); 125 EXPECT_FALSE(rv);
109 rv = memory1.Create(test_name, false, false, kDataSize); 126 rv = memory1.Create(test_name, false, false, kDataSize);
110 EXPECT_TRUE(rv); 127 EXPECT_TRUE(rv);
111 rv = memory1.Map(kDataSize); 128 rv = memory1.Map(kDataSize);
112 EXPECT_TRUE(rv); 129 EXPECT_TRUE(rv);
113 SharedMemory memory2; 130 SharedMemory memory2;
114 rv = memory2.Open(test_name, false); 131 rv = memory2.Open(test_name, false);
115 EXPECT_TRUE(rv); 132 EXPECT_TRUE(rv);
116 rv = memory2.Map(kDataSize); 133 rv = memory2.Map(kDataSize);
117 EXPECT_TRUE(rv); 134 EXPECT_TRUE(rv);
118 EXPECT_NE(memory1.memory(), memory2.memory()); // Compare the pointers. 135 EXPECT_NE(memory1.memory(), memory2.memory()); // Compare the pointers.
119 136
120 // Make sure we don't segfault. (it actually happened!) 137 // Make sure we don't segfault. (it actually happened!)
121 ASSERT_NE(memory1.memory(), static_cast<void*>(NULL)); 138 ASSERT_NE(memory1.memory(), static_cast<void*>(NULL));
122 ASSERT_NE(memory2.memory(), static_cast<void*>(NULL)); 139 ASSERT_NE(memory2.memory(), static_cast<void*>(NULL));
123 140
124 // Write data to the first memory segment, verify contents of second. 141 // Write data to the first memory segment, verify contents of second.
125 memset(memory1.memory(), '1', kDataSize); 142 memset(memory1.memory(), '1', kDataSize);
126 EXPECT_EQ(memcmp(memory1.memory(), memory2.memory(), kDataSize), 0); 143 EXPECT_EQ(memcmp(memory1.memory(), memory2.memory(), kDataSize), 0);
127 144
128 // Close the first memory segment, and verify the second has the right data. 145 // Close the first memory segment, and verify the second has the right data.
129 memory1.Close(); 146 memory1.Close();
130 char *start_ptr = static_cast<char *>(memory2.memory()); 147 char *start_ptr = static_cast<char *>(memory2.memory());
131 char *end_ptr = start_ptr + kDataSize; 148 char *end_ptr = start_ptr + kDataSize;
132 for (char* ptr = start_ptr; ptr < end_ptr; ptr++) 149 for (char* ptr = start_ptr; ptr < end_ptr; ptr++)
133 EXPECT_EQ(*ptr, '1'); 150 EXPECT_EQ(*ptr, '1');
134 151
135 // Close the second memory segment. 152 // Close the second memory segment.
136 memory2.Close(); 153 memory2.Close();
154
155 rv = memory1.Delete(test_name);
156 EXPECT_TRUE(rv);
157 rv = memory2.Delete(test_name);
158 EXPECT_TRUE(rv);
137 } 159 }
138 160
139 #if defined(OS_WIN)
140 // Create a set of 5 threads to each open a shared memory segment and write to 161 // Create a set of 5 threads to each open a shared memory segment and write to
141 // it. Verify that they are always reading/writing consistent data. 162 // it. Verify that they are always reading/writing consistent data.
142 TEST(SharedMemoryTest, MultipleThreads) { 163 TEST(SharedMemoryTest, MultipleThreads) {
164 MultipleThreadMain::CleanUp();
143 PlatformThreadHandle thread_handles[kNumThreads]; 165 PlatformThreadHandle thread_handles[kNumThreads];
144 MultipleThreadMain* thread_delegates[kNumThreads]; 166 MultipleThreadMain* thread_delegates[kNumThreads];
145 167
146 // Spawn the threads. 168 // Spawn the threads.
147 for (int16 index = 0; index < kNumThreads; index++) { 169 for (int16 index = 0; index < kNumThreads; index++) {
148 PlatformThreadHandle pth; 170 PlatformThreadHandle pth;
149 thread_delegates[index] = new MultipleThreadMain(index); 171 thread_delegates[index] = new MultipleThreadMain(index);
150 EXPECT_TRUE(PlatformThread::Create(0, thread_delegates[index], &pth)); 172 EXPECT_TRUE(PlatformThread::Create(0, thread_delegates[index], &pth));
151 thread_handles[index] = pth; 173 thread_handles[index] = pth;
152 } 174 }
153 175
154 // Wait for the threads to finish. 176 // Wait for the threads to finish.
155 for (int index = 0; index < kNumThreads; index++) { 177 for (int index = 0; index < kNumThreads; index++) {
156 PlatformThread::Join(thread_handles[index]); 178 PlatformThread::Join(thread_handles[index]);
157 delete thread_delegates[index]; 179 delete thread_delegates[index];
158 } 180 }
181
182 MultipleThreadMain::CleanUp();
159 } 183 }
160 184
185 // TODO(port): this test requires the MultipleLockThread class
186 // (defined above), which requires the ability to pass file
187 // descriptors between processes. We haven't done that yet in Chrome
188 // for POSIX.
189 #if defined(OS_WIN)
161 // Create a set of threads to each open a shared memory segment and write to it 190 // Create a set of threads to each open a shared memory segment and write to it
162 // with the lock held. Verify that they are always reading/writing consistent 191 // with the lock held. Verify that they are always reading/writing consistent
163 // data. 192 // data.
164 TEST(SharedMemoryTest, Lock) { 193 TEST(SharedMemoryTest, Lock) {
165 PlatformThreadHandle thread_handles[kNumThreads]; 194 PlatformThreadHandle thread_handles[kNumThreads];
166 MultipleLockThread* thread_delegates[kNumThreads]; 195 MultipleLockThread* thread_delegates[kNumThreads];
167 196
168 // Spawn the threads. 197 // Spawn the threads.
169 for (int index = 0; index < kNumThreads; ++index) { 198 for (int index = 0; index < kNumThreads; ++index) {
170 PlatformThreadHandle pth; 199 PlatformThreadHandle pth;
171 thread_delegates[index] = new MultipleLockThread(index); 200 thread_delegates[index] = new MultipleLockThread(index);
172 EXPECT_TRUE(PlatformThread::Create(0, thread_delegates[index], &pth)); 201 EXPECT_TRUE(PlatformThread::Create(0, thread_delegates[index], &pth));
173 thread_handles[index] = pth; 202 thread_handles[index] = pth;
174 } 203 }
175 204
176 // Wait for the threads to finish. 205 // Wait for the threads to finish.
177 for (int index = 0; index < kNumThreads; ++index) { 206 for (int index = 0; index < kNumThreads; ++index) {
178 PlatformThread::Join(thread_handles[index]); 207 PlatformThread::Join(thread_handles[index]);
179 delete thread_delegates[index]; 208 delete thread_delegates[index];
180 } 209 }
181 } 210 }
182 #endif 211 #endif
183 212
213 // Allocate private (unique) shared memory with an empty string for a
214 // name. Make sure several of them don't point to the same thing as
215 // we might expect if the names are equal.
216 TEST(SharedMemoryTest, AnonymousPrivate) {
217 int i, j;
218 int count = 4;
219 bool rv;
220 const int kDataSize = 8192;
221
222 SharedMemory* memories = new SharedMemory[count];
223 int **pointers = new int*[count];
224 ASSERT_TRUE(memories);
225 ASSERT_TRUE(pointers);
226
227 for (i = 0; i < count; i++) {
228 rv = memories[i].Create(L"", false, true, kDataSize);
229 EXPECT_TRUE(rv);
230 rv = memories[i].Map(kDataSize);
231 EXPECT_TRUE(rv);
232 int *ptr = static_cast<int*>(memories[i].memory());
233 EXPECT_TRUE(ptr);
234 pointers[i] = ptr;
235 }
236
237 for (i = 0; i < count; i++) {
238 // zero out the first int in each except for i; for that one, make it 100.
239 for (j = 0; j < count; j++) {
240 if (i == j)
241 pointers[j][0] = 100;
242 else
243 pointers[j][0] = 0;
244 }
245 // make sure there is no bleeding of the 100 into the other pointers
246 for (j = 0; j < count; j++) {
247 if (i == j)
248 EXPECT_EQ(100, pointers[j][0]);
249 else
250 EXPECT_EQ(0, pointers[j][0]);
251 }
252 }
253
254 for (int i = 0; i < count; i++) {
255 memories[i].Close();
256 }
257 }
258
259
184 } // namespace base 260 } // namespace base
OLDNEW
« no previous file with comments | « base/shared_memory_posix.cc ('k') | base/shared_memory_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698