From 4c11f25f8c972bc5bed6d92abe2a0a3e41f499d7 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Mon, 24 Oct 2011 21:13:56 +0000 Subject: Expressed the thread-safety annotations in code, replacing the existing comment-based system (by Aaron Jacobs). --- include/gtest/gtest.h | 18 +++++++---- include/gtest/internal/gtest-linked_ptr.h | 8 ++--- include/gtest/internal/gtest-port.h | 4 +++ src/gtest-internal-inl.h | 6 +++- src/gtest.cc | 51 ++++++++++++++++--------------- 5 files changed, 51 insertions(+), 36 deletions(-) diff --git a/include/gtest/gtest.h b/include/gtest/gtest.h index 432ee2d..c196990 100644 --- a/include/gtest/gtest.h +++ b/include/gtest/gtest.h @@ -1107,11 +1107,13 @@ class GTEST_API_ UnitTest { // Returns the TestCase object for the test that's currently running, // or NULL if no test is running. - const TestCase* current_test_case() const; + const TestCase* current_test_case() const + GTEST_LOCK_EXCLUDED_(mutex_); // Returns the TestInfo object for the test that's currently running, // or NULL if no test is running. - const TestInfo* current_test_info() const; + const TestInfo* current_test_info() const + GTEST_LOCK_EXCLUDED_(mutex_); // Returns the random seed used at the start of the current test run. int random_seed() const; @@ -1121,7 +1123,8 @@ class GTEST_API_ UnitTest { // value-parameterized tests and instantiate and register them. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - internal::ParameterizedTestCaseRegistry& parameterized_test_registry(); + internal::ParameterizedTestCaseRegistry& parameterized_test_registry() + GTEST_LOCK_EXCLUDED_(mutex_); #endif // GTEST_HAS_PARAM_TEST // Gets the number of successful test cases. @@ -1194,7 +1197,8 @@ class GTEST_API_ UnitTest { const char* file_name, int line_number, const internal::String& message, - const internal::String& os_stack_trace); + const internal::String& os_stack_trace) + GTEST_LOCK_EXCLUDED_(mutex_); // Adds a TestProperty to the current TestResult object. If the result already // contains a property with the same key, the value will be updated. @@ -1227,10 +1231,12 @@ class GTEST_API_ UnitTest { // Pushes a trace defined by SCOPED_TRACE() on to the per-thread // Google Test trace stack. - void PushGTestTrace(const internal::TraceInfo& trace); + void PushGTestTrace(const internal::TraceInfo& trace) + GTEST_LOCK_EXCLUDED_(mutex_); // Pops a trace from the per-thread Google Test trace stack. - void PopGTestTrace(); + void PopGTestTrace() + GTEST_LOCK_EXCLUDED_(mutex_); // Protects mutable state in *impl_. This is mutable as some const // methods need to lock it too. diff --git a/include/gtest/internal/gtest-linked_ptr.h b/include/gtest/internal/gtest-linked_ptr.h index 57147b4..b1362cd 100644 --- a/include/gtest/internal/gtest-linked_ptr.h +++ b/include/gtest/internal/gtest-linked_ptr.h @@ -105,8 +105,8 @@ class linked_ptr_internal { // framework. // Join an existing circle. - // L < g_linked_ptr_mutex - void join(linked_ptr_internal const* ptr) { + void join(linked_ptr_internal const* ptr) + GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { MutexLock lock(&g_linked_ptr_mutex); linked_ptr_internal const* p = ptr; @@ -117,8 +117,8 @@ class linked_ptr_internal { // Leave whatever circle we're part of. Returns true if we were the // last member of the circle. Once this is done, you can join() another. - // L < g_linked_ptr_mutex - bool depart() { + bool depart() + GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { MutexLock lock(&g_linked_ptr_mutex); if (next_ == this) return true; diff --git a/include/gtest/internal/gtest-port.h b/include/gtest/internal/gtest-port.h index f3b7b62..cb870c9 100644 --- a/include/gtest/internal/gtest-port.h +++ b/include/gtest/internal/gtest-port.h @@ -1789,6 +1789,10 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. #define GTEST_DEFINE_string_(name, default_val, doc) \ GTEST_API_ ::testing::internal::String GTEST_FLAG(name) = (default_val) +// Thread annotations +#define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) +#define GTEST_LOCK_EXCLUDED_(locks) + // Parses 'str' for a 32-bit signed integer. If successful, writes the result // to *value and returns true; otherwise leaves *value unchanged and returns // false. diff --git a/src/gtest-internal-inl.h b/src/gtest-internal-inl.h index 8a85724..d869f0f 100644 --- a/src/gtest-internal-inl.h +++ b/src/gtest-internal-inl.h @@ -438,8 +438,12 @@ class OsStackTraceGetterInterface { class OsStackTraceGetter : public OsStackTraceGetterInterface { public: OsStackTraceGetter() : caller_frame_(NULL) {} - virtual String CurrentStackTrace(int max_depth, int skip_count); + + virtual String CurrentStackTrace(int max_depth, int skip_count) + GTEST_LOCK_EXCLUDED_(mutex_); + virtual void UponLeavingGTest(); + GTEST_LOCK_EXCLUDED_(mutex_); // This string is inserted in place of stack frames that are part of // Google Test's implementation. diff --git a/src/gtest.cc b/src/gtest.cc index 7bdd28a..e407ee9 100644 --- a/src/gtest.cc +++ b/src/gtest.cc @@ -3528,8 +3528,8 @@ void StreamingListener::MakeConnection() { // Pushes the given source file location and message onto a per-thread // trace stack maintained by Google Test. -// L < UnitTest::mutex_ -ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) { +ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) + GTEST_LOCK_EXCLUDED_(UnitTest::mutex_) { TraceInfo trace; trace.file = file; trace.line = line; @@ -3539,8 +3539,8 @@ ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) { } // Pops the info pushed by the c'tor. -// L < UnitTest::mutex_ -ScopedTrace::~ScopedTrace() { +ScopedTrace::~ScopedTrace() + GTEST_LOCK_EXCLUDED_(UnitTest::mutex_) { UnitTest::GetInstance()->PopGTestTrace(); } @@ -3554,14 +3554,14 @@ ScopedTrace::~ScopedTrace() { // skip_count - the number of top frames to be skipped; doesn't count // against max_depth. // -// L < mutex_ -// We use "L < mutex_" to denote that the function may acquire mutex_. -String OsStackTraceGetter::CurrentStackTrace(int, int) { +String OsStackTraceGetter::CurrentStackTrace(int /* max_depth */, + int /* skip_count */) + GTEST_LOCK_EXCLUDED_(mutex_) { return String(""); } -// L < mutex_ -void OsStackTraceGetter::UponLeavingGTest() { +void OsStackTraceGetter::UponLeavingGTest() + GTEST_LOCK_EXCLUDED_(mutex_) { } const char* const @@ -3774,12 +3774,13 @@ Environment* UnitTest::AddEnvironment(Environment* env) { // assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call // this to report their results. The user code should use the // assertion macros instead of calling this directly. -// L < mutex_ -void UnitTest::AddTestPartResult(TestPartResult::Type result_type, - const char* file_name, - int line_number, - const internal::String& message, - const internal::String& os_stack_trace) { +void UnitTest::AddTestPartResult( + TestPartResult::Type result_type, + const char* file_name, + int line_number, + const internal::String& message, + const internal::String& os_stack_trace) + GTEST_LOCK_EXCLUDED_(mutex_) { Message msg; msg << message; @@ -3912,16 +3913,16 @@ const char* UnitTest::original_working_dir() const { // Returns the TestCase object for the test that's currently running, // or NULL if no test is running. -// L < mutex_ -const TestCase* UnitTest::current_test_case() const { +const TestCase* UnitTest::current_test_case() const + GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); return impl_->current_test_case(); } // Returns the TestInfo object for the test that's currently running, // or NULL if no test is running. -// L < mutex_ -const TestInfo* UnitTest::current_test_info() const { +const TestInfo* UnitTest::current_test_info() const + GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); return impl_->current_test_info(); } @@ -3932,9 +3933,9 @@ int UnitTest::random_seed() const { return impl_->random_seed(); } #if GTEST_HAS_PARAM_TEST // Returns ParameterizedTestCaseRegistry object used to keep track of // value-parameterized tests and instantiate and register them. -// L < mutex_ internal::ParameterizedTestCaseRegistry& - UnitTest::parameterized_test_registry() { + UnitTest::parameterized_test_registry() + GTEST_LOCK_EXCLUDED_(mutex_) { return impl_->parameterized_test_registry(); } #endif // GTEST_HAS_PARAM_TEST @@ -3951,15 +3952,15 @@ UnitTest::~UnitTest() { // Pushes a trace defined by SCOPED_TRACE() on to the per-thread // Google Test trace stack. -// L < mutex_ -void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) { +void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) + GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); impl_->gtest_trace_stack().push_back(trace); } // Pops a trace from the per-thread Google Test trace stack. -// L < mutex_ -void UnitTest::PopGTestTrace() { +void UnitTest::PopGTestTrace() + GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); impl_->gtest_trace_stack().pop_back(); } -- cgit v0.12