summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2010-02-24 17:19:25 (GMT)
committerzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2010-02-24 17:19:25 (GMT)
commit3bef459eac9aa84c579f34249aebc9ff56832054 (patch)
treec91cb1205fb45e4a96889ae478afa66a0559694c /src
parentdd280cfa8dff2247f71a1177d7c8f0c2fde9789a (diff)
downloadgoogletest-3bef459eac9aa84c579f34249aebc9ff56832054.zip
googletest-3bef459eac9aa84c579f34249aebc9ff56832054.tar.gz
googletest-3bef459eac9aa84c579f34249aebc9ff56832054.tar.bz2
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.h5
-rw-r--r--src/gtest-port.cc88
-rw-r--r--src/gtest.cc2
3 files changed, 93 insertions, 2 deletions
diff --git a/src/gtest-internal-inl.h b/src/gtest-internal-inl.h
index 596dc55..4142e7a 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 b9504f5..5994fd5 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 fb5bae9..3306f3f 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;