aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2010-03-04 22:15:53 +0000
committerzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2010-03-04 22:15:53 +0000
commit12a92c26fc0e0de81f687dbe739a6aa24f37f9dd (patch)
tree9a7a9aac24a5946d5bca4e04ec681ecd38b6199c /include
parent0928f00c6b995af037b787b710fde509267ad624 (diff)
downloadgoogletest-12a92c26fc0e0de81f687dbe739a6aa24f37f9dd.tar.gz
googletest-12a92c26fc0e0de81f687dbe739a6aa24f37f9dd.tar.bz2
googletest-12a92c26fc0e0de81f687dbe739a6aa24f37f9dd.zip
Renames ThreadStartSempahore to Notificaton (by Vlad Losev); adds threading tests for SCOPED_TRACE() (by Vlad Losev); replaces native pthread calls with gtest's threading constructs (by Vlad Losev); fixes flakiness in CountedDestructor (by Vlad Losev); minor MSVC 7.1 clean-up (by Zhanyong Wan).
Diffstat (limited to 'include')
-rw-r--r--include/gtest/internal/gtest-port.h183
-rw-r--r--include/gtest/internal/gtest-string.h13
2 files changed, 108 insertions, 88 deletions
diff --git a/include/gtest/internal/gtest-port.h b/include/gtest/internal/gtest-port.h
index 6910c7b7..b1b92039 100644
--- a/include/gtest/internal/gtest-port.h
+++ b/include/gtest/internal/gtest-port.h
@@ -463,13 +463,10 @@
#include <vector> // NOLINT
#endif
-// Determines whether to support value-parameterized tests.
-
-#if defined(__GNUC__) || (_MSC_VER >= 1400)
-// TODO(vladl@google.com): get the implementation rid of vector and list
-// to compile on MSVC 7.1.
+// We don't support MSVC 7.1 with exceptions disabled now. Therefore
+// all the compilers we care about are adequate for supporting
+// value-parameterized tests.
#define GTEST_HAS_PARAM_TEST 1
-#endif // defined(__GNUC__) || (_MSC_VER >= 1400)
// Determines whether to support type-driven tests.
@@ -774,6 +771,97 @@ const ::std::vector<String>& GetArgvs();
#if GTEST_HAS_PTHREAD
+// 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 notified. Instances of this class must be created
+// and destroyed in the controller thread.
+//
+// This class is only for testing Google Test's own constructs. Do not
+// use it in user tests, either directly or indirectly.
+class Notification {
+ public:
+ Notification() : notified_(false) {}
+
+ // Notifies all threads created with this notification to start. Must
+ // be called from the controller thread.
+ void Notify() { notified_ = true; }
+
+ // Blocks until the controller thread notifies. Must be called from a test
+ // thread.
+ void WaitForNotification() {
+ while(!notified_) {
+ SleepMilliseconds(10);
+ }
+ }
+
+ private:
+ volatile bool notified_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
+};
+
+// Helper class for testing Google Test's multi-threading constructs.
+// To use it, derive a class template ThreadWithParam<T> from
+// ThreadWithParamBase<T> and implement thread creation and startup in
+// the constructor and joining the thread in JoinUnderlyingThread().
+// Then you can write:
+//
+// void ThreadFunc(int param) { /* Do things with param */ }
+// Notification thread_can_start;
+// ...
+// // The thread_can_start parameter is optional; you can supply NULL.
+// ThreadWithParam<int> thread(&ThreadFunc, 5, &thread_can_start);
+// thread_can_start.Notify();
+//
+// These classes are only for testing Google Test's own constructs. Do
+// not use them in user tests, either directly or indirectly.
+template <typename T>
+class ThreadWithParamBase {
+ public:
+ typedef void (*UserThreadFunc)(T);
+
+ ThreadWithParamBase(
+ UserThreadFunc func, T param, Notification* thread_can_start)
+ : func_(func),
+ param_(param),
+ thread_can_start_(thread_can_start),
+ finished_(false) {}
+ virtual ~ThreadWithParamBase() {}
+
+ void Join() {
+ if (!finished_) {
+ JoinUnderlyingThread();
+ finished_ = true;
+ }
+ }
+
+ virtual void JoinUnderlyingThread() = 0;
+
+ void ThreadMain() {
+ if (thread_can_start_ != NULL)
+ thread_can_start_->WaitForNotification();
+ func_(param_);
+ }
+
+ protected:
+ const UserThreadFunc func_; // User-supplied thread function.
+ const T param_; // User-supplied parameter to the thread function.
+ // When non-NULL, used to block execution until the controller thread
+ // notifies.
+ Notification* const thread_can_start_;
+ bool finished_; // true iff we know that the thread function has finished.
+};
+
// gtest-port.h guarantees to #include <pthread.h> when GTEST_HAS_PTHREAD is
// true.
#include <pthread.h>
@@ -936,99 +1024,32 @@ 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 only for testing Google Test's own constructs. Do not
-// use it in user tests, either directly or indirectly.
-class ThreadStartSemaphore {
- public:
- ThreadStartSemaphore() : signalled_(false) {}
-
- // Signals to all threads created with this semaphore to start. Must
- // be called from the controller thread.
- void Signal() { signalled_ = true; }
-
- // Blocks until the controller thread signals. Must be called from a test
- // thread.
- void Wait() {
- while(!signalled_) {
- SleepMilliseconds(10);
- }
- }
-
- private:
- volatile bool signalled_;
-
- GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadStartSemaphore);
-};
-
// Helper class for testing Google Test's multi-threading constructs.
-// Use:
-//
-// void ThreadFunc(int param) { /* Do things with param */ }
-// ThreadStartSemaphore semaphore;
-// ...
-// // The semaphore parameter is optional; you can supply NULL.
-// ThreadWithParam<int> thread(&ThreadFunc, 5, &semaphore);
-// semaphore.Signal(); // Allows the thread to start.
-//
-// 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 {
+class ThreadWithParam : public ThreadWithParamBase<T> {
public:
- typedef void (*UserThreadFunc)(T);
-
- ThreadWithParam(UserThreadFunc func, T param, ThreadStartSemaphore* semaphore)
- : func_(func),
- param_(param),
- start_semaphore_(semaphore),
- finished_(false) {
+ ThreadWithParam(void (*func)(T), T param, Notification* thread_can_start)
+ : ThreadWithParamBase<T>(func, param, thread_can_start) {
// The thread can be created only after all fields except thread_
// have been initialized.
GTEST_CHECK_POSIX_SUCCESS_(
pthread_create(&thread_, 0, ThreadMainStatic, this));
}
- ~ThreadWithParam() { Join(); }
+ virtual ~ThreadWithParam() { this->Join(); }
- void Join() {
- if (!finished_) {
- GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0));
- finished_ = true;
- }
+ virtual void JoinUnderlyingThread() {
+ GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0));
}
private:
- void ThreadMain() {
- if (start_semaphore_ != NULL)
- start_semaphore_->Wait();
- func_(param_);
- }
static void* ThreadMainStatic(void* thread_with_param) {
static_cast<ThreadWithParam<T>*>(thread_with_param)->ThreadMain();
return NULL; // We are not interested in the thread exit code.
}
- const UserThreadFunc func_; // User-supplied thread function.
- const T param_; // User-supplied parameter to the thread function.
- // When non-NULL, used to block execution until the controller thread
- // signals.
- ThreadStartSemaphore* const start_semaphore_;
- bool finished_; // Has the thread function finished?
pthread_t thread_; // The native thread object.
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam);
};
#define GTEST_IS_THREADSAFE 1
diff --git a/include/gtest/internal/gtest-string.h b/include/gtest/internal/gtest-string.h
index 6f9ba052..280645e6 100644
--- a/include/gtest/internal/gtest-string.h
+++ b/include/gtest/internal/gtest-string.h
@@ -51,14 +51,13 @@ namespace internal {
// String - a UTF-8 string class.
//
-// We cannot use std::string as Microsoft's STL implementation in
-// Visual C++ 7.1 has problems when exception is disabled. There is a
-// hack to work around this, but we've seen cases where the hack fails
-// to work.
+// For historic reasons, we don't use std::string.
//
-// Also, String is different from std::string in that it can represent
-// both NULL and the empty string, while std::string cannot represent
-// NULL.
+// TODO(wan@google.com): replace this class with std::string or
+// implement it in terms of the latter.
+//
+// Note that String can represent both NULL and the empty string,
+// while std::string cannot represent NULL.
//
// NULL and the empty string are considered different. NULL is less
// than anything (including the empty string) except itself.