Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
googletest
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
googletest
Commits
4879aac7
Commit
4879aac7
authored
Feb 25, 2010
by
zhanyong.wan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Simplifies the threading implementation and improves some comments.
parent
0d27868d
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
110 additions
and
170 deletions
+110
-170
gtest-port.h
include/gtest/internal/gtest-port.h
+96
-90
gtest-port.cc
src/gtest-port.cc
+9
-57
gtest-port_test.cc
test/gtest-port_test.cc
+5
-23
No files found.
include/gtest/internal/gtest-port.h
View file @
4879aac7
...
@@ -733,6 +733,16 @@ inline void FlushInfoLog() { fflush(NULL); }
...
@@ -733,6 +733,16 @@ inline void FlushInfoLog() { fflush(NULL); }
else \
else \
GTEST_LOG_(FATAL) << "Condition " #condition " failed. "
GTEST_LOG_(FATAL) << "Condition " #condition " failed. "
// An all-mode assert to verify that the given POSIX-style function
// call returns 0 (indicating success). Known limitation: this
// doesn't expand to a balanced 'if' statement, so enclose the macro
// in {} if you need to use it as the only statement in an 'if'
// branch.
#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \
if (const int gtest_error = (posix_call)) \
GTEST_LOG_(FATAL) << #posix_call << "failed with error " \
<< gtest_error
#if GTEST_HAS_STREAM_REDIRECTION_
#if GTEST_HAS_STREAM_REDIRECTION_
// Defines the stderr capturer:
// Defines the stderr capturer:
...
@@ -776,54 +786,75 @@ const ::std::vector<String>& GetArgvs();
...
@@ -776,54 +786,75 @@ const ::std::vector<String>& GetArgvs();
// // of the current scope.
// // of the current scope.
//
//
// MutexBase implements behavior for both statically and dynamically
// MutexBase implements behavior for both statically and dynamically
// allocated mutexes. Do not use
the MutexBase type directly. Instead,
// allocated mutexes. Do not use
MutexBase directly. Instead, write
//
define a static mutex using the GTEST_DEFINE_STATIC_MUTEX_ macro
:
//
the following to define a static mutex
:
//
//
// GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex);
// GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex);
//
//
//
Such mutex may also be forward-declared
:
//
You can forward declare a static mutex like this
:
//
//
// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);
// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);
//
//
// Do not use MutexBase for dynamic mutexes either. Use the Mutex class
// To create a dynamic mutex, just define an object of type Mutex.
// for them.
class
MutexBase
{
class
MutexBase
{
public
:
public
:
void
Lock
();
// Acquires this mutex.
void
Unlock
();
void
Lock
()
{
GTEST_CHECK_POSIX_SUCCESS_
(
pthread_mutex_lock
(
&
mutex_
));
owner_
=
pthread_self
();
}
// Releases this mutex.
void
Unlock
()
{
// We don't protect writing to owner_ here, as it's the caller's
// responsibility to ensure that the current thread holds the
// mutex when this is called.
owner_
=
0
;
GTEST_CHECK_POSIX_SUCCESS_
(
pthread_mutex_unlock
(
&
mutex_
));
}
// Does nothing if the current thread holds the mutex. Otherwise, crashes
// Does nothing if the current thread holds the mutex. Otherwise, crashes
// with high probability.
// with high probability.
void
AssertHeld
()
const
;
void
AssertHeld
()
const
{
GTEST_CHECK_
(
owner_
==
pthread_self
())
<<
"The current thread is not holding the mutex @"
<<
this
;
}
// We must be able to initialize objects of MutexBase used as static
// A static mutex may be used before main() is entered. It may even
// mutexes with initializer lists. This means MutexBase has to be a POD.
// be used before the dynamic initialization stage. Therefore we
// The class members have to be public.
// must be able to initialize a static mutex object at link time.
// This means MutexBase has to be a POD and its member variables
// have to be public.
public
:
public
:
pthread_mutex_t
mutex_
;
pthread_mutex_t
mutex_
;
// The underlying pthread mutex.
pthread_t
owner_
;
pthread_t
owner_
;
// The thread holding the mutex; 0 means no one holds it.
};
};
// Forward-declares a static mutex.
// Forward-declares a static mutex.
#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
extern ::testing::internal::MutexBase mutex
extern ::testing::internal::MutexBase mutex
// Defines and statically initializes a static mutex.
// Defines and statically
(i.e. at link time)
initializes a static mutex.
#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, 0 }
::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, 0 }
// The
class Mutex supports only mutexes created at runtime. It shares its
// The
Mutex class can only be used for mutexes created at runtime. It
// API with MutexBase otherwise.
//
shares its
API with MutexBase otherwise.
class
Mutex
:
public
MutexBase
{
class
Mutex
:
public
MutexBase
{
public
:
public
:
Mutex
();
Mutex
()
{
~
Mutex
();
GTEST_CHECK_POSIX_SUCCESS_
(
pthread_mutex_init
(
&
mutex_
,
NULL
));
owner_
=
0
;
}
~
Mutex
()
{
GTEST_CHECK_POSIX_SUCCESS_
(
pthread_mutex_destroy
(
&
mutex_
));
}
private
:
private
:
GTEST_DISALLOW_COPY_AND_ASSIGN_
(
Mutex
);
GTEST_DISALLOW_COPY_AND_ASSIGN_
(
Mutex
);
};
};
// We cannot
call it MutexLock directly
as the ctor declaration would
// We cannot
name this class MutexLock
as the ctor declaration would
// conflict with a macro named MutexLock, which is defined on some
// conflict with a macro named MutexLock, which is defined on some
// platforms. Hence the typedef trick below.
// platforms. Hence the typedef trick below.
class
GTestMutexLock
{
class
GTestMutexLock
{
...
@@ -844,39 +875,33 @@ typedef GTestMutexLock MutexLock;
...
@@ -844,39 +875,33 @@ typedef GTestMutexLock MutexLock;
// Implements thread-local storage on pthreads-based systems.
// Implements thread-local storage on pthreads-based systems.
//
//
// // Thread 1
// // Thread 1
//
ThreadLocal<int> tl(100);
//
ThreadLocal<int> tl(100); // 100 is the default value for each thread.
//
//
// // Thread 2
// // Thread 2
//
tl.set(150);
//
tl.set(150); // Changes the value for thread 2 only.
// EXPECT_EQ(150, tl.get());
// EXPECT_EQ(150, tl.get());
//
//
// // Thread 1
// // Thread 1
//
EXPECT_EQ(100, tl.get()); // On Thread 1, tl.get() returns
original value.
//
EXPECT_EQ(100, tl.get()); // In thread 1, tl has the
original value.
// tl.set(200);
// tl.set(200);
// EXPECT_EQ(200, tl.get());
// EXPECT_EQ(200, tl.get());
//
//
// The
default ThreadLocal constructor requires T to have a default
// The
template type argument T must have a public copy constructor.
//
constructor. The single param constructor requires a copy contructor
//
In addition, the default ThreadLocal constructor requires T to have
//
from T. A per-thread object managed by a ThreadLocal instance for a
//
a public default constructor. An object managed by a ThreadLocal
//
thread is guaranteed to exist at least until the earliest of the two
//
instance for a thread is guaranteed to exist at least until the
// e
vents: (a) the thread terminates or (b) the ThreadLocal object
// e
arliest of the two events: (a) the thread terminates or (b) the
//
managing i
t is destroyed.
//
ThreadLocal objec
t is destroyed.
template
<
typename
T
>
template
<
typename
T
>
class
ThreadLocal
{
class
ThreadLocal
{
public
:
public
:
ThreadLocal
()
ThreadLocal
()
:
key_
(
CreateKey
()),
:
key_
(
CreateKey
()),
default_
()
{}
default_
(),
explicit
ThreadLocal
(
const
T
&
value
)
:
key_
(
CreateKey
()),
instance_creator_func_
(
DefaultConstructNewInstance
)
{}
default_
(
value
)
{}
explicit
ThreadLocal
(
const
T
&
value
)
:
key_
(
CreateKey
()),
default_
(
value
),
instance_creator_func_
(
CopyConstructNewInstance
)
{}
~
ThreadLocal
()
{
~
ThreadLocal
()
{
const
int
err
=
pthread_key_delete
(
key_
);
GTEST_CHECK_POSIX_SUCCESS_
(
pthread_key_delete
(
key_
));
GTEST_CHECK_
(
err
==
0
)
<<
"pthread_key_delete failed with error "
<<
err
;
}
}
T
*
pointer
()
{
return
GetOrCreateValue
();
}
T
*
pointer
()
{
return
GetOrCreateValue
();
}
...
@@ -887,54 +912,43 @@ class ThreadLocal {
...
@@ -887,54 +912,43 @@ class ThreadLocal {
private
:
private
:
static
pthread_key_t
CreateKey
()
{
static
pthread_key_t
CreateKey
()
{
pthread_key_t
key
;
pthread_key_t
key
;
const
int
err
=
pthread_key_create
(
&
key
,
&
DeleteData
);
GTEST_CHECK_POSIX_SUCCESS_
(
pthread_key_create
(
&
key
,
&
DeleteData
));
GTEST_CHECK_
(
err
==
0
)
<<
"pthread_key_create failed with error "
<<
err
;
return
key
;
return
key
;
}
}
T
*
GetOrCreateValue
()
const
{
T
*
GetOrCreateValue
()
const
{
T
*
value
=
static_cast
<
T
*>
(
pthread_getspecific
(
key_
));
T
*
const
value
=
static_cast
<
T
*>
(
pthread_getspecific
(
key_
));
if
(
value
==
NULL
)
{
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
;
return
value
;
T
*
const
new_value
=
new
T
(
default_
);
GTEST_CHECK_POSIX_SUCCESS_
(
pthread_setspecific
(
key_
,
new_value
));
return
new_value
;
}
}
static
void
DeleteData
(
void
*
data
)
{
delete
static_cast
<
T
*>
(
data
);
}
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.
// A key pthreads uses for looking up per-thread values.
const
pthread_key_t
key_
;
const
pthread_key_t
key_
;
// Contains the value that CopyConstructNewInstance copies from.
const
T
default_
;
// The default value for each thread.
const
T
default_
;
// Points to either DefaultConstructNewInstance or CopyConstructNewInstance.
T
*
(
*
const
instance_creator_func_
)(
const
T
&
default_
);
GTEST_DISALLOW_COPY_AND_ASSIGN_
(
ThreadLocal
);
GTEST_DISALLOW_COPY_AND_ASSIGN_
(
ThreadLocal
);
};
};
// Allows
the controller thread pause execution of newly created test
// Allows
a controller thread to pause execution of newly created
// threads until signalled.
Instances of this class must be created an
d
// threads until signalled.
Instances of this class must be create
d
// destroyed in the controller thread.
//
and
destroyed in the controller thread.
//
//
// This class is supplied only for t
he purpose of t
esting Google Test's own
// This class is supplied only for testing Google Test's own
// constructs. Do not use it in user tests, either directly or indirectly.
// constructs. Do not use it in user tests, either directly or indirectly.
class
ThreadStartSemaphore
{
class
ThreadStartSemaphore
{
public
:
public
:
ThreadStartSemaphore
();
ThreadStartSemaphore
();
~
ThreadStartSemaphore
();
~
ThreadStartSemaphore
();
// Signals to all t
est t
hreads created with this semaphore to start. Must
// Signals to all threads created with this semaphore to start. Must
// be called from the controll
ing
thread.
// be called from the controll
er
thread.
void
Signal
();
void
Signal
();
// Blocks until the controll
ing
thread signals. Must be called from a test
// Blocks until the controll
er
thread signals. Must be called from a test
// thread.
// thread.
void
Wait
();
void
Wait
();
...
@@ -947,17 +961,17 @@ class ThreadStartSemaphore {
...
@@ -947,17 +961,17 @@ class ThreadStartSemaphore {
GTEST_DISALLOW_COPY_AND_ASSIGN_
(
ThreadStartSemaphore
);
GTEST_DISALLOW_COPY_AND_ASSIGN_
(
ThreadStartSemaphore
);
};
};
// Helper class for testing Google Test's multithreading constructs.
// Helper class for testing Google Test's multi
-
threading constructs.
// Use:
// Use:
//
//
// void ThreadFunc(int param) { /* Do things with param */ }
// void ThreadFunc(int param) { /* Do things with param */ }
//
Thread
Semaphore semaphore;
//
ThreadStart
Semaphore semaphore;
// ...
// ...
// // The semaphore parameter is optional; you can supply NULL.
// // The semaphore parameter is optional; you can supply NULL.
//
Thre
dWithParam<int> thread(&ThreadFunc, 5, &semaphore);
//
Threa
dWithParam<int> thread(&ThreadFunc, 5, &semaphore);
//
sem.Signal();
// Allows the thread to start.
//
semaphore.Signal();
// Allows the thread to start.
//
//
// This class is supplied only for t
he purpose of t
esting Google Test's own
// This class is supplied only for testing Google Test's own
// constructs. Do not use it in user tests, either directly or indirectly.
// constructs. Do not use it in user tests, either directly or indirectly.
template
<
typename
T
>
template
<
typename
T
>
class
ThreadWithParam
{
class
ThreadWithParam
{
...
@@ -969,19 +983,16 @@ class ThreadWithParam {
...
@@ -969,19 +983,16 @@ class ThreadWithParam {
param_
(
param
),
param_
(
param
),
start_semaphore_
(
semaphore
),
start_semaphore_
(
semaphore
),
finished_
(
false
)
{
finished_
(
false
)
{
// func_, param_, and start_semaphore_ must be initialized before
// The thread can be created only after all fields except thread_
// pthread_create() is called.
// have been initialized.
const
int
err
=
pthread_create
(
&
thread_
,
0
,
ThreadMainStatic
,
this
);
GTEST_CHECK_POSIX_SUCCESS_
(
GTEST_CHECK_
(
err
==
0
)
<<
"pthread_create failed with error: "
pthread_create
(
&
thread_
,
0
,
ThreadMainStatic
,
this
));
<<
strerror
(
err
)
<<
"("
<<
err
<<
")"
;
}
}
~
ThreadWithParam
()
{
Join
();
}
~
ThreadWithParam
()
{
Join
();
}
void
Join
()
{
void
Join
()
{
if
(
!
finished_
)
{
if
(
!
finished_
)
{
const
int
err
=
pthread_join
(
thread_
,
0
);
GTEST_CHECK_POSIX_SUCCESS_
(
pthread_join
(
thread_
,
0
));
GTEST_CHECK_
(
err
==
0
)
<<
"pthread_join failed with error:"
<<
strerror
(
err
)
<<
"("
<<
err
<<
")"
;
finished_
=
true
;
finished_
=
true
;
}
}
}
}
...
@@ -992,23 +1003,18 @@ class ThreadWithParam {
...
@@ -992,23 +1003,18 @@ class ThreadWithParam {
start_semaphore_
->
Wait
();
start_semaphore_
->
Wait
();
func_
(
param_
);
func_
(
param_
);
}
}
static
void
*
ThreadMainStatic
(
void
*
param
)
{
static
void
*
ThreadMainStatic
(
void
*
thread_with_
param
)
{
static_cast
<
ThreadWithParam
<
T
>*>
(
param
)
->
ThreadMain
();
static_cast
<
ThreadWithParam
<
T
>*>
(
thread_with_
param
)
->
ThreadMain
();
return
NULL
;
// We are not interested in thread exit code.
return
NULL
;
// We are not interested in th
e th
read exit code.
}
}
// User supplied thread function.
const
UserThreadFunc
func_
;
// User-supplied thread function.
const
UserThreadFunc
func_
;
const
T
param_
;
// User-supplied parameter to the thread function.
// 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
// When non-NULL, used to block execution until the controller thread
// signals.
// signals.
ThreadStartSemaphore
*
const
start_semaphore_
;
ThreadStartSemaphore
*
const
start_semaphore_
;
// true iff UserThreadFunc has not completed yet.
bool
finished_
;
// Has the thread function finished?
bool
finished_
;
pthread_t
thread_
;
// The native thread object.
};
};
#define GTEST_IS_THREADSAFE 1
#define GTEST_IS_THREADSAFE 1
...
...
src/gtest-port.cc
View file @
4879aac7
...
@@ -81,10 +81,8 @@ const int kStdErrFileno = STDERR_FILENO;
...
@@ -81,10 +81,8 @@ const int kStdErrFileno = STDERR_FILENO;
// newly created test threads until signalled. Instances of this class must
// newly created test threads until signalled. Instances of this class must
// be created and destroyed in the controller thread.
// be created and destroyed in the controller thread.
ThreadStartSemaphore
::
ThreadStartSemaphore
()
:
signalled_
(
false
)
{
ThreadStartSemaphore
::
ThreadStartSemaphore
()
:
signalled_
(
false
)
{
int
err
=
pthread_mutex_init
(
&
mutex_
,
NULL
);
GTEST_CHECK_POSIX_SUCCESS_
(
pthread_mutex_init
(
&
mutex_
,
NULL
));
GTEST_CHECK_
(
err
==
0
)
<<
"pthread_mutex_init failed with error "
<<
err
;
GTEST_CHECK_POSIX_SUCCESS_
(
pthread_cond_init
(
&
cond_
,
NULL
));
err
=
pthread_cond_init
(
&
cond_
,
NULL
);
GTEST_CHECK_
(
err
==
0
)
<<
"pthread_cond_init failed with error "
<<
err
;
pthread_mutex_lock
(
&
mutex_
);
pthread_mutex_lock
(
&
mutex_
);
}
}
...
@@ -92,75 +90,29 @@ ThreadStartSemaphore::~ThreadStartSemaphore() {
...
@@ -92,75 +90,29 @@ ThreadStartSemaphore::~ThreadStartSemaphore() {
// Every ThreadStartSemaphore object must be signalled. It locks
// Every ThreadStartSemaphore object must be signalled. It locks
// internal mutex upon creation and Signal unlocks it.
// internal mutex upon creation and Signal unlocks it.
GTEST_CHECK_
(
signalled_
);
GTEST_CHECK_
(
signalled_
);
GTEST_CHECK_POSIX_SUCCESS_
(
pthread_mutex_destroy
(
&
mutex_
));
int
err
=
pthread_mutex_destroy
(
&
mutex_
);
GTEST_CHECK_POSIX_SUCCESS_
(
pthread_cond_destroy
(
&
cond_
));
GTEST_CHECK_
(
err
==
0
)
<<
"pthread_mutex_destroy failed with error "
<<
err
;
err
=
pthread_cond_destroy
(
&
cond_
);
GTEST_CHECK_
(
err
==
0
)
<<
"pthread_cond_destroy failed with error "
<<
err
;
}
}
// Signals to all test threads to start. Must be called from the
// Signals to all test threads to start. Must be called from the
// controlling thread.
// controlling thread.
void
ThreadStartSemaphore
::
Signal
()
{
void
ThreadStartSemaphore
::
Signal
()
{
signalled_
=
true
;
signalled_
=
true
;
int
err
=
pthread_cond_signal
(
&
cond_
);
GTEST_CHECK_POSIX_SUCCESS_
(
pthread_cond_signal
(
&
cond_
));
GTEST_CHECK_
(
err
==
0
)
GTEST_CHECK_POSIX_SUCCESS_
(
pthread_mutex_unlock
(
&
mutex_
));
<<
"pthread_cond_signal failed with error "
<<
err
;
err
=
pthread_mutex_unlock
(
&
mutex_
);
GTEST_CHECK_
(
err
==
0
)
<<
"pthread_mutex_unlock failed with error "
<<
err
;
}
}
// Blocks until the controlling thread signals. Should be called from a
// Blocks until the controlling thread signals. Should be called from a
// test thread.
// test thread.
void
ThreadStartSemaphore
::
Wait
()
{
void
ThreadStartSemaphore
::
Wait
()
{
int
err
=
pthread_mutex_lock
(
&
mutex_
);
GTEST_CHECK_POSIX_SUCCESS_
(
pthread_mutex_lock
(
&
mutex_
));
GTEST_CHECK_
(
err
==
0
)
<<
"pthread_mutex_lock failed with error "
<<
err
;
while
(
!
signalled_
)
{
while
(
!
signalled_
)
{
err
=
pthread_cond_wait
(
&
cond_
,
&
mutex_
);
GTEST_CHECK_POSIX_SUCCESS_
(
pthread_cond_wait
(
&
cond_
,
&
mutex_
));
GTEST_CHECK_
(
err
==
0
)
<<
"pthread_cond_wait failed with error "
<<
err
;
}
}
err
=
pthread_mutex_unlock
(
&
mutex_
);
GTEST_CHECK_POSIX_SUCCESS_
(
pthread_mutex_unlock
(
&
mutex_
));
GTEST_CHECK_
(
err
==
0
)
<<
"pthread_mutex_unlock failed with error "
<<
err
;
}
void
MutexBase
::
Lock
()
{
const
int
err
=
pthread_mutex_lock
(
&
mutex_
);
GTEST_CHECK_
(
err
==
0
)
<<
"pthread_mutex_lock failed with error "
<<
err
;
owner_
=
pthread_self
();
}
void
MutexBase
::
Unlock
()
{
// We don't protect writing to owner_ here, as it's the caller's
// responsibility to ensure that the current thread holds the mutex when
// this is called.
owner_
=
0
;
const
int
err
=
pthread_mutex_unlock
(
&
mutex_
);
GTEST_CHECK_
(
err
==
0
)
<<
"pthread_mutex_unlock failed with error "
<<
err
;
}
}
// Does nothing if the current thread holds the mutex. Otherwise, crashes
// with high probability.
void
MutexBase
::
AssertHeld
()
const
{
GTEST_CHECK_
(
owner_
==
pthread_self
())
<<
"Current thread is not holding mutex."
<<
this
;
}
Mutex
::
Mutex
()
{
owner_
=
0
;
const
int
err
=
pthread_mutex_init
(
&
mutex_
,
NULL
);
GTEST_CHECK_
(
err
==
0
)
<<
"pthread_mutex_init failed with error "
<<
err
;
}
Mutex
::~
Mutex
()
{
const
int
err
=
pthread_mutex_destroy
(
&
mutex_
);
GTEST_CHECK_
(
err
==
0
)
<<
"pthread_mutex_destroy failed with error "
<<
err
;
}
#endif // GTEST_HAS_PTHREAD
#endif // GTEST_HAS_PTHREAD
#if GTEST_OS_MAC
#if GTEST_OS_MAC
...
...
test/gtest-port_test.cc
View file @
4879aac7
...
@@ -770,18 +770,6 @@ TEST(ThreadLocalTest, SingleParamConstructorInitializesToParam) {
...
@@ -770,18 +770,6 @@ TEST(ThreadLocalTest, SingleParamConstructorInitializesToParam) {
EXPECT_EQ
(
&
i
,
t2
.
get
());
EXPECT_EQ
(
&
i
,
t2
.
get
());
}
}
class
NoCopyConstructor
{
public
:
NoCopyConstructor
()
{}
private
:
GTEST_DISALLOW_COPY_AND_ASSIGN_
(
NoCopyConstructor
);
};
TEST
(
ThreadLocalTest
,
ValueCopyConstructorIsNotRequiredForDefaultVersion
)
{
ThreadLocal
<
NoCopyConstructor
>
bar
;
bar
.
get
();
}
class
NoDefaultContructor
{
class
NoDefaultContructor
{
public
:
public
:
explicit
NoDefaultContructor
(
const
char
*
)
{}
explicit
NoDefaultContructor
(
const
char
*
)
{}
...
@@ -796,9 +784,6 @@ TEST(ThreadLocalTest, ValueDefaultContructorIsNotRequiredForParamVersion) {
...
@@ -796,9 +784,6 @@ TEST(ThreadLocalTest, ValueDefaultContructorIsNotRequiredForParamVersion) {
TEST
(
ThreadLocalTest
,
GetAndPointerReturnSameValue
)
{
TEST
(
ThreadLocalTest
,
GetAndPointerReturnSameValue
)
{
ThreadLocal
<
String
>
thread_local
;
ThreadLocal
<
String
>
thread_local
;
// This is why EXPECT_TRUE is used here rather than EXPECT_EQ because
// we don't care about a particular value of thread_local.pointer() here;
// we only care about pointer and reference referring to the same lvalue.
EXPECT_EQ
(
thread_local
.
pointer
(),
&
(
thread_local
.
get
()));
EXPECT_EQ
(
thread_local
.
pointer
(),
&
(
thread_local
.
get
()));
// Verifies the condition still holds after calling set.
// Verifies the condition still holds after calling set.
...
@@ -825,7 +810,7 @@ TEST(MutexTestDeathTest, AssertHeldShouldAssertWhenNotLocked) {
...
@@ -825,7 +810,7 @@ TEST(MutexTestDeathTest, AssertHeldShouldAssertWhenNotLocked) {
{
MutexLock
lock
(
&
m
);
}
{
MutexLock
lock
(
&
m
);
}
m
.
AssertHeld
();
m
.
AssertHeld
();
},
},
"
Current thread is not holding mutex.
.+"
);
"
The current thread is not holding the mutex @
.+"
);
}
}
void
SleepMilliseconds
(
int
time
)
{
void
SleepMilliseconds
(
int
time
)
{
...
@@ -847,16 +832,13 @@ class AtomicCounterWithMutex {
...
@@ -847,16 +832,13 @@ class AtomicCounterWithMutex {
// We cannot use Mutex and MutexLock here or rely on their memory
// We cannot use Mutex and MutexLock here or rely on their memory
// barrier functionality as we are testing them here.
// barrier functionality as we are testing them here.
pthread_mutex_t
memory_barrier_mutex
;
pthread_mutex_t
memory_barrier_mutex
;
int
err
=
pthread_mutex_init
(
&
memory_barrier_mutex
,
NULL
);
GTEST_CHECK_POSIX_SUCCESS_
(
GTEST_CHECK_
(
err
==
0
)
<<
"pthread_mutex_init failed with error "
<<
err
;
pthread_mutex_init
(
&
memory_barrier_mutex
,
NULL
));
err
=
pthread_mutex_lock
(
&
memory_barrier_mutex
);
GTEST_CHECK_POSIX_SUCCESS_
(
pthread_mutex_lock
(
&
memory_barrier_mutex
));
GTEST_CHECK_
(
err
==
0
)
<<
"pthread_mutex_lock failed with error "
<<
err
;
SleepMilliseconds
(
random_
.
Generate
(
30
));
SleepMilliseconds
(
random_
.
Generate
(
30
));
err
=
pthread_mutex_unlock
(
&
memory_barrier_mutex
);
GTEST_CHECK_POSIX_SUCCESS_
(
pthread_mutex_unlock
(
&
memory_barrier_mutex
));
GTEST_CHECK_
(
err
==
0
)
<<
"pthread_mutex_unlock failed with error "
<<
err
;
}
}
value_
=
temp
+
1
;
value_
=
temp
+
1
;
}
}
...
...
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