diff options
author | zhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925> | 2010-02-24 17:19:25 +0000 |
---|---|---|
committer | zhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925> | 2010-02-24 17:19:25 +0000 |
commit | 3bef459eac9aa84c579f34249aebc9ff56832054 (patch) | |
tree | c91cb1205fb45e4a96889ae478afa66a0559694c /src | |
parent | dd280cfa8dff2247f71a1177d7c8f0c2fde9789a (diff) | |
download | googletest-3bef459eac9aa84c579f34249aebc9ff56832054.tar.gz googletest-3bef459eac9aa84c579f34249aebc9ff56832054.tar.bz2 googletest-3bef459eac9aa84c579f34249aebc9ff56832054.zip |
Adds threading support (by Miklos Fazekas, Vlad Losev, and Chandler Carruth); adds wide InitGoogleTest to gtest.def (by Vlad Losev); updates the version number (by Zhanyong Wan); updates the release notes for 1.5.0 (by Vlad Losev); removes scons scripts from the distribution (by Zhanyong Wan); adds the cmake build script to the distribution (by Zhanyong Wan); adds fused source files to the distribution (by Vlad Losev and Chandler Carruth).
Diffstat (limited to 'src')
-rw-r--r-- | src/gtest-internal-inl.h | 5 | ||||
-rw-r--r-- | src/gtest-port.cc | 88 | ||||
-rw-r--r-- | src/gtest.cc | 2 |
3 files changed, 93 insertions, 2 deletions
diff --git a/src/gtest-internal-inl.h b/src/gtest-internal-inl.h index 596dc553..4142e7a7 100644 --- a/src/gtest-internal-inl.h +++ b/src/gtest-internal-inl.h @@ -60,7 +60,7 @@ #include <windows.h> // For DWORD. #endif // GTEST_OS_WINDOWS -#include <gtest/gtest.h> +#include <gtest/gtest.h> // NOLINT #include <gtest/gtest-spi.h> namespace testing { @@ -1228,6 +1228,9 @@ bool ParseNaturalNumber(const ::std::string& str, Integer* number) { // TestResult contains some private methods that should be hidden from // Google Test user but are required for testing. This class allow our tests // to access them. +// +// This class is supplied only for the purpose of testing Google Test's own +// constructs. Do not use it in user tests, either directly or indirectly. class TestResultAccessor { public: static void RecordProperty(TestResult* test_result, diff --git a/src/gtest-port.cc b/src/gtest-port.cc index b9504f56..5994fd54 100644 --- a/src/gtest-port.cc +++ b/src/gtest-port.cc @@ -75,6 +75,94 @@ const int kStdOutFileno = STDOUT_FILENO; const int kStdErrFileno = STDERR_FILENO; #endif // _MSC_VER +#if GTEST_HAS_PTHREAD + +// ThreadStartSemaphore allows the controller thread to pause execution of +// newly created test threads until signalled. Instances of this class must +// be created and destroyed in the controller thread. +ThreadStartSemaphore::ThreadStartSemaphore() : signalled_(false) { + int err = pthread_mutex_init(&mutex_, NULL); + GTEST_CHECK_(err == 0) << "pthread_mutex_init failed with error " << err; + err = pthread_cond_init(&cond_, NULL); + GTEST_CHECK_(err == 0) << "pthread_cond_init failed with error " << err; + pthread_mutex_lock(&mutex_); +} + +ThreadStartSemaphore::~ThreadStartSemaphore() { + // Every ThreadStartSemaphore object must be signalled. It locks + // internal mutex upon creation and Signal unlocks it. + GTEST_CHECK_(signalled_); + + int err = pthread_mutex_destroy(&mutex_); + GTEST_CHECK_(err == 0) + << "pthread_mutex_destroy failed with error " << err; + err = pthread_cond_destroy(&cond_); + GTEST_CHECK_(err == 0) + << "pthread_cond_destroy failed with error " << err; +} + +// Signals to all test threads to start. Must be called from the +// controlling thread. +void ThreadStartSemaphore::Signal() { + signalled_ = true; + int err = pthread_cond_signal(&cond_); + GTEST_CHECK_(err == 0) + << "pthread_cond_signal failed with error " << err; + err = pthread_mutex_unlock(&mutex_); + GTEST_CHECK_(err == 0) + << "pthread_mutex_unlock failed with error " << err; +} + +// Blocks until the controlling thread signals. Should be called from a +// test thread. +void ThreadStartSemaphore::Wait() { + int err = pthread_mutex_lock(&mutex_); + GTEST_CHECK_(err == 0) << "pthread_mutex_lock failed with error " << err; + + while (!signalled_) { + err = pthread_cond_wait(&cond_, &mutex_); + GTEST_CHECK_(err == 0) + << "pthread_cond_wait failed with error " << err; + } + err = pthread_mutex_unlock(&mutex_); + GTEST_CHECK_(err == 0) + << "pthread_mutex_unlock failed with error " << err; +} + +void MutexBase::Lock() { + const int err = pthread_mutex_lock(&mutex_); + GTEST_CHECK_(err == 0) << "pthread_mutex_lock failed with error " << err; + owner_ = pthread_self(); +} + +void MutexBase::Unlock() { + // We don't protect writing to owner_ here, as it's the caller's + // responsibility to ensure that the current thread holds the mutex when + // this is called. + owner_ = 0; + const int err = pthread_mutex_unlock(&mutex_); + GTEST_CHECK_(err == 0) << "pthread_mutex_unlock failed with error " << err; +} + +// Does nothing if the current thread holds the mutex. Otherwise, crashes +// with high probability. +void MutexBase::AssertHeld() const { + GTEST_CHECK_(owner_ == pthread_self()) + << "Current thread is not holding mutex." << this; +} + +Mutex::Mutex() { + owner_ = 0; + const int err = pthread_mutex_init(&mutex_, NULL); + GTEST_CHECK_(err == 0) << "pthread_mutex_init failed with error " << err; +} + +Mutex::~Mutex() { + const int err = pthread_mutex_destroy(&mutex_); + GTEST_CHECK_(err == 0) << "pthread_mutex_destroy failed with error " << err; +} +#endif // GTEST_HAS_PTHREAD + #if GTEST_OS_MAC // Returns the number of threads running in the process, or 0 to indicate that diff --git a/src/gtest.cc b/src/gtest.cc index fb5bae94..3306f3fa 100644 --- a/src/gtest.cc +++ b/src/gtest.cc @@ -342,7 +342,7 @@ void AssertHelper::operator=(const Message& message) const { } // Mutex for linked pointers. -Mutex g_linked_ptr_mutex(Mutex::NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX); +GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); // Application pathname gotten in InitGoogleTest. String g_executable_path; |