aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2010-02-26 05:42:53 +0000
committerzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2010-02-26 05:42:53 +0000
commitc85a77a6ab0ef05c4a9a8554bf8c5e1c8687cc75 (patch)
tree45ff15530d24e3b41939398d3afaffe98e11b3ba
parent4f874c187beb3d185f7892887c8b13f356bf1fd6 (diff)
downloadgoogletest-c85a77a6ab0ef05c4a9a8554bf8c5e1c8687cc75.tar.gz
googletest-c85a77a6ab0ef05c4a9a8554bf8c5e1c8687cc75.tar.bz2
googletest-c85a77a6ab0ef05c4a9a8554bf8c5e1c8687cc75.zip
Simplifies ThreadStartSemaphore's implementation.
-rw-r--r--include/gtest/internal/gtest-port.h38
-rw-r--r--src/gtest-port.cc40
-rw-r--r--test/gtest-port_test.cc19
3 files changed, 33 insertions, 64 deletions
diff --git a/include/gtest/internal/gtest-port.h b/include/gtest/internal/gtest-port.h
index bdf75e2f..6910c7b7 100644
--- a/include/gtest/internal/gtest-port.h
+++ b/include/gtest/internal/gtest-port.h
@@ -220,6 +220,7 @@
#include <regex.h> // NOLINT
#include <strings.h> // NOLINT
#include <sys/types.h> // NOLINT
+#include <time.h> // NOLINT
#include <unistd.h> // NOLINT
#define GTEST_USES_POSIX_RE 1
@@ -935,28 +936,41 @@ class ThreadLocal {
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
};
+// Sleeps for (roughly) n milli-seconds. This function is only for
+// testing Google Test's own constructs. Don't use it in user tests,
+// either directly or indirectly.
+inline void SleepMilliseconds(int n) {
+ const timespec time = {
+ 0, // 0 seconds.
+ n * 1000L * 1000L, // And n ms.
+ };
+ nanosleep(&time, NULL);
+}
+
// Allows a controller thread to pause execution of newly created
// threads until signalled. Instances of this class must be created
// and destroyed in the controller thread.
//
-// This class is supplied only for testing Google Test's own
-// constructs. Do not use it in user tests, either directly or indirectly.
+// This class is only for testing Google Test's own constructs. Do not
+// use it in user tests, either directly or indirectly.
class ThreadStartSemaphore {
public:
- ThreadStartSemaphore();
- ~ThreadStartSemaphore();
+ ThreadStartSemaphore() : signalled_(false) {}
+
// Signals to all threads created with this semaphore to start. Must
// be called from the controller thread.
- void Signal();
+ void Signal() { signalled_ = true; }
+
// Blocks until the controller thread signals. Must be called from a test
// thread.
- void Wait();
+ void Wait() {
+ while(!signalled_) {
+ SleepMilliseconds(10);
+ }
+ }
private:
- // We cannot use Mutex here as this class is intended for testing it.
- pthread_mutex_t mutex_;
- pthread_cond_t cond_;
- bool signalled_;
+ volatile bool signalled_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadStartSemaphore);
};
@@ -971,8 +985,8 @@ class ThreadStartSemaphore {
// ThreadWithParam<int> thread(&ThreadFunc, 5, &semaphore);
// semaphore.Signal(); // Allows the thread to start.
//
-// This class is supplied only for testing Google Test's own
-// constructs. Do not use it in user tests, either directly or indirectly.
+// This class is only for testing Google Test's own constructs. Do not
+// use it in user tests, either directly or indirectly.
template <typename T>
class ThreadWithParam {
public:
diff --git a/src/gtest-port.cc b/src/gtest-port.cc
index 1c4c1bdc..b9504f56 100644
--- a/src/gtest-port.cc
+++ b/src/gtest-port.cc
@@ -75,46 +75,6 @@ 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) {
- GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL));
- GTEST_CHECK_POSIX_SUCCESS_(pthread_cond_init(&cond_, NULL));
- 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_);
- GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_));
- GTEST_CHECK_POSIX_SUCCESS_(pthread_cond_destroy(&cond_));
-}
-
-// Signals to all test threads to start. Must be called from the
-// controlling thread.
-void ThreadStartSemaphore::Signal() {
- signalled_ = true;
- GTEST_CHECK_POSIX_SUCCESS_(pthread_cond_signal(&cond_));
- GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_));
-}
-
-// Blocks until the controlling thread signals. Should be called from a
-// test thread.
-void ThreadStartSemaphore::Wait() {
- GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
-
- while (!signalled_) {
- GTEST_CHECK_POSIX_SUCCESS_(pthread_cond_wait(&cond_, &mutex_));
- }
- GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_));
-}
-
-#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/test/gtest-port_test.cc b/test/gtest-port_test.cc
index f7f26215..357a99ed 100644
--- a/test/gtest-port_test.cc
+++ b/test/gtest-port_test.cc
@@ -35,10 +35,6 @@
#include <stdio.h>
-#if GTEST_HAS_PTHREAD
-#include <unistd.h> // For nanosleep().
-#endif // GTEST_HAS_PTHREAD
-
#if GTEST_OS_MAC
#include <time.h>
#endif // GTEST_OS_MAC
@@ -137,10 +133,7 @@ TEST(GetThreadCountTest, ReturnsCorrectValue) {
if (GetThreadCount() == 1)
break;
- timespec time;
- time.tv_sec = 0;
- time.tv_nsec = 100L * 1000 * 1000; // .1 seconds.
- nanosleep(&time, NULL);
+ SleepMilliseconds(100);
}
EXPECT_EQ(1U, GetThreadCount());
pthread_mutex_destroy(&mutex);
@@ -802,7 +795,7 @@ TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) {
}
#if GTEST_IS_THREADSAFE
-TEST(MutexTestDeathTest, AssertHeldShouldAssertWhenNotLocked) {
+TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) {
// AssertHeld() is flaky only in the presence of multiple threads accessing
// the lock. In this case, the test is robust.
EXPECT_DEATH_IF_SUPPORTED({
@@ -813,8 +806,10 @@ TEST(MutexTestDeathTest, AssertHeldShouldAssertWhenNotLocked) {
"The current thread is not holding the mutex @.+");
}
-void SleepMilliseconds(int time) {
- usleep(static_cast<useconds_t>(time * 1000.0));
+TEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) {
+ Mutex m;
+ MutexLock lock(&m);
+ m.AssertHeld();
}
class AtomicCounterWithMutex {
@@ -873,7 +868,7 @@ TEST(MutexTest, OnlyOneThreadCanLockAtATime) {
kCycleCount),
&semaphore));
}
- semaphore.Signal(); // Start the threads.
+ semaphore.Signal(); // Starts the threads.
for (int i = 0; i < kThreadCount; ++i)
counting_threads[i]->Join();