Alien-cares
view release on metacpan or search on metacpan
libcares/test/gmock-1.8.0/gmock-gtest-all.cc view on Meta::CPAN
}
void Notification::Notify() {
GTEST_CHECK_(::SetEvent(event_.Get()) != FALSE);
}
void Notification::WaitForNotification() {
GTEST_CHECK_(
::WaitForSingleObject(event_.Get(), INFINITE) == WAIT_OBJECT_0);
}
Mutex::Mutex()
: owner_thread_id_(0),
type_(kDynamic),
critical_section_init_phase_(0),
critical_section_(new CRITICAL_SECTION) {
::InitializeCriticalSection(critical_section_);
}
Mutex::~Mutex() {
// Static mutexes are leaked intentionally. It is not thread-safe to try
// to clean them up.
// TODO(yukawa): Switch to Slim Reader/Writer (SRW) Locks, which requires
// nothing to clean it up but is available only on Vista and later.
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa904937.aspx
if (type_ == kDynamic) {
::DeleteCriticalSection(critical_section_);
delete critical_section_;
critical_section_ = NULL;
}
}
void Mutex::Lock() {
ThreadSafeLazyInit();
::EnterCriticalSection(critical_section_);
owner_thread_id_ = ::GetCurrentThreadId();
}
void Mutex::Unlock() {
ThreadSafeLazyInit();
// We don't protect writing to owner_thread_id_ here, as it's the
// caller's responsibility to ensure that the current thread holds the
// mutex when this is called.
owner_thread_id_ = 0;
::LeaveCriticalSection(critical_section_);
}
// Does nothing if the current thread holds the mutex. Otherwise, crashes
// with high probability.
void Mutex::AssertHeld() {
ThreadSafeLazyInit();
GTEST_CHECK_(owner_thread_id_ == ::GetCurrentThreadId())
<< "The current thread is not holding the mutex @" << this;
}
// Initializes owner_thread_id_ and critical_section_ in static mutexes.
void Mutex::ThreadSafeLazyInit() {
// Dynamic mutexes are initialized in the constructor.
if (type_ == kStatic) {
switch (
::InterlockedCompareExchange(&critical_section_init_phase_, 1L, 0L)) {
case 0:
// If critical_section_init_phase_ was 0 before the exchange, we
// are the first to test it and need to perform the initialization.
owner_thread_id_ = 0;
critical_section_ = new CRITICAL_SECTION;
::InitializeCriticalSection(critical_section_);
// Updates the critical_section_init_phase_ to 2 to signal
// initialization complete.
GTEST_CHECK_(::InterlockedCompareExchange(
&critical_section_init_phase_, 2L, 1L) ==
1L);
break;
case 1:
// Somebody else is already initializing the mutex; spin until they
// are done.
while (::InterlockedCompareExchange(&critical_section_init_phase_,
2L,
2L) != 2L) {
// Possibly yields the rest of the thread's time slice to other
// threads.
::Sleep(0);
}
break;
case 2:
break; // The mutex is already initialized and ready for use.
default:
GTEST_CHECK_(false)
<< "Unexpected value of critical_section_init_phase_ "
<< "while initializing a static mutex.";
}
}
}
namespace {
class ThreadWithParamSupport : public ThreadWithParamBase {
public:
static HANDLE CreateThread(Runnable* runnable,
Notification* thread_can_start) {
ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start);
DWORD thread_id;
// TODO(yukawa): Consider to use _beginthreadex instead.
HANDLE thread_handle = ::CreateThread(
NULL, // Default security.
0, // Default stack size.
&ThreadWithParamSupport::ThreadMain,
param, // Parameter to ThreadMainStatic
0x0, // Default creation flags.
&thread_id); // Need a valid pointer for the call to work under Win98.
GTEST_CHECK_(thread_handle != NULL) << "CreateThread failed with error "
<< ::GetLastError() << ".";
if (thread_handle == NULL) {
delete param;
}
return thread_handle;
}
private:
struct ThreadMainParam {
ThreadMainParam(Runnable* runnable, Notification* thread_can_start)
: runnable_(runnable),
thread_can_start_(thread_can_start) {
}
scoped_ptr<Runnable> runnable_;
// Does not own.
Notification* thread_can_start_;
};
static DWORD WINAPI ThreadMain(void* ptr) {
// Transfers ownership.
scoped_ptr<ThreadMainParam> param(static_cast<ThreadMainParam*>(ptr));
if (param->thread_can_start_ != NULL)
param->thread_can_start_->WaitForNotification();
param->runnable_->Run();
libcares/test/gmock-1.8.0/gmock-gtest-all.cc view on Meta::CPAN
// ThreadLocalValueHolderBases.
}
static void OnThreadExit(DWORD thread_id) {
GTEST_CHECK_(thread_id != 0) << ::GetLastError();
std::vector<linked_ptr<ThreadLocalValueHolderBase> > value_holders;
// Clean up the ThreadIdToThreadLocals data structure while holding the
// lock, but defer the destruction of the ThreadLocalValueHolderBases.
{
MutexLock lock(&mutex_);
ThreadIdToThreadLocals* const thread_to_thread_locals =
GetThreadLocalsMapLocked();
ThreadIdToThreadLocals::iterator thread_local_pos =
thread_to_thread_locals->find(thread_id);
if (thread_local_pos != thread_to_thread_locals->end()) {
ThreadLocalValues& thread_local_values = thread_local_pos->second;
for (ThreadLocalValues::iterator value_pos =
thread_local_values.begin();
value_pos != thread_local_values.end();
++value_pos) {
value_holders.push_back(value_pos->second);
}
thread_to_thread_locals->erase(thread_local_pos);
}
}
// Outside the lock, let the destructor for 'value_holders' deallocate the
// ThreadLocalValueHolderBases.
}
private:
// In a particular thread, maps a ThreadLocal object to its value.
typedef std::map<const ThreadLocalBase*,
linked_ptr<ThreadLocalValueHolderBase> > ThreadLocalValues;
// Stores all ThreadIdToThreadLocals having values in a thread, indexed by
// thread's ID.
typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals;
// Holds the thread id and thread handle that we pass from
// StartWatcherThreadFor to WatcherThreadFunc.
typedef std::pair<DWORD, HANDLE> ThreadIdAndHandle;
static void StartWatcherThreadFor(DWORD thread_id) {
// The returned handle will be kept in thread_map and closed by
// watcher_thread in WatcherThreadFunc.
HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION,
FALSE,
thread_id);
GTEST_CHECK_(thread != NULL);
// We need to to pass a valid thread ID pointer into CreateThread for it
// to work correctly under Win98.
DWORD watcher_thread_id;
HANDLE watcher_thread = ::CreateThread(
NULL, // Default security.
0, // Default stack size
&ThreadLocalRegistryImpl::WatcherThreadFunc,
reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)),
CREATE_SUSPENDED,
&watcher_thread_id);
GTEST_CHECK_(watcher_thread != NULL);
// Give the watcher thread the same priority as ours to avoid being
// blocked by it.
::SetThreadPriority(watcher_thread,
::GetThreadPriority(::GetCurrentThread()));
::ResumeThread(watcher_thread);
::CloseHandle(watcher_thread);
}
// Monitors exit from a given thread and notifies those
// ThreadIdToThreadLocals about thread termination.
static DWORD WINAPI WatcherThreadFunc(LPVOID param) {
const ThreadIdAndHandle* tah =
reinterpret_cast<const ThreadIdAndHandle*>(param);
GTEST_CHECK_(
::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0);
OnThreadExit(tah->first);
::CloseHandle(tah->second);
delete tah;
return 0;
}
// Returns map of thread local instances.
static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() {
mutex_.AssertHeld();
static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals;
return map;
}
// Protects access to GetThreadLocalsMapLocked() and its return value.
static Mutex mutex_;
// Protects access to GetThreadMapLocked() and its return value.
static Mutex thread_map_mutex_;
};
Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex);
Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex);
ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread(
const ThreadLocalBase* thread_local_instance) {
return ThreadLocalRegistryImpl::GetValueOnCurrentThread(
thread_local_instance);
}
void ThreadLocalRegistry::OnThreadLocalDestroyed(
const ThreadLocalBase* thread_local_instance) {
ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance);
}
#endif // GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
#if GTEST_USES_POSIX_RE
// Implements RE. Currently only needed for death tests.
RE::~RE() {
if (is_valid_) {
// regfree'ing an invalid regex might crash because the content
// of the regex is undefined. Since the regex's are essentially
// the same, one cannot be valid (or invalid) without the other
// being so too.
regfree(&partial_regex_);
regfree(&full_regex_);
( run in 3.116 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )