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).
This commit is contained in:
@@ -77,7 +77,7 @@ namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Protects copying of all linked_ptr objects.
|
||||
extern Mutex g_linked_ptr_mutex;
|
||||
GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex);
|
||||
|
||||
// This is used internally by all instances of linked_ptr<>. It needs to be
|
||||
// a non-template class because different types of linked_ptr<> can refer to
|
||||
|
||||
@@ -343,10 +343,14 @@
|
||||
|
||||
#endif // GTEST_HAS_RTTI
|
||||
|
||||
// Determines whether <pthread.h> is available.
|
||||
// Determines whether Google Test can use the pthreads library.
|
||||
#ifndef GTEST_HAS_PTHREAD
|
||||
// The user didn't tell us, so we need to figure it out.
|
||||
#define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_SOLARIS)
|
||||
// The user didn't tell us explicitly, so we assume pthreads support is
|
||||
// available on Linux and Mac.
|
||||
//
|
||||
// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0
|
||||
// to your compiler flags.
|
||||
#define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC)
|
||||
#endif // GTEST_HAS_PTHREAD
|
||||
|
||||
// Determines whether Google Test can use tr1/tuple. You can define
|
||||
@@ -708,6 +712,27 @@ class GTestLog {
|
||||
inline void LogToStderr() {}
|
||||
inline void FlushInfoLog() { fflush(NULL); }
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE.
|
||||
//
|
||||
// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition
|
||||
// is not satisfied.
|
||||
// Synopsys:
|
||||
// GTEST_CHECK_(boolean_condition);
|
||||
// or
|
||||
// GTEST_CHECK_(boolean_condition) << "Additional message";
|
||||
//
|
||||
// This checks the condition and if the condition is not satisfied
|
||||
// it prints message about the condition violation, including the
|
||||
// condition itself, plus additional message streamed into it, if any,
|
||||
// and then it aborts the program. It aborts the program irrespective of
|
||||
// whether it is built in the debug mode or not.
|
||||
#define GTEST_CHECK_(condition) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (::testing::internal::IsTrue(condition)) \
|
||||
; \
|
||||
else \
|
||||
GTEST_LOG_(FATAL) << "Condition " #condition " failed. "
|
||||
|
||||
#if GTEST_HAS_STREAM_REDIRECTION_
|
||||
|
||||
// Defines the stderr capturer:
|
||||
@@ -736,6 +761,260 @@ const ::std::vector<String>& GetArgvs();
|
||||
|
||||
// Defines synchronization primitives.
|
||||
|
||||
#if GTEST_HAS_PTHREAD
|
||||
|
||||
// gtest-port.h guarantees to #include <pthread.h> when GTEST_HAS_PTHREAD is
|
||||
// true.
|
||||
#include <pthread.h>
|
||||
|
||||
// MutexBase and Mutex implement mutex on pthreads-based platforms. They
|
||||
// are used in conjunction with class MutexLock:
|
||||
//
|
||||
// Mutex mutex;
|
||||
// ...
|
||||
// MutexLock lock(&mutex); // Acquires the mutex and releases it at the end
|
||||
// // of the current scope.
|
||||
//
|
||||
// MutexBase implements behavior for both statically and dynamically
|
||||
// allocated mutexes. Do not use the MutexBase type directly. Instead,
|
||||
// define a static mutex using the GTEST_DEFINE_STATIC_MUTEX_ macro:
|
||||
//
|
||||
// GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex);
|
||||
//
|
||||
// Such mutex may also be forward-declared:
|
||||
//
|
||||
// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);
|
||||
//
|
||||
// Do not use MutexBase for dynamic mutexes either. Use the Mutex class
|
||||
// for them.
|
||||
class MutexBase {
|
||||
public:
|
||||
void Lock();
|
||||
void Unlock();
|
||||
|
||||
// Does nothing if the current thread holds the mutex. Otherwise, crashes
|
||||
// with high probability.
|
||||
void AssertHeld() const;
|
||||
|
||||
// We must be able to initialize objects of MutexBase used as static
|
||||
// mutexes with initializer lists. This means MutexBase has to be a POD.
|
||||
// The class members have to be public.
|
||||
public:
|
||||
pthread_mutex_t mutex_;
|
||||
pthread_t owner_;
|
||||
};
|
||||
|
||||
// Forward-declares a static mutex.
|
||||
#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
|
||||
extern ::testing::internal::MutexBase mutex
|
||||
|
||||
// Defines and statically initializes a static mutex.
|
||||
#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
|
||||
::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, 0 }
|
||||
|
||||
// The class Mutex supports only mutexes created at runtime. It shares its
|
||||
// API with MutexBase otherwise.
|
||||
class Mutex : public MutexBase {
|
||||
public:
|
||||
Mutex();
|
||||
~Mutex();
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex);
|
||||
};
|
||||
|
||||
// We cannot call it MutexLock directly as the ctor declaration would
|
||||
// conflict with a macro named MutexLock, which is defined on some
|
||||
// platforms. Hence the typedef trick below.
|
||||
class GTestMutexLock {
|
||||
public:
|
||||
explicit GTestMutexLock(MutexBase* mutex)
|
||||
: mutex_(mutex) { mutex_->Lock(); }
|
||||
|
||||
~GTestMutexLock() { mutex_->Unlock(); }
|
||||
|
||||
private:
|
||||
MutexBase* const mutex_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock);
|
||||
};
|
||||
|
||||
typedef GTestMutexLock MutexLock;
|
||||
|
||||
// Implements thread-local storage on pthreads-based systems.
|
||||
//
|
||||
// // Thread 1
|
||||
// ThreadLocal<int> tl(100);
|
||||
//
|
||||
// // Thread 2
|
||||
// tl.set(150);
|
||||
// EXPECT_EQ(150, tl.get());
|
||||
//
|
||||
// // Thread 1
|
||||
// EXPECT_EQ(100, tl.get()); // On Thread 1, tl.get() returns original value.
|
||||
// tl.set(200);
|
||||
// EXPECT_EQ(200, tl.get());
|
||||
//
|
||||
// The default ThreadLocal constructor requires T to have a default
|
||||
// constructor. The single param constructor requires a copy contructor
|
||||
// from T. A per-thread object managed by a ThreadLocal instance for a
|
||||
// thread is guaranteed to exist at least until the earliest of the two
|
||||
// events: (a) the thread terminates or (b) the ThreadLocal object
|
||||
// managing it is destroyed.
|
||||
template <typename T>
|
||||
class ThreadLocal {
|
||||
public:
|
||||
ThreadLocal()
|
||||
: key_(CreateKey()),
|
||||
default_(),
|
||||
instance_creator_func_(DefaultConstructNewInstance) {}
|
||||
|
||||
explicit ThreadLocal(const T& value)
|
||||
: key_(CreateKey()),
|
||||
default_(value),
|
||||
instance_creator_func_(CopyConstructNewInstance) {}
|
||||
|
||||
~ThreadLocal() {
|
||||
const int err = pthread_key_delete(key_);
|
||||
GTEST_CHECK_(err == 0) << "pthread_key_delete failed with error " << err;
|
||||
}
|
||||
|
||||
T* pointer() { return GetOrCreateValue(); }
|
||||
const T* pointer() const { return GetOrCreateValue(); }
|
||||
const T& get() const { return *pointer(); }
|
||||
void set(const T& value) { *pointer() = value; }
|
||||
|
||||
private:
|
||||
static pthread_key_t CreateKey() {
|
||||
pthread_key_t key;
|
||||
const int err = pthread_key_create(&key, &DeleteData);
|
||||
GTEST_CHECK_(err == 0) << "pthread_key_create failed with error " << err;
|
||||
return key;
|
||||
}
|
||||
|
||||
T* GetOrCreateValue() const {
|
||||
T* value = static_cast<T*>(pthread_getspecific(key_));
|
||||
if (value == NULL) {
|
||||
value = (*instance_creator_func_)(default_);
|
||||
const int err = pthread_setspecific(key_, value);
|
||||
GTEST_CHECK_(err == 0) << "pthread_setspecific failed with error " << err;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static void DeleteData(void* data) { delete static_cast<T*>(data); }
|
||||
|
||||
static T* DefaultConstructNewInstance(const T&) { return new T(); }
|
||||
|
||||
// Copy constructs new instance of T from default_. Will not be
|
||||
// instantiated unless this ThreadLocal is constructed by the single
|
||||
// parameter constructor.
|
||||
static T* CopyConstructNewInstance(const T& t) { return new T(t); }
|
||||
|
||||
// A key pthreads uses for looking up per-thread values.
|
||||
const pthread_key_t key_;
|
||||
// Contains the value that CopyConstructNewInstance copies from.
|
||||
const T default_;
|
||||
// Points to either DefaultConstructNewInstance or CopyConstructNewInstance.
|
||||
T* (*const instance_creator_func_)(const T& default_);
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
|
||||
};
|
||||
|
||||
// Allows the controller thread pause execution of newly created test
|
||||
// threads until signalled. Instances of this class must be created and
|
||||
// destroyed in the controller thread.
|
||||
//
|
||||
// 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 ThreadStartSemaphore {
|
||||
public:
|
||||
ThreadStartSemaphore();
|
||||
~ThreadStartSemaphore();
|
||||
// Signals to all test threads created with this semaphore to start. Must
|
||||
// be called from the controlling thread.
|
||||
void Signal();
|
||||
// Blocks until the controlling thread signals. Must be called from a test
|
||||
// thread.
|
||||
void Wait();
|
||||
|
||||
private:
|
||||
// We cannot use Mutex here as this class is intended for testing it.
|
||||
pthread_mutex_t mutex_;
|
||||
pthread_cond_t cond_;
|
||||
bool signalled_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadStartSemaphore);
|
||||
};
|
||||
|
||||
// Helper class for testing Google Test's multithreading constructs.
|
||||
// Use:
|
||||
//
|
||||
// void ThreadFunc(int param) { /* Do things with param */ }
|
||||
// ThreadSemaphore semaphore;
|
||||
// ...
|
||||
// // The semaphore parameter is optional; you can supply NULL.
|
||||
// ThredWithParam<int> thread(&ThreadFunc, 5, &semaphore);
|
||||
// sem.Signal(); // Allows the thread to start.
|
||||
//
|
||||
// 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.
|
||||
template <typename T>
|
||||
class ThreadWithParam {
|
||||
public:
|
||||
typedef void (*UserThreadFunc)(T);
|
||||
|
||||
ThreadWithParam(UserThreadFunc func, T param, ThreadStartSemaphore* semaphore)
|
||||
: func_(func),
|
||||
param_(param),
|
||||
start_semaphore_(semaphore),
|
||||
finished_(false) {
|
||||
// func_, param_, and start_semaphore_ must be initialized before
|
||||
// pthread_create() is called.
|
||||
const int err = pthread_create(&thread_, 0, ThreadMainStatic, this);
|
||||
GTEST_CHECK_(err == 0) << "pthread_create failed with error: "
|
||||
<< strerror(err) << "(" << err << ")";
|
||||
}
|
||||
~ThreadWithParam() { Join(); }
|
||||
|
||||
void Join() {
|
||||
if (!finished_) {
|
||||
const int err = pthread_join(thread_, 0);
|
||||
GTEST_CHECK_(err == 0) << "pthread_join failed with error:"
|
||||
<< strerror(err) << "(" << err << ")";
|
||||
finished_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void ThreadMain() {
|
||||
if (start_semaphore_ != NULL)
|
||||
start_semaphore_->Wait();
|
||||
func_(param_);
|
||||
}
|
||||
static void* ThreadMainStatic(void* param) {
|
||||
static_cast<ThreadWithParam<T>*>(param)->ThreadMain();
|
||||
return NULL; // We are not interested in thread exit code.
|
||||
}
|
||||
|
||||
// User supplied thread function.
|
||||
const UserThreadFunc func_;
|
||||
// User supplied parameter to UserThreadFunc.
|
||||
const T param_;
|
||||
|
||||
// Native thread object.
|
||||
pthread_t thread_;
|
||||
// When non-NULL, used to block execution until the controller thread
|
||||
// signals.
|
||||
ThreadStartSemaphore* const start_semaphore_;
|
||||
// true iff UserThreadFunc has not completed yet.
|
||||
bool finished_;
|
||||
};
|
||||
|
||||
#define GTEST_IS_THREADSAFE 1
|
||||
|
||||
#else // GTEST_HAS_PTHREAD
|
||||
|
||||
// A dummy implementation of synchronization primitives (mutex, lock,
|
||||
// and thread-local variable). Necessary for compiling Google Test where
|
||||
// mutex is not supported - using Google Test in multiple threads is not
|
||||
@@ -744,14 +1023,14 @@ const ::std::vector<String>& GetArgvs();
|
||||
class Mutex {
|
||||
public:
|
||||
Mutex() {}
|
||||
explicit Mutex(int /*unused*/) {}
|
||||
void AssertHeld() const {}
|
||||
enum { NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX = 0 };
|
||||
};
|
||||
|
||||
// We cannot call it MutexLock directly as the ctor declaration would
|
||||
// conflict with a macro named MutexLock, which is defined on some
|
||||
// platforms. Hence the typedef trick below.
|
||||
#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
|
||||
extern ::testing::internal::Mutex mutex
|
||||
|
||||
#define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex
|
||||
|
||||
class GTestMutexLock {
|
||||
public:
|
||||
explicit GTestMutexLock(Mutex*) {} // NOLINT
|
||||
@@ -772,14 +1051,16 @@ class ThreadLocal {
|
||||
T value_;
|
||||
};
|
||||
|
||||
// Returns the number of threads running in the process, or 0 to indicate that
|
||||
// we cannot detect it.
|
||||
size_t GetThreadCount();
|
||||
|
||||
// The above synchronization primitives have dummy implementations.
|
||||
// Therefore Google Test is not thread-safe.
|
||||
#define GTEST_IS_THREADSAFE 0
|
||||
|
||||
#endif // GTEST_HAS_PTHREAD
|
||||
|
||||
// Returns the number of threads running in the process, or 0 to indicate that
|
||||
// we cannot detect it.
|
||||
size_t GetThreadCount();
|
||||
|
||||
// Passing non-POD classes through ellipsis (...) crashes the ARM
|
||||
// compiler and generates a warning in Sun Studio. The Nokia Symbian
|
||||
// and the IBM XL C/C++ compiler try to instantiate a copy constructor
|
||||
@@ -1024,27 +1305,6 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds.
|
||||
|
||||
// Utilities for command line flags and environment variables.
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE.
|
||||
//
|
||||
// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition
|
||||
// is not satisfied.
|
||||
// Synopsys:
|
||||
// GTEST_CHECK_(boolean_condition);
|
||||
// or
|
||||
// GTEST_CHECK_(boolean_condition) << "Additional message";
|
||||
//
|
||||
// This checks the condition and if the condition is not satisfied
|
||||
// it prints message about the condition violation, including the
|
||||
// condition itself, plus additional message streamed into it, if any,
|
||||
// and then it aborts the program. It aborts the program irrespective of
|
||||
// whether it is built in the debug mode or not.
|
||||
#define GTEST_CHECK_(condition) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (::testing::internal::IsTrue(condition)) \
|
||||
; \
|
||||
else \
|
||||
GTEST_LOG_(FATAL) << "Condition " #condition " failed. "
|
||||
|
||||
// Macro for referencing flags.
|
||||
#define GTEST_FLAG(name) FLAGS_gtest_##name
|
||||
|
||||
|
||||
Reference in New Issue
Block a user