Index: base/threading/worker_pool_posix_unittest.cc |
diff --git a/base/threading/worker_pool_posix_unittest.cc b/base/threading/worker_pool_posix_unittest.cc |
index 1b700e1d75198bd66dfcd55d58050b0291b0875a..4bb0650702d04f406a50ff3ab042565d598c5940 100644 |
--- a/base/threading/worker_pool_posix_unittest.cc |
+++ b/base/threading/worker_pool_posix_unittest.cc |
@@ -231,7 +231,22 @@ TEST_F(PosixDynamicThreadPoolTest, Complex) { |
pool_->PostTask(FROM_HERE, CreateNewIncrementingTaskCallback()); |
WaitForIdleThreads(1); |
- EXPECT_EQ(3U, unique_threads_.size()); |
+ // The POSIX implementation of PlatformThread::CurrentId() uses pthread_self() |
+ // which is not guaranteed to be unique after a thread joins. The OS X |
+ // implemntation of pthread_self() returns the address of the pthread_t, which |
+ // is merely a malloc()ed pointer stored in the first TLS slot. When a thread |
+ // joins and that structure is freed, the block of memory can be put on the |
+ // OS free list, meaning the same address could be reused in a subsequent |
+ // allocation. This in fact happens when allocating in a loop as this test |
+ // does. |
+ // |
+ // Because there are two concurrent threads, there's at least the guarantee |
+ // of having two unique thread IDs in the set. But after those two threads are |
+ // joined, the next-created thread can get a re-used ID if the allocation of |
+ // the pthread_t structure is taken from the free list. Therefore, there can |
+ // be either 2 or 3 unique thread IDs in the set at this stage in the test. |
+ EXPECT_TRUE(unique_threads_.size() >= 2 && unique_threads_.size() <= 3) |
+ << "unique_threads_.size() = " << unique_threads_.size(); |
EXPECT_EQ(1, peer_.num_idle_threads()); |
EXPECT_EQ(4, counter_); |
} |