diff --git a/source/common/common/thread.cc b/source/common/common/thread.cc index 2a5b032c6f53d..63cac85f6ca0e 100644 --- a/source/common/common/thread.cc +++ b/source/common/common/thread.cc @@ -31,6 +31,11 @@ struct ThreadIds { return main_thread_id_ == id || test_thread_id_ == id; } + bool isMainThreadActive() const { + absl::MutexLock lock(&mutex_); + return main_thread_use_count_ != 0; + } + // Returns a singleton instance of this. The instance is never freed. static ThreadIds& get() { MUTABLE_CONSTRUCT_ON_FIRST_USE(ThreadIds); } @@ -101,6 +106,8 @@ struct ThreadIds { bool MainThread::isMainOrTestThread() { return ThreadIds::get().inMainOrTestThread(); } +bool MainThread::isMainThreadActive() { return ThreadIds::get().isMainThreadActive(); } + TestThread::TestThread() { ThreadIds::get().registerTestThread(); } TestThread::~TestThread() { ThreadIds::get().releaseTestThread(); } diff --git a/source/common/common/thread.h b/source/common/common/thread.h index 45e3dc89343af..f1f415cf04d50 100644 --- a/source/common/common/thread.h +++ b/source/common/common/thread.h @@ -197,9 +197,14 @@ class MainThread { ~MainThread(); /** - * Returns whether the current thread is the main thread or test thread. + * @return whether the current thread is the main thread or test thread. */ static bool isMainOrTestThread(); + + /** + * @return whether a MainThread has been instantiated. + */ + static bool isMainThreadActive(); }; // To improve exception safety in data plane, we plan to forbid the use of raw try in the core code diff --git a/test/test_listener.cc b/test/test_listener.cc index 12dba6668f813..89c8c9251e5a2 100644 --- a/test/test_listener.cc +++ b/test/test_listener.cc @@ -14,6 +14,9 @@ void TestListener::OnTestEnd(const ::testing::TestInfo& test_info) { "]: Active singletons exist. Something is leaking. Consider " "commenting out this assert and letting the heap checker run:\n", active_singletons)); + RELEASE_ASSERT(!Thread::MainThread::isMainThreadActive(), + absl::StrCat("MainThreadLeak: [", test_info.test_suite_name(), ".", + test_info.name(), "] test exited before main thread shut down")); } } // namespace Envoy