mirror of
https://github.com/google/googletest.git
synced 2024-12-29 20:23:34 +08:00
Simplifies ThreadStartSemaphore's implementation.
This commit is contained in:
parent
4f874c187b
commit
c85a77a6ab
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user