Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c39331f
figure out test-thread automatically from platform
jmarantz Oct 11, 2021
d020ad7
Merge branch 'main' into auto-test-thread
jmarantz Oct 11, 2021
d7c99b1
remove refs to TestThread.
jmarantz Oct 11, 2021
28e2757
format
jmarantz Oct 11, 2021
42acfab
Separate isMainThread and isTestThread, as the distinction is interes…
jmarantz Oct 11, 2021
b66ab36
Restore coverage of isMainOrTestThread.
jmarantz Oct 12, 2021
eb21b87
Merge branch 'main' into auto-test-thread
jmarantz Oct 12, 2021
38f9e80
ratchet down coverage targets as line-count for 100%-covered thread.c…
jmarantz Oct 12, 2021
a2b8e24
Merge branch 'main' into auto-test-thread
jmarantz Oct 12, 2021
601170c
Merge branch 'main' into auto-test-thread
jmarantz Oct 14, 2021
6bad113
revert coverage tweak -- another PR made it looser.
jmarantz Oct 14, 2021
9395c0f
macro-ize the assertions.
jmarantz Oct 15, 2021
86e8cd6
release build fix
jmarantz Oct 15, 2021
4943eda
format
jmarantz Oct 15, 2021
789993a
lower coverage expectations to match observed results in a subdir not…
jmarantz Oct 16, 2021
c27d990
Merge branch 'main' into auto-test-thread
jmarantz Oct 16, 2021
b2fb078
Remove definition for isTestThread and isMainOrTestThread on platform…
jmarantz Oct 16, 2021
36ee46e
Merge branch 'main' into auto-test-thread
jmarantz Oct 16, 2021
792bf5b
macro-ize one more call to isMainOrTestThread.
jmarantz Oct 16, 2021
d3bbf50
make TRY_NEEDS_AUDIT just act as 'try' when we can't figure out the t…
jmarantz Oct 16, 2021
98651fd
clean up comments.
jmarantz Oct 17, 2021
36d9ca1
Merge branch 'main' into auto-test-thread
jmarantz Oct 22, 2021
4f42287
Add an RAII hook to allow overrides of the threading assertions.
jmarantz Oct 23, 2021
4969f31
Merge branch 'main' into auto-test-thread
jmarantz Oct 28, 2021
c07d919
Add some comments.
jmarantz Oct 28, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 10 additions & 32 deletions source/common/common/thread.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,16 @@ struct ThreadIds {
// 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;
return main_thread_id_ == id ||
// https://stackoverflow.com/questions/4867839/how-can-i-tell-if-pthread-self-is-the-main-first-thread-in-the-process
#ifdef __linux__
getpid() == syscall(SYS_gettid)
#elif defined(__APPLE__)
pthread_main_np() != 0
#else
true
#endif
;
}

bool isMainThreadActive() const {
Expand All @@ -53,20 +62,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() {
Expand All @@ -78,27 +73,14 @@ 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_;
};

Expand All @@ -108,10 +90,6 @@ bool MainThread::isMainOrTestThread() { return ThreadIds::get().inMainOrTestThre

bool MainThread::isMainThreadActive() { return ThreadIds::get().isMainThreadActive(); }

TestThread::TestThread() { ThreadIds::get().registerTestThread(); }

TestThread::~TestThread() { ThreadIds::get().releaseTestThread(); }

MainThread::MainThread() { ThreadIds::get().registerMainThread(); }

MainThread::~MainThread() { ThreadIds::get().releaseMainThread(); }
Expand Down
15 changes: 5 additions & 10 deletions source/common/common/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,17 +168,12 @@ class AtomicPtr : private AtomicPtrArray<T, 1, alloc_mode> {
T* get(const MakeObject& make_object) { return BaseClass::get(0, make_object); }
};

// RAII object to declare the TestThread. This should be declared in main() or
// equivalent for any test binaries.
// Deprecated RAII object to declare the TestThread. This is no longer needed as
// we figure this out automatically from the platform.
//
// Generally we expect TestThread to be instantiated only once on main() for
// each test binary, though nested instantiations are allowed as long as the
// thread ID does not change.
class TestThread {
public:
TestThread();
~TestThread();
};
// TODO(jmarantz): Remove this declaration after Nov 15, 2021 to allow
// references from other repositories to be cleaned up.
struct TestThread {};

// RAII object to declare the MainThread. This should be declared in the thread
// function or equivalent.
Expand Down
1 change: 0 additions & 1 deletion test/benchmark/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ int main(int argc, char** argv) {
}

TestEnvironment::initializeTestMain(argv[0]);
Thread::TestThread test_thread;

// Suppressing non-error messages in benchmark tests. This hides warning
// messages that appear when using a runtime feature when there isn't an initialized
Expand Down
2 changes: 0 additions & 2 deletions test/fuzz/fuzz_runner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ void Runner::setupEnvironment(int argc, char** argv, spdlog::level::level_enum d
// state.
ProcessWide process_wide;
TestEnvironment::initializeOptions(argc, argv);
static auto* test_thread = new Envoy::Thread::TestThread;
UNREFERENCED_PARAMETER(test_thread);

const auto environment_log_level = TestEnvironment::getOptions().logLevel();
// We only override the default log level if it looks like we're debugging;
Expand Down
2 changes: 0 additions & 2 deletions test/integration/base_integration_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -364,8 +364,6 @@ class BaseIntegrationTest : protected Logger::Loggable<Logger::Id::testing> {

std::unique_ptr<Stats::Scope> upstream_stats_store_;

Thread::TestThread test_thread_;

// Make sure the test server will be torn down after any fake client.
// The test server owns the runtime, which is often accessed by client and
// fake upstream codecs and must outlast them.
Expand Down
2 changes: 0 additions & 2 deletions test/test_runner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ class RuntimeManagingListener : public ::testing::EmptyTestEventListener {
} // namespace

int TestRunner::RunTests(int argc, char** argv) {
Thread::TestThread test_thread;

::testing::InitGoogleMock(&argc, argv);
// We hold on to process_wide to provide RAII cleanup of process-wide
// state.
Expand Down
1 change: 0 additions & 1 deletion test/tools/router_check/router_check.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include "test/tools/router_check/router.h"

int main(int argc, char* argv[]) {
Envoy::Thread::TestThread test_thread;
Envoy::Options options(argc, argv);

const bool enforce_coverage = options.failUnder() != 0.0;
Expand Down