Added support for platforms where pthread_t is a struct rather than an integral

type.
This commit is contained in:
jgm 2012-04-02 17:41:03 +00:00
parent f0b86fc3b0
commit 9a56024c9a
2 changed files with 23 additions and 8 deletions

View File

@ -79,7 +79,8 @@ macro(config_compiler_and_linker)
# whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI # whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
# explicitly. # explicitly.
set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0") set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0")
set(cxx_strict_flags "-Wextra") set(cxx_strict_flags
"-Wextra -Wno-unused-parameter -Wno-missing-field-initializers")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
set(cxx_exception_flags "-features=except") set(cxx_exception_flags "-features=except")
# Sun Pro doesn't provide macros to indicate whether exceptions and # Sun Pro doesn't provide macros to indicate whether exceptions and

View File

@ -1240,21 +1240,23 @@ class MutexBase {
void Lock() { void Lock() {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
owner_ = pthread_self(); owner_ = pthread_self();
has_owner_ = true;
} }
// Releases this mutex. // Releases this mutex.
void Unlock() { void Unlock() {
// We don't protect writing to owner_ here, as it's the caller's // Since the lock is being released the owner_ field should no longer be
// responsibility to ensure that the current thread holds the // considered valid. We don't protect writing to has_owner_ here, as it's
// the caller's responsibility to ensure that the current thread holds the
// mutex when this is called. // mutex when this is called.
owner_ = 0; has_owner_ = false;
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_));
} }
// Does nothing if the current thread holds the mutex. Otherwise, crashes // Does nothing if the current thread holds the mutex. Otherwise, crashes
// with high probability. // with high probability.
void AssertHeld() const { void AssertHeld() const {
GTEST_CHECK_(owner_ == pthread_self()) GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self()))
<< "The current thread is not holding the mutex @" << this; << "The current thread is not holding the mutex @" << this;
} }
@ -1265,7 +1267,14 @@ class MutexBase {
// have to be public. // have to be public.
public: public:
pthread_mutex_t mutex_; // The underlying pthread mutex. pthread_mutex_t mutex_; // The underlying pthread mutex.
pthread_t owner_; // The thread holding the mutex; 0 means no one holds it. // has_owner_ indicates whether the owner_ field below contains a valid thread
// ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All
// accesses to the owner_ field should be protected by a check of this field.
// An alternative might be to memset() owner_ to all zeros, but there's no
// guarantee that a zero'd pthread_t is necessarily invalid or even different
// from pthread_self().
bool has_owner_;
pthread_t owner_; // The thread holding the mutex.
}; };
// Forward-declares a static mutex. // Forward-declares a static mutex.
@ -1273,8 +1282,13 @@ class MutexBase {
extern ::testing::internal::MutexBase mutex extern ::testing::internal::MutexBase mutex
// Defines and statically (i.e. at link time) initializes a static mutex. // Defines and statically (i.e. at link time) initializes a static mutex.
// The initialization list here does not explicitly initialize each field,
// instead relying on default initialization for the unspecified fields. In
// particular, the owner_ field (a pthread_t) is not explicitly initialized.
// This allows initialization to work whether pthread_t is a scalar or struct.
// The flag -Wmissing-field-initializers must not be specified for this to work.
# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ # define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, 0 } ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false }
// The Mutex class can only be used for mutexes created at runtime. It // The Mutex class can only be used for mutexes created at runtime. It
// shares its API with MutexBase otherwise. // shares its API with MutexBase otherwise.
@ -1282,7 +1296,7 @@ class Mutex : public MutexBase {
public: public:
Mutex() { Mutex() {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL));
owner_ = 0; has_owner_ = false;
} }
~Mutex() { ~Mutex() {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_));