summaryrefslogtreecommitdiff
path: root/src/gtest-port.cc
diff options
context:
space:
mode:
authorzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2010-02-24 17:19:25 +0000
committerzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2010-02-24 17:19:25 +0000
commit050a520ddf9a34b93a3b41704fa2450d7450783f (patch)
treec91cb1205fb45e4a96889ae478afa66a0559694c /src/gtest-port.cc
parent6851df92502ee6b9b96f008ae66e676f9565fc46 (diff)
downloadgtest-050a520ddf9a34b93a3b41704fa2450d7450783f.tar.gz
gtest-050a520ddf9a34b93a3b41704fa2450d7450783f.tar.bz2
gtest-050a520ddf9a34b93a3b41704fa2450d7450783f.tar.xz
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).
git-svn-id: http://googletest.googlecode.com/svn/trunk@376 861a406c-534a-0410-8894-cb66d6ee9925
Diffstat (limited to 'src/gtest-port.cc')
-rw-r--r--src/gtest-port.cc88
1 files changed, 88 insertions, 0 deletions
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