-
Notifications
You must be signed in to change notification settings - Fork 5.5k
test: remove the manual declarations of TestThread and figure it out from the platform. #18557
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 11 commits
c39331f
d020ad7
d7c99b1
28e2757
42acfab
b66ab36
eb21b87
38f9e80
a2b8e24
601170c
6bad113
9395c0f
86e8cd6
4943eda
789993a
c27d990
b2fb078
36ee46e
792bf5b
d3bbf50
98651fd
36d9ca1
4f42287
4969f31
c07d919
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,15 +20,20 @@ namespace { | |
| // call-sites for isMainThread(), which might be a bit of work, but will make | ||
| // tests more hermetic. | ||
| struct ThreadIds { | ||
| // Determines whether we are currently running on the main-thread or | ||
| // test-thread. We need to allow for either one because we don't establish | ||
| // the full threading model in all unit tests. | ||
| bool inMainOrTestThread() const { | ||
| // We don't take the lock when testing the thread IDs, as they are atomic, | ||
| // and are cleared when being released. All possible thread orderings | ||
| // result in the correct result even without a lock. | ||
| std::thread::id id = std::this_thread::get_id(); | ||
| return main_thread_id_ == id || test_thread_id_ == id; | ||
| // We don't take the lock when testing the thread IDs, as they are atomic, | ||
| // and are cleared when being released. All possible thread orderings | ||
| // result in the correct result even without a lock. | ||
| bool inMainThread() const { return std::this_thread::get_id() == main_thread_id_; } | ||
|
|
||
| bool inTestThread() const { | ||
| // https://stackoverflow.com/questions/4867839/how-can-i-tell-if-pthread-self-is-the-main-first-thread-in-the-process | ||
| #ifdef __linux__ | ||
| return getpid() == syscall(SYS_gettid); | ||
| #elif defined(__APPLE__) | ||
| return pthread_main_np() != 0; | ||
| #else | ||
| return true; | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @davinci26 @wrowe is there an approach that would work in Windows?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know on top of my head, I am looking into it.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I'm understanding this change correctly, it seems like on Windows this change would mean that isMainOrTestThread() would always return true. Presumably that is ok? Would that not cause problems? Are linux and APPLE the only two non-Windows platforms we build on? If so, those would fall into the "return true" block. I wonder if it might be wise to something like: In case we end up with such a platform down the road. (Fuscia or FreeBSD or something)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I think it would cause problems if we did an
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Windows might be tricky to support due to the way the threading model works. Can you open an issue and I will pick it up at some point
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added in #18669 -- this is not a blocker for this PR though.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed, Windows benefit implicitly from this change just by having better test coverage on Linux. I want to provide parity as external filter writers might need this feature when they test their filters on windows |
||
| #endif | ||
| } | ||
|
|
||
| bool isMainThreadActive() const { | ||
|
|
@@ -53,20 +58,6 @@ struct ThreadIds { | |
| } | ||
| } | ||
|
|
||
| // Call this when the TestThread exits. Nested semantics are supported, so | ||
| // that if multiple TestThread instances are declared, we unwind them | ||
| // properly. | ||
| void releaseTestThread() { | ||
| absl::MutexLock lock(&mutex_); | ||
| ASSERT(test_thread_use_count_ > 0); | ||
| ASSERT(std::this_thread::get_id() == test_thread_id_); | ||
| if (--test_thread_use_count_ == 0) { | ||
| // Clearing the thread ID when its use-count goes to zero allows us | ||
| // to read the atomic without taking a lock. | ||
| test_thread_id_ = std::thread::id{}; | ||
| } | ||
| } | ||
|
|
||
| // Declares current thread as the main one, or verifies that the current | ||
| // thread matches any previous declarations. | ||
| void registerMainThread() { | ||
|
|
@@ -78,39 +69,24 @@ struct ThreadIds { | |
| } | ||
| } | ||
|
|
||
| // Declares current thread as the test thread, or verifies that the current | ||
| // thread matches any previous declarations. | ||
| void registerTestThread() { | ||
| absl::MutexLock lock(&mutex_); | ||
| if (++test_thread_use_count_ > 1) { | ||
| ASSERT(std::this_thread::get_id() == test_thread_id_); | ||
| } else { | ||
| test_thread_id_ = std::this_thread::get_id(); | ||
| } | ||
| } | ||
|
|
||
| private: | ||
| // The atomic thread IDs can be read without a mutex, but they are written | ||
| // under a mutex so that they are consistent with their use_counts. this | ||
| // avoids the possibility of two threads racing to claim being the main/test | ||
| // thread. | ||
| std::atomic<std::thread::id> main_thread_id_; | ||
| std::atomic<std::thread::id> test_thread_id_; | ||
|
|
||
| int32_t main_thread_use_count_ GUARDED_BY(mutex_) = 0; | ||
| int32_t test_thread_use_count_ GUARDED_BY(mutex_) = 0; | ||
| mutable absl::Mutex mutex_; | ||
| }; | ||
|
|
||
| } // namespace | ||
|
|
||
| bool MainThread::isMainOrTestThread() { return ThreadIds::get().inMainOrTestThread(); } | ||
|
|
||
| bool MainThread::isMainThreadActive() { return ThreadIds::get().isMainThreadActive(); } | ||
| bool MainThread::isMainThread() { return ThreadIds::get().inMainThread(); } | ||
|
|
||
| TestThread::TestThread() { ThreadIds::get().registerTestThread(); } | ||
| bool MainThread::isTestThread() { return ThreadIds::get().inTestThread(); } | ||
|
|
||
| TestThread::~TestThread() { ThreadIds::get().releaseTestThread(); } | ||
| bool MainThread::isMainThreadActive() { return ThreadIds::get().isMainThreadActive(); } | ||
|
|
||
| MainThread::MainThread() { ThreadIds::get().registerMainThread(); } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.