Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
yangql
googletest
Commits
c85a77a6
Commit
c85a77a6
authored
Feb 26, 2010
by
zhanyong.wan
Browse files
Simplifies ThreadStartSemaphore's implementation.
parent
4f874c18
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
33 additions
and
64 deletions
+33
-64
include/gtest/internal/gtest-port.h
include/gtest/internal/gtest-port.h
+26
-12
src/gtest-port.cc
src/gtest-port.cc
+0
-40
test/gtest-port_test.cc
test/gtest-port_test.cc
+7
-12
No files found.
include/gtest/internal/gtest-port.h
View file @
c85a77a6
...
@@ -220,6 +220,7 @@
...
@@ -220,6 +220,7 @@
#include <regex.h> // NOLINT
#include <regex.h> // NOLINT
#include <strings.h> // NOLINT
#include <strings.h> // NOLINT
#include <sys/types.h> // NOLINT
#include <sys/types.h> // NOLINT
#include <time.h> // NOLINT
#include <unistd.h> // NOLINT
#include <unistd.h> // NOLINT
#define GTEST_USES_POSIX_RE 1
#define GTEST_USES_POSIX_RE 1
...
@@ -935,28 +936,41 @@ class ThreadLocal {
...
@@ -935,28 +936,41 @@ class ThreadLocal {
GTEST_DISALLOW_COPY_AND_ASSIGN_
(
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
// Allows a controller thread to pause execution of newly created
// threads until signalled. Instances of this class must be created
// threads until signalled. Instances of this class must be created
// and destroyed in the controller thread.
// and destroyed in the controller thread.
//
//
// This class is
supplied
only for testing Google Test's own
// This class is only for testing Google Test's own
constructs. Do not
//
constructs. Do not
use it in user tests, either directly or indirectly.
// use it in user tests, either directly or indirectly.
class
ThreadStartSemaphore
{
class
ThreadStartSemaphore
{
public:
public:
ThreadStartSemaphore
()
;
ThreadStartSemaphore
()
:
signalled_
(
false
)
{}
~
ThreadStartSemaphore
();
// Signals to all threads created with this semaphore to start. Must
// Signals to all threads created with this semaphore to start. Must
// be called from the controller thread.
// be called from the controller thread.
void
Signal
();
void
Signal
()
{
signalled_
=
true
;
}
// Blocks until the controller thread signals. Must be called from a test
// Blocks until the controller thread signals. Must be called from a test
// thread.
// thread.
void
Wait
();
void
Wait
()
{
while
(
!
signalled_
)
{
SleepMilliseconds
(
10
);
}
}
private:
private:
// We cannot use Mutex here as this class is intended for testing it.
volatile
bool
signalled_
;
pthread_mutex_t
mutex_
;
pthread_cond_t
cond_
;
bool
signalled_
;
GTEST_DISALLOW_COPY_AND_ASSIGN_
(
ThreadStartSemaphore
);
GTEST_DISALLOW_COPY_AND_ASSIGN_
(
ThreadStartSemaphore
);
};
};
...
@@ -971,8 +985,8 @@ class ThreadStartSemaphore {
...
@@ -971,8 +985,8 @@ class ThreadStartSemaphore {
// ThreadWithParam<int> thread(&ThreadFunc, 5, &semaphore);
// ThreadWithParam<int> thread(&ThreadFunc, 5, &semaphore);
// semaphore.Signal(); // Allows the thread to start.
// semaphore.Signal(); // Allows the thread to start.
//
//
// This class is
supplied
only for testing Google Test's own
// This class is only for testing Google Test's own
constructs. Do not
//
constructs. Do not
use it in user tests, either directly or indirectly.
// use it in user tests, either directly or indirectly.
template
<
typename
T
>
template
<
typename
T
>
class
ThreadWithParam
{
class
ThreadWithParam
{
public:
public:
...
...
src/gtest-port.cc
View file @
c85a77a6
...
@@ -75,46 +75,6 @@ const int kStdOutFileno = STDOUT_FILENO;
...
@@ -75,46 +75,6 @@ const int kStdOutFileno = STDOUT_FILENO;
const
int
kStdErrFileno
=
STDERR_FILENO
;
const
int
kStdErrFileno
=
STDERR_FILENO
;
#endif // _MSC_VER
#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
#if GTEST_OS_MAC
// Returns the number of threads running in the process, or 0 to indicate that
// Returns the number of threads running in the process, or 0 to indicate that
...
...
test/gtest-port_test.cc
View file @
c85a77a6
...
@@ -35,10 +35,6 @@
...
@@ -35,10 +35,6 @@
#include <stdio.h>
#include <stdio.h>
#if GTEST_HAS_PTHREAD
#include <unistd.h> // For nanosleep().
#endif // GTEST_HAS_PTHREAD
#if GTEST_OS_MAC
#if GTEST_OS_MAC
#include <time.h>
#include <time.h>
#endif // GTEST_OS_MAC
#endif // GTEST_OS_MAC
...
@@ -137,10 +133,7 @@ TEST(GetThreadCountTest, ReturnsCorrectValue) {
...
@@ -137,10 +133,7 @@ TEST(GetThreadCountTest, ReturnsCorrectValue) {
if
(
GetThreadCount
()
==
1
)
if
(
GetThreadCount
()
==
1
)
break
;
break
;
timespec
time
;
SleepMilliseconds
(
100
);
time
.
tv_sec
=
0
;
time
.
tv_nsec
=
100L
*
1000
*
1000
;
// .1 seconds.
nanosleep
(
&
time
,
NULL
);
}
}
EXPECT_EQ
(
1U
,
GetThreadCount
());
EXPECT_EQ
(
1U
,
GetThreadCount
());
pthread_mutex_destroy
(
&
mutex
);
pthread_mutex_destroy
(
&
mutex
);
...
@@ -802,7 +795,7 @@ TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) {
...
@@ -802,7 +795,7 @@ TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) {
}
}
#if GTEST_IS_THREADSAFE
#if GTEST_IS_THREADSAFE
TEST
(
Mutex
Test
DeathTest
,
AssertHeldShouldAssertWhenNotLocked
)
{
TEST
(
MutexDeathTest
,
AssertHeldShouldAssertWhenNotLocked
)
{
// AssertHeld() is flaky only in the presence of multiple threads accessing
// AssertHeld() is flaky only in the presence of multiple threads accessing
// the lock. In this case, the test is robust.
// the lock. In this case, the test is robust.
EXPECT_DEATH_IF_SUPPORTED
({
EXPECT_DEATH_IF_SUPPORTED
({
...
@@ -813,8 +806,10 @@ TEST(MutexTestDeathTest, AssertHeldShouldAssertWhenNotLocked) {
...
@@ -813,8 +806,10 @@ TEST(MutexTestDeathTest, AssertHeldShouldAssertWhenNotLocked) {
"The current thread is not holding the mutex @.+"
);
"The current thread is not holding the mutex @.+"
);
}
}
void
SleepMilliseconds
(
int
time
)
{
TEST
(
MutexTest
,
AssertHeldShouldNotAssertWhenLocked
)
{
usleep
(
static_cast
<
useconds_t
>
(
time
*
1000.0
));
Mutex
m
;
MutexLock
lock
(
&
m
);
m
.
AssertHeld
();
}
}
class
AtomicCounterWithMutex
{
class
AtomicCounterWithMutex
{
...
@@ -873,7 +868,7 @@ TEST(MutexTest, OnlyOneThreadCanLockAtATime) {
...
@@ -873,7 +868,7 @@ TEST(MutexTest, OnlyOneThreadCanLockAtATime) {
kCycleCount
),
kCycleCount
),
&
semaphore
));
&
semaphore
));
}
}
semaphore
.
Signal
();
// Start the threads.
semaphore
.
Signal
();
// Start
s
the threads.
for
(
int
i
=
0
;
i
<
kThreadCount
;
++
i
)
for
(
int
i
=
0
;
i
<
kThreadCount
;
++
i
)
counting_threads
[
i
]
->
Join
();
counting_threads
[
i
]
->
Join
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment