Compare commits

...

6 Commits

Author SHA1 Message Date
Igor Molchanov
659ab8d6f2
Merge 2aa1e7cc67feb634cc25d6d32e2cb32f0988a886 into 1b96fa13f549387b7549cc89e1a785cf143a1a50 2025-11-14 12:17:10 +08:00
Derek Mauro
1b96fa13f5 Switch to referenceful lock holder for Abseil compatibility
PiperOrigin-RevId: 831156684
Change-Id: I8a8b017ec2fc318a65f57e04428c030c707ee682
2025-11-11 18:56:52 -08:00
makise-homura
2aa1e7cc67 Correctly deal with abi::__cxa_demangle() on LCC
abi::__cxa_demangle("7MyArrayIbLi42EE", nullptr, nullptr, nullptr)
returns "MyArray<bool, 42>" on GCC/x86_64, but "MyArray<bool, (int)42>"
on LCC/e2k. This behavior causes googletest-list-tests-unittest test to
fail.

This commit fixes that by slightly modifying the regex to match this
behavior of abi::__cxa_demangle().
2024-08-30 21:34:07 +03:00
makise-homura
24699b4926 Extend NVC workaround for no-optimize-sibling-calls
__attribute__((optimize("no-optimize-sibling-calls"))) is not supported
for at least some versions of NVC (nVidia HPC compiler), and this case
has a workaround in gtest-port.h. Actually, this is true not just for
NVC (that defines __NVCOMPILER), but for other EDG-based compilers as
well, for example, LCC.

So the correct check here would be not just for __NVCOMPILER, but
for __EDG__ (NVC defines this too, because it is based on EDG).

This commit does this.
2024-08-30 21:34:07 +03:00
makise-homura
df6fa41e1b Eliminate -Wreturn-type (at least on LCC)
There are four GetName<T>() functions that are expected to have
a limited set of possible <T> types. But compiler does not know about
that, and may complain (and in LCC case, does) about no return
operator in the end of these functions.

This commit adds dummy return to each of these functions to eliminate
this warning.
2024-08-30 21:34:07 +03:00
makise-homura
5b2ecaa64e Treat LCC as compiler different from GCC
LCC (eLbrus C/C++ compiler) is an EDG-based compiler that in most cases
is similar in behavior to GNU, but it has different warning options
supported and enabled by default. It seems to have sense to treat LCC
and GNU differently, as CMake supports it from 3.23.

For it to be done, CMake policy CMP0129 should be set to NEW,
and then CMAKE_${LANG}_COMPILER_ID may be checked to be STREQUAL "LCC".

This commit does this, and introduces warning arguments in call
to compiler that are slightly different from GNU to let googletest be
buildable without unexpected warnings.
2024-08-30 21:34:07 +03:00
14 changed files with 68 additions and 54 deletions

View File

@ -3,6 +3,7 @@
cmake_minimum_required(VERSION 3.16)
cmake_policy(SET CMP0129 NEW)
project(googletest-distribution)
set(GOOGLETEST_VERSION 1.16.0)

View File

@ -37,6 +37,7 @@ endif()
# ${gmock_BINARY_DIR}.
# Language "C" is required for find_package(Threads).
cmake_minimum_required(VERSION 3.13)
cmake_policy(SET CMP0129 NEW)
project(gmock VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
if (COMMAND set_up_hermetic_build)

View File

@ -1467,7 +1467,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
// function have been satisfied. If not, it will report Google Test
// non-fatal failures for the violations.
~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
MutexLock l(&g_gmock_mutex);
MutexLock l(g_gmock_mutex);
VerifyAndClearExpectationsLocked();
Mock::UnregisterLocked(this);
ClearDefaultActionsLocked();
@ -1646,7 +1646,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
const ArgumentTuple& args =
*static_cast<const ArgumentTuple*>(untyped_args);
MutexLock l(&g_gmock_mutex);
MutexLock l(g_gmock_mutex);
TypedExpectation<F>* exp = this->FindMatchingExpectationLocked(args);
if (exp == nullptr) { // A match wasn't found.
this->FormatUnexpectedCallMessageLocked(args, what, why);

View File

@ -156,7 +156,7 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message,
if (!LogIsVisible(severity)) return;
// Ensures that logs from different threads don't interleave.
MutexLock l(&g_log_mutex);
MutexLock l(g_log_mutex);
if (severity == kWarning) {
// Prints a GMOCK WARNING marker to make the warnings easily searchable.

View File

@ -212,7 +212,7 @@ void ExpectationBase::CheckActionCountIfNotDone() const
GTEST_LOCK_EXCLUDED_(mutex_) {
bool should_check = false;
{
MutexLock l(&mutex_);
MutexLock l(mutex_);
if (!action_count_checked_) {
action_count_checked_ = true;
should_check = true;
@ -318,7 +318,7 @@ UntypedFunctionMockerBase::~UntypedFunctionMockerBase() = default;
void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj)
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
{
MutexLock l(&g_gmock_mutex);
MutexLock l(g_gmock_mutex);
mock_obj_ = mock_obj;
}
Mock::Register(mock_obj, this);
@ -332,7 +332,7 @@ void UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj,
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
// We protect name_ under g_gmock_mutex in case this mock function
// is called from two threads concurrently.
MutexLock l(&g_gmock_mutex);
MutexLock l(g_gmock_mutex);
mock_obj_ = mock_obj;
name_ = name;
}
@ -345,7 +345,7 @@ const void* UntypedFunctionMockerBase::MockObject() const
{
// We protect mock_obj_ under g_gmock_mutex in case this mock
// function is called from two threads concurrently.
MutexLock l(&g_gmock_mutex);
MutexLock l(g_gmock_mutex);
Assert(mock_obj_ != nullptr, __FILE__, __LINE__,
"MockObject() must not be called before RegisterOwner() or "
"SetOwnerAndName() has been called.");
@ -362,7 +362,7 @@ const char* UntypedFunctionMockerBase::Name() const
{
// We protect name_ under g_gmock_mutex in case this mock
// function is called from two threads concurrently.
MutexLock l(&g_gmock_mutex);
MutexLock l(g_gmock_mutex);
Assert(name_ != nullptr, __FILE__, __LINE__,
"Name() must not be called before SetOwnerAndName() has "
"been called.");
@ -490,7 +490,7 @@ class MockObjectRegistry {
// failure, unless the user explicitly asked us to ignore it.
~MockObjectRegistry() {
if (!GMOCK_FLAG_GET(catch_leaked_mocks)) return;
internal::MutexLock l(&internal::g_gmock_mutex);
internal::MutexLock l(internal::g_gmock_mutex);
int leaked_count = 0;
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
@ -559,7 +559,7 @@ UninterestingCallReactionMap() {
void SetReactionOnUninterestingCalls(uintptr_t mock_obj,
internal::CallReaction reaction)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
internal::MutexLock l(internal::g_gmock_mutex);
UninterestingCallReactionMap()[mock_obj] = reaction;
}
@ -590,7 +590,7 @@ void Mock::FailUninterestingCalls(uintptr_t mock_obj)
// entry in the call-reaction table should be removed.
void Mock::UnregisterCallReaction(uintptr_t mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
internal::MutexLock l(internal::g_gmock_mutex);
UninterestingCallReactionMap().erase(static_cast<uintptr_t>(mock_obj));
}
@ -598,7 +598,7 @@ void Mock::UnregisterCallReaction(uintptr_t mock_obj)
// made on the given mock object.
internal::CallReaction Mock::GetReactionOnUninterestingCalls(
const void* mock_obj) GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
internal::MutexLock l(internal::g_gmock_mutex);
return (UninterestingCallReactionMap().count(
reinterpret_cast<uintptr_t>(mock_obj)) == 0)
? internal::intToCallReaction(
@ -611,7 +611,7 @@ internal::CallReaction Mock::GetReactionOnUninterestingCalls(
// objects.
void Mock::AllowLeak(const void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
internal::MutexLock l(internal::g_gmock_mutex);
g_mock_object_registry.states()[mock_obj].leakable = true;
}
@ -620,7 +620,7 @@ void Mock::AllowLeak(const void* mock_obj)
// Test non-fatal failures and returns false.
bool Mock::VerifyAndClearExpectations(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
internal::MutexLock l(internal::g_gmock_mutex);
return VerifyAndClearExpectationsLocked(mock_obj);
}
@ -629,7 +629,7 @@ bool Mock::VerifyAndClearExpectations(void* mock_obj)
// verification was successful.
bool Mock::VerifyAndClear(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
internal::MutexLock l(internal::g_gmock_mutex);
ClearDefaultActionsLocked(mock_obj);
return VerifyAndClearExpectationsLocked(mock_obj);
}
@ -679,7 +679,7 @@ bool Mock::IsStrict(void* mock_obj)
void Mock::Register(const void* mock_obj,
internal::UntypedFunctionMockerBase* mocker)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
internal::MutexLock l(internal::g_gmock_mutex);
g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
}
@ -689,7 +689,7 @@ void Mock::Register(const void* mock_obj,
void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj,
const char* file, int line)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
internal::MutexLock l(internal::g_gmock_mutex);
MockObjectState& state = g_mock_object_registry.states()[mock_obj];
if (state.first_used_file == nullptr) {
state.first_used_file = file;

View File

@ -47,6 +47,7 @@ endif()
# Project version.
cmake_minimum_required(VERSION 3.13)
cmake_policy(SET CMP0129 NEW)
project(gtest VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C)
if (COMMAND set_up_hermetic_build)

View File

@ -102,9 +102,11 @@ macro(config_compiler_and_linker)
if (CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM")
set(cxx_base_flags "${cxx_base_flags} -Wno-implicit-float-size-conversion -ffp-model=precise")
endif()
elseif (CMAKE_COMPILER_IS_GNUCXX)
set(cxx_base_flags "-Wall -Wshadow -Wundef")
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0)
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR
CMAKE_CXX_COMPILER_ID STREQUAL "LCC")
set(cxx_base_flags "-Wall -Wundef")
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND
NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0)
set(cxx_base_flags "${cxx_base_flags} -Wno-error=dangling-else")
endif()
set(cxx_exception_flags "-fexceptions")
@ -115,6 +117,11 @@ macro(config_compiler_and_linker)
set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0")
set(cxx_strict_flags
"-Wextra -Wno-unused-parameter -Wno-missing-field-initializers")
if (CMAKE_CXX_COMPILER_ID STREQUAL "LCC")
set(cxx_base_flags "${cxx_base_flags} -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unused-function")
else()
set(cxx_base_flags "${cxx_base_flags} -Wshadow")
endif()
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
set(cxx_exception_flags "-features=except")
# Sun Pro doesn't provide macros to indicate whether exceptions and

View File

@ -852,7 +852,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// Ask the compiler not to perform tail call optimization inside
// the marked function.
#define GTEST_NO_TAIL_CALL_ __attribute__((disable_tail_calls))
#elif defined(__GNUC__) && !defined(__NVCOMPILER)
#elif defined(__GNUC__) && !defined(__EDG__)
#define GTEST_NO_TAIL_CALL_ \
__attribute__((optimize("no-optimize-sibling-calls")))
#else
@ -1424,12 +1424,11 @@ class GTEST_API_ Mutex {
// "MutexLock l(&mu)". Hence the typedef trick below.
class GTestMutexLock {
public:
explicit GTestMutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->lock(); }
~GTestMutexLock() { mutex_->unlock(); }
explicit GTestMutexLock(Mutex& mutex) : mutex_(mutex) { mutex_.lock(); }
~GTestMutexLock() { mutex_.unlock(); }
private:
Mutex* const mutex_;
Mutex& mutex_;
GTestMutexLock(const GTestMutexLock&) = delete;
GTestMutexLock& operator=(const GTestMutexLock&) = delete;
@ -1716,12 +1715,11 @@ class Mutex : public MutexBase {
// "MutexLock l(&mu)". Hence the typedef trick below.
class GTestMutexLock {
public:
explicit GTestMutexLock(MutexBase* mutex) : mutex_(mutex) { mutex_->lock(); }
~GTestMutexLock() { mutex_->unlock(); }
explicit GTestMutexLock(MutexBase& mutex) : mutex_(mutex) { mutex_.lock(); }
~GTestMutexLock() { mutex_.unlock(); }
private:
MutexBase* const mutex_;
MutexBase& mutex_;
GTestMutexLock(const GTestMutexLock&) = delete;
GTestMutexLock& operator=(const GTestMutexLock&) = delete;
@ -1881,7 +1879,7 @@ class Mutex {
// "MutexLock l(&mu)". Hence the typedef trick below.
class GTestMutexLock {
public:
explicit GTestMutexLock(Mutex*) {} // NOLINT
explicit GTestMutexLock(Mutex&) {} // NOLINT
};
typedef GTestMutexLock MutexLock;

View File

@ -499,7 +499,7 @@ class ThreadLocalRegistryImpl {
MemoryIsNotDeallocated memory_is_not_deallocated;
#endif // _MSC_VER
DWORD current_thread = ::GetCurrentThreadId();
MutexLock lock(&mutex_);
MutexLock lock(mutex_);
ThreadIdToThreadLocals* const thread_to_thread_locals =
GetThreadLocalsMapLocked();
ThreadIdToThreadLocals::iterator thread_local_pos =
@ -532,7 +532,7 @@ class ThreadLocalRegistryImpl {
// Clean up the ThreadLocalValues data structure while holding the lock, but
// defer the destruction of the ThreadLocalValueHolderBases.
{
MutexLock lock(&mutex_);
MutexLock lock(mutex_);
ThreadIdToThreadLocals* const thread_to_thread_locals =
GetThreadLocalsMapLocked();
for (ThreadIdToThreadLocals::iterator it =
@ -559,7 +559,7 @@ class ThreadLocalRegistryImpl {
// Clean up the ThreadIdToThreadLocals data structure while holding the
// lock, but defer the destruction of the ThreadLocalValueHolderBases.
{
MutexLock lock(&mutex_);
MutexLock lock(mutex_);
ThreadIdToThreadLocals* const thread_to_thread_locals =
GetThreadLocalsMapLocked();
ThreadIdToThreadLocals::iterator thread_local_pos =

View File

@ -1086,14 +1086,14 @@ void DefaultPerThreadTestPartResultReporter::ReportTestPartResult(
// Returns the global test part result reporter.
TestPartResultReporterInterface*
UnitTestImpl::GetGlobalTestPartResultReporter() {
internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
internal::MutexLock lock(global_test_part_result_reporter_mutex_);
return global_test_part_result_reporter_;
}
// Sets the global test part result reporter.
void UnitTestImpl::SetGlobalTestPartResultReporter(
TestPartResultReporterInterface* reporter) {
internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
internal::MutexLock lock(global_test_part_result_reporter_mutex_);
global_test_part_result_reporter_ = reporter;
}
@ -2347,7 +2347,7 @@ void TestResult::RecordProperty(const std::string& xml_element,
if (!ValidateTestProperty(xml_element, test_property)) {
return;
}
internal::MutexLock lock(&test_properties_mutex_);
internal::MutexLock lock(test_properties_mutex_);
const std::vector<TestProperty>::iterator property_with_matching_key =
std::find_if(test_properties_.begin(), test_properties_.end(),
internal::TestPropertyKeyIs(test_property.key()));
@ -5088,7 +5088,7 @@ std::string OsStackTraceGetter::CurrentStackTrace(int max_depth, int skip_count)
void* caller_frame = nullptr;
{
MutexLock lock(&mutex_);
MutexLock lock(mutex_);
caller_frame = caller_frame_;
}
@ -5127,7 +5127,7 @@ void OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) {
caller_frame = nullptr;
}
MutexLock lock(&mutex_);
MutexLock lock(mutex_);
caller_frame_ = caller_frame;
#endif // GTEST_HAS_ABSL
}
@ -5390,13 +5390,13 @@ void UnitTest::UponLeavingGTest() {
// Sets the TestSuite object for the test that's currently running.
void UnitTest::set_current_test_suite(TestSuite* a_current_test_suite) {
internal::MutexLock lock(&mutex_);
internal::MutexLock lock(mutex_);
impl_->set_current_test_suite(a_current_test_suite);
}
// Sets the TestInfo object for the test that's currently running.
void UnitTest::set_current_test_info(TestInfo* a_current_test_info) {
internal::MutexLock lock(&mutex_);
internal::MutexLock lock(mutex_);
impl_->set_current_test_info(a_current_test_info);
}
@ -5435,7 +5435,7 @@ void UnitTest::AddTestPartResult(TestPartResult::Type result_type,
Message msg;
msg << message;
internal::MutexLock lock(&mutex_);
internal::MutexLock lock(mutex_);
if (!impl_->gtest_trace_stack().empty()) {
msg << "\n" << GTEST_NAME_ << " trace:";
@ -5618,7 +5618,7 @@ const char* UnitTest::original_working_dir() const {
// or NULL if no test is running.
const TestSuite* UnitTest::current_test_suite() const
GTEST_LOCK_EXCLUDED_(mutex_) {
internal::MutexLock lock(&mutex_);
internal::MutexLock lock(mutex_);
return impl_->current_test_suite();
}
@ -5626,7 +5626,7 @@ const TestSuite* UnitTest::current_test_suite() const
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
const TestCase* UnitTest::current_test_case() const
GTEST_LOCK_EXCLUDED_(mutex_) {
internal::MutexLock lock(&mutex_);
internal::MutexLock lock(mutex_);
return impl_->current_test_suite();
}
#endif
@ -5635,7 +5635,7 @@ const TestCase* UnitTest::current_test_case() const
// or NULL if no test is running.
const TestInfo* UnitTest::current_test_info() const
GTEST_LOCK_EXCLUDED_(mutex_) {
internal::MutexLock lock(&mutex_);
internal::MutexLock lock(mutex_);
return impl_->current_test_info();
}
@ -5659,13 +5659,13 @@ UnitTest::~UnitTest() { delete impl_; }
// Google Test trace stack.
void UnitTest::PushGTestTrace(const internal::TraceInfo& trace)
GTEST_LOCK_EXCLUDED_(mutex_) {
internal::MutexLock lock(&mutex_);
internal::MutexLock lock(mutex_);
impl_->gtest_trace_stack().push_back(trace);
}
// Pops a trace from the per-thread Google Test trace stack.
void UnitTest::PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_) {
internal::MutexLock lock(&mutex_);
internal::MutexLock lock(mutex_);
impl_->gtest_trace_stack().pop_back();
}

View File

@ -74,7 +74,7 @@ TypedTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\.
TypedTest/1\. # TypeParam = int\s*\*( __ptr64)?
TestA
TestB
TypedTest/2\. # TypeParam = .*MyArray<bool,\s*42>
TypedTest/2\. # TypeParam = .*MyArray<bool,\s*(\(int\))?42>
TestA
TestB
My/TypeParamTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\.
@ -83,7 +83,7 @@ My/TypeParamTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\.
My/TypeParamTest/1\. # TypeParam = int\s*\*( __ptr64)?
TestA
TestB
My/TypeParamTest/2\. # TypeParam = .*MyArray<bool,\s*42>
My/TypeParamTest/2\. # TypeParam = .*MyArray<bool,\s*(\(int\))?42>
TestA
TestB
MyInstantiation/ValueParamTest\.

View File

@ -720,6 +720,7 @@ class TypedTestNames {
return std::string("char") + ::testing::PrintToString(i);
if (std::is_same<T, int>::value)
return std::string("int") + ::testing::PrintToString(i);
return std::string("unknown");
}
};
@ -755,6 +756,7 @@ class TypedTestPNames {
if (std::is_same<T, unsigned int>::value) {
return std::string("unsignedInt") + ::testing::PrintToString(i);
}
return std::string("unknown");
}
};

View File

@ -308,7 +308,7 @@ TEST(GetThreadCountTest, ReturnsCorrectValue) {
internal::Mutex mutex;
{
internal::MutexLock lock(&mutex);
internal::MutexLock lock(mutex);
pthread_attr_t attr;
ASSERT_EQ(0, pthread_attr_init(&attr));
ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
@ -1028,7 +1028,9 @@ TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) {
EXPECT_DEATH_IF_SUPPORTED(
{
Mutex m;
{ MutexLock lock(&m); }
{
MutexLock lock(m);
}
m.AssertHeld();
},
"thread .*hold");
@ -1036,13 +1038,13 @@ TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) {
TEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) {
Mutex m;
MutexLock lock(&m);
MutexLock lock(m);
m.AssertHeld();
}
class AtomicCounterWithMutex {
public:
explicit AtomicCounterWithMutex(Mutex* mutex)
explicit AtomicCounterWithMutex(Mutex& mutex)
: value_(0), mutex_(mutex), random_(42) {}
void Increment() {
@ -1083,7 +1085,7 @@ class AtomicCounterWithMutex {
private:
volatile int value_;
Mutex* const mutex_; // Protects value_.
Mutex& mutex_; // Protects value_.
Random random_;
};
@ -1094,7 +1096,7 @@ void CountingThreadFunc(pair<AtomicCounterWithMutex*, int> param) {
// Tests that the mutex only lets one thread at a time to lock it.
TEST(MutexTest, OnlyOneThreadCanLockAtATime) {
Mutex mutex;
AtomicCounterWithMutex locked_counter(&mutex);
AtomicCounterWithMutex locked_counter(mutex);
typedef ThreadWithParam<pair<AtomicCounterWithMutex*, int> > ThreadType;
const int kCycleCount = 20;

View File

@ -172,6 +172,7 @@ class TypedTestNames {
if (std::is_same<T, int>::value) {
return std::string("int") + ::testing::PrintToString(i);
}
return std::string("unknown");
}
};
@ -320,6 +321,7 @@ class TypeParametrizedTestNames {
if (std::is_same<T, int>::value) {
return std::string("parInt") + ::testing::PrintToString(i);
}
return std::string("unknown");
}
};