OLD | NEW |
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 <fcntl.h> | 5 #include <fcntl.h> |
6 #include <poll.h> | 6 #include <poll.h> |
7 #include <signal.h> | 7 #include <signal.h> |
8 #include <stdio.h> | 8 #include <stdio.h> |
9 #include <sys/resource.h> | 9 #include <sys/resource.h> |
10 #include <sys/time.h> | 10 #include <sys/time.h> |
(...skipping 24 matching lines...) Expand all Loading... |
35 if (task_d != 0 || task_stat.st_nlink < 3) | 35 if (task_d != 0 || task_stat.st_nlink < 3) |
36 return -1; | 36 return -1; |
37 const int num_threads = task_stat.st_nlink - 2; | 37 const int num_threads = task_stat.st_nlink - 2; |
38 return num_threads; | 38 return num_threads; |
39 } | 39 } |
40 | 40 |
41 } // namespace | 41 } // namespace |
42 | 42 |
43 namespace sandbox { | 43 namespace sandbox { |
44 | 44 |
| 45 extern bool kAllowForkWithThreads; |
| 46 |
45 bool IsAndroid() { | 47 bool IsAndroid() { |
46 #if defined(OS_ANDROID) | 48 #if defined(OS_ANDROID) |
47 return true; | 49 return true; |
48 #else | 50 #else |
49 return false; | 51 return false; |
50 #endif | 52 #endif |
51 } | 53 } |
52 | 54 |
53 bool IsArchitectureArm() { | 55 bool IsArchitectureArm() { |
54 #if defined(ARCH_CPU_ARM_FAMILY) | 56 #if defined(ARCH_CPU_ARM_FAMILY) |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 // there is a way to delay the start of the thread | 121 // there is a way to delay the start of the thread |
120 // (https://code.google.com/p/thread-sanitizer/issues/detail?id=19). | 122 // (https://code.google.com/p/thread-sanitizer/issues/detail?id=19). |
121 const int kNumExpectedThreads = 2; | 123 const int kNumExpectedThreads = 2; |
122 #endif | 124 #endif |
123 | 125 |
124 // The kernel is at liberty to wake a thread id futex before updating /proc. | 126 // The kernel is at liberty to wake a thread id futex before updating /proc. |
125 // If another test running in the same process has stopped a thread, it may | 127 // If another test running in the same process has stopped a thread, it may |
126 // appear as still running in /proc. | 128 // appear as still running in /proc. |
127 // We poll /proc, with an exponential back-off. At most, we'll sleep around | 129 // We poll /proc, with an exponential back-off. At most, we'll sleep around |
128 // 2^iterations nanoseconds in nanosleep(). | 130 // 2^iterations nanoseconds in nanosleep(). |
129 for (unsigned int iteration = 0; iteration < 30; iteration++) { | 131 if (!kAllowForkWithThreads) { |
130 struct timespec ts = {0, 1L << iteration /* nanoseconds */}; | 132 for (unsigned int iteration = 0; iteration < 30; iteration++) { |
131 PCHECK(0 == HANDLE_EINTR(nanosleep(&ts, &ts))); | 133 struct timespec ts = {0, 1L << iteration /* nanoseconds */}; |
132 num_threads = CountThreads(); | 134 PCHECK(0 == HANDLE_EINTR(nanosleep(&ts, &ts))); |
133 if (kNumExpectedThreads == num_threads) | 135 num_threads = CountThreads(); |
134 break; | 136 if (kNumExpectedThreads == num_threads) |
| 137 break; |
| 138 } |
135 } | 139 } |
136 | 140 |
137 ASSERT_EQ(kNumExpectedThreads, num_threads) | 141 const std::string multiple_threads_error = |
138 << "Running sandbox tests with multiple threads " | 142 "Running sandbox tests with multiple threads " |
139 << "is not supported and will make the tests " | 143 "is not supported and will make the tests flaky."; |
140 << "flaky.\n"; | 144 if (!kAllowForkWithThreads) { |
| 145 ASSERT_EQ(kNumExpectedThreads, num_threads) << multiple_threads_error; |
| 146 } else { |
| 147 LOG(ERROR) << multiple_threads_error; |
| 148 } |
| 149 |
141 int fds[2]; | 150 int fds[2]; |
142 ASSERT_EQ(0, pipe(fds)); | 151 ASSERT_EQ(0, pipe(fds)); |
143 // Check that our pipe is not on one of the standard file descriptor. | 152 // Check that our pipe is not on one of the standard file descriptor. |
144 SANDBOX_ASSERT(fds[0] > 2 && fds[1] > 2); | 153 SANDBOX_ASSERT(fds[0] > 2 && fds[1] > 2); |
145 | 154 |
146 pid_t pid; | 155 pid_t pid; |
147 ASSERT_LE(0, (pid = fork())); | 156 ASSERT_LE(0, (pid = fork())); |
148 if (!pid) { | 157 if (!pid) { |
149 // In child process | 158 // In child process |
150 // Redirect stderr to our pipe. This way, we can capture all error | 159 // Redirect stderr to our pipe. This way, we can capture all error |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 fflush(stderr); | 290 fflush(stderr); |
282 _exit(kExitWithAssertionFailure); | 291 _exit(kExitWithAssertionFailure); |
283 } | 292 } |
284 | 293 |
285 void UnitTests::IgnoreThisTest() { | 294 void UnitTests::IgnoreThisTest() { |
286 fflush(stderr); | 295 fflush(stderr); |
287 _exit(kIgnoreThisTest); | 296 _exit(kIgnoreThisTest); |
288 } | 297 } |
289 | 298 |
290 } // namespace | 299 } // namespace |
OLD | NEW |