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