Reformatted condition_variable* in system_wrappers.
BUG= TEST=Ran trybots. Review URL: https://webrtc-codereview.appspot.com/937017 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3095 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
12b828ac90
commit
a36d75a03c
@ -12,30 +12,31 @@
|
||||
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CONDITION_VARIABLE_WRAPPER_H_
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class CriticalSectionWrapper;
|
||||
|
||||
class ConditionVariableWrapper
|
||||
{
|
||||
public:
|
||||
// Factory method, constructor disabled.
|
||||
static ConditionVariableWrapper* CreateConditionVariable();
|
||||
class ConditionVariableWrapper {
|
||||
public:
|
||||
// Factory method, constructor disabled.
|
||||
static ConditionVariableWrapper* CreateConditionVariable();
|
||||
|
||||
virtual ~ConditionVariableWrapper() {}
|
||||
virtual ~ConditionVariableWrapper() {}
|
||||
|
||||
// Calling thread will atomically release critSect and wait until next
|
||||
// some other thread calls Wake() or WakeAll().
|
||||
virtual void SleepCS(CriticalSectionWrapper& critSect) = 0;
|
||||
// Calling thread will atomically release crit_sect and wait until next
|
||||
// some other thread calls Wake() or WakeAll().
|
||||
virtual void SleepCS(CriticalSectionWrapper& crit_sect) = 0;
|
||||
|
||||
// Same as above but with a timeout.
|
||||
virtual bool SleepCS(CriticalSectionWrapper& critSect,
|
||||
unsigned long maxTimeInMS) = 0;
|
||||
// Same as above but with a timeout.
|
||||
virtual bool SleepCS(CriticalSectionWrapper& crit_sect,
|
||||
unsigned long max_time_in_ms) = 0;
|
||||
|
||||
// Wakes one thread calling SleepCS().
|
||||
virtual void Wake() = 0;
|
||||
// Wakes one thread calling SleepCS().
|
||||
virtual void Wake() = 0;
|
||||
|
||||
// Wakes all threads calling SleepCS().
|
||||
virtual void WakeAll() = 0;
|
||||
// Wakes all threads calling SleepCS().
|
||||
virtual void WakeAll() = 0;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CONDITION_VARIABLE_WRAPPER_H_
|
||||
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CONDITION_VARIABLE_WRAPPER_H_
|
||||
|
@ -9,29 +9,25 @@
|
||||
*/
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#include "condition_variable_wrapper.h"
|
||||
#include "condition_variable_win.h"
|
||||
#elif defined(WEBRTC_LINUX)
|
||||
#include <pthread.h>
|
||||
#include "condition_variable_wrapper.h"
|
||||
#include "condition_variable_posix.h"
|
||||
#elif defined(WEBRTC_MAC)
|
||||
#include <pthread.h>
|
||||
#include "condition_variable_wrapper.h"
|
||||
#include "condition_variable_posix.h"
|
||||
#include <windows.h>
|
||||
#include "condition_variable_win.h"
|
||||
#include "condition_variable_wrapper.h"
|
||||
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
|
||||
#include <pthread.h>
|
||||
#include "condition_variable_posix.h"
|
||||
#include "condition_variable_wrapper.h"
|
||||
#endif
|
||||
|
||||
namespace webrtc {
|
||||
ConditionVariableWrapper*
|
||||
ConditionVariableWrapper::CreateConditionVariable()
|
||||
{
|
||||
|
||||
ConditionVariableWrapper* ConditionVariableWrapper::CreateConditionVariable() {
|
||||
#if defined(_WIN32)
|
||||
return new ConditionVariableWindows;
|
||||
return new ConditionVariableWindows;
|
||||
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
|
||||
return ConditionVariablePosix::Create();
|
||||
return ConditionVariablePosix::Create();
|
||||
#else
|
||||
return NULL;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -10,142 +10,123 @@
|
||||
|
||||
#include "condition_variable_posix.h"
|
||||
|
||||
#include <errno.h>
|
||||
#if defined(WEBRTC_LINUX)
|
||||
#include <ctime>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "critical_section_posix.h"
|
||||
|
||||
namespace webrtc {
|
||||
ConditionVariableWrapper* ConditionVariablePosix::Create()
|
||||
{
|
||||
ConditionVariablePosix* ptr = new ConditionVariablePosix;
|
||||
if (!ptr)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const int error = ptr->Construct();
|
||||
if (error)
|
||||
{
|
||||
delete ptr;
|
||||
return NULL;
|
||||
}
|
||||
ConditionVariableWrapper* ConditionVariablePosix::Create() {
|
||||
ConditionVariablePosix* ptr = new ConditionVariablePosix;
|
||||
if (!ptr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
const int error = ptr->Construct();
|
||||
if (error) {
|
||||
delete ptr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
ConditionVariablePosix::ConditionVariablePosix()
|
||||
{
|
||||
ConditionVariablePosix::ConditionVariablePosix() {
|
||||
}
|
||||
|
||||
int ConditionVariablePosix::Construct()
|
||||
{
|
||||
int ConditionVariablePosix::Construct() {
|
||||
#ifdef WEBRTC_CLOCK_TYPE_REALTIME
|
||||
pthread_cond_init(&_cond, NULL);
|
||||
pthread_cond_init(&cond_, NULL);
|
||||
#else
|
||||
int result = 0;
|
||||
pthread_condattr_t condAttr;
|
||||
result = pthread_condattr_init(&condAttr);
|
||||
if (result != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
result = pthread_condattr_setclock(&condAttr, CLOCK_MONOTONIC);
|
||||
if (result != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
result = pthread_cond_init(&_cond, &condAttr);
|
||||
if (result != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
result = pthread_condattr_destroy(&condAttr);
|
||||
if (result != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int result = 0;
|
||||
pthread_condattr_t cond_attr;
|
||||
result = pthread_condattr_init(&cond_attr);
|
||||
if (result != 0) {
|
||||
return -1;
|
||||
}
|
||||
result = pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
|
||||
if (result != 0) {
|
||||
return -1;
|
||||
}
|
||||
result = pthread_cond_init(&cond_, &cond_attr);
|
||||
if (result != 0) {
|
||||
return -1;
|
||||
}
|
||||
result = pthread_condattr_destroy(&cond_attr);
|
||||
if (result != 0) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ConditionVariablePosix::~ConditionVariablePosix()
|
||||
{
|
||||
pthread_cond_destroy(&_cond);
|
||||
ConditionVariablePosix::~ConditionVariablePosix() {
|
||||
pthread_cond_destroy(&cond_);
|
||||
}
|
||||
|
||||
void ConditionVariablePosix::SleepCS(CriticalSectionWrapper& critSect)
|
||||
{
|
||||
CriticalSectionPosix* cs = reinterpret_cast<CriticalSectionPosix*>(
|
||||
&critSect);
|
||||
pthread_cond_wait(&_cond, &cs->_mutex);
|
||||
void ConditionVariablePosix::SleepCS(CriticalSectionWrapper& crit_sect) {
|
||||
CriticalSectionPosix* cs = reinterpret_cast<CriticalSectionPosix*>(
|
||||
&crit_sect);
|
||||
pthread_cond_wait(&cond_, &cs->_mutex);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ConditionVariablePosix::SleepCS(
|
||||
CriticalSectionWrapper& critSect,
|
||||
unsigned long maxTimeInMS)
|
||||
{
|
||||
const unsigned long INFINITE = 0xFFFFFFFF;
|
||||
|
||||
const int MILLISECONDS_PER_SECOND = 1000;
|
||||
bool ConditionVariablePosix::SleepCS(CriticalSectionWrapper& crit_sect,
|
||||
unsigned long max_time_inMS) {
|
||||
const unsigned long INFINITE = 0xFFFFFFFF;
|
||||
const int MILLISECONDS_PER_SECOND = 1000;
|
||||
#ifndef WEBRTC_LINUX
|
||||
const int MICROSECONDS_PER_MILLISECOND = 1000;
|
||||
const int MICROSECONDS_PER_MILLISECOND = 1000;
|
||||
#endif
|
||||
const int NANOSECONDS_PER_SECOND = 1000000000;
|
||||
const int NANOSECONDS_PER_MILLISECOND = 1000000;
|
||||
const int NANOSECONDS_PER_SECOND = 1000000000;
|
||||
const int NANOSECONDS_PER_MILLISECOND = 1000000;
|
||||
|
||||
CriticalSectionPosix* cs = reinterpret_cast<CriticalSectionPosix*>(
|
||||
&critSect);
|
||||
CriticalSectionPosix* cs = reinterpret_cast<CriticalSectionPosix*>(
|
||||
&crit_sect);
|
||||
|
||||
if (maxTimeInMS != INFINITE)
|
||||
{
|
||||
timespec ts;
|
||||
if (max_time_inMS != INFINITE) {
|
||||
timespec ts;
|
||||
#ifndef WEBRTC_MAC
|
||||
#ifdef WEBRTC_CLOCK_TYPE_REALTIME
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
#else
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
#endif
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, 0);
|
||||
ts.tv_sec = tv.tv_sec;
|
||||
ts.tv_nsec = tv.tv_usec * MICROSECONDS_PER_MILLISECOND;
|
||||
#else // WEBRTC_MAC
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, 0);
|
||||
ts.tv_sec = tv.tv_sec;
|
||||
ts.tv_nsec = tv.tv_usec * MICROSECONDS_PER_MILLISECOND;
|
||||
#endif
|
||||
|
||||
ts.tv_sec += maxTimeInMS / MILLISECONDS_PER_SECOND;
|
||||
ts.tv_nsec += (maxTimeInMS - ((maxTimeInMS / MILLISECONDS_PER_SECOND)*
|
||||
MILLISECONDS_PER_SECOND)) * NANOSECONDS_PER_MILLISECOND;
|
||||
ts.tv_sec += max_time_inMS / MILLISECONDS_PER_SECOND;
|
||||
ts.tv_nsec +=
|
||||
(max_time_inMS
|
||||
- ((max_time_inMS / MILLISECONDS_PER_SECOND) * MILLISECONDS_PER_SECOND))
|
||||
* NANOSECONDS_PER_MILLISECOND;
|
||||
|
||||
if (ts.tv_nsec >= NANOSECONDS_PER_SECOND)
|
||||
{
|
||||
ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
|
||||
ts.tv_nsec %= NANOSECONDS_PER_SECOND;
|
||||
}
|
||||
const int res = pthread_cond_timedwait(&_cond, &cs->_mutex, &ts);
|
||||
return (res == ETIMEDOUT) ? false : true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pthread_cond_wait(&_cond, &cs->_mutex);
|
||||
return true;
|
||||
if (ts.tv_nsec >= NANOSECONDS_PER_SECOND) {
|
||||
ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
|
||||
ts.tv_nsec %= NANOSECONDS_PER_SECOND;
|
||||
}
|
||||
const int res = pthread_cond_timedwait(&cond_, &cs->_mutex, &ts);
|
||||
return (res == ETIMEDOUT) ? false : true;
|
||||
} else {
|
||||
pthread_cond_wait(&cond_, &cs->_mutex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void ConditionVariablePosix::Wake()
|
||||
{
|
||||
pthread_cond_signal(&_cond);
|
||||
void ConditionVariablePosix::Wake() {
|
||||
pthread_cond_signal(&cond_);
|
||||
}
|
||||
|
||||
void ConditionVariablePosix::WakeAll()
|
||||
{
|
||||
pthread_cond_broadcast(&_cond);
|
||||
void ConditionVariablePosix::WakeAll() {
|
||||
pthread_cond_broadcast(&cond_);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -11,29 +11,30 @@
|
||||
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_POSIX_H_
|
||||
#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_POSIX_H_
|
||||
|
||||
#include "condition_variable_wrapper.h"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "condition_variable_wrapper.h"
|
||||
|
||||
namespace webrtc {
|
||||
class ConditionVariablePosix : public ConditionVariableWrapper
|
||||
{
|
||||
public:
|
||||
static ConditionVariableWrapper* Create();
|
||||
~ConditionVariablePosix();
|
||||
|
||||
void SleepCS(CriticalSectionWrapper& critSect);
|
||||
bool SleepCS(CriticalSectionWrapper& critSect, unsigned long maxTimeInMS);
|
||||
void Wake();
|
||||
void WakeAll();
|
||||
class ConditionVariablePosix : public ConditionVariableWrapper {
|
||||
public:
|
||||
static ConditionVariableWrapper* Create();
|
||||
~ConditionVariablePosix();
|
||||
|
||||
private:
|
||||
ConditionVariablePosix();
|
||||
int Construct();
|
||||
void SleepCS(CriticalSectionWrapper& crit_sect);
|
||||
bool SleepCS(CriticalSectionWrapper& crit_sect, unsigned long max_time_in_ms);
|
||||
void Wake();
|
||||
void WakeAll();
|
||||
|
||||
private:
|
||||
pthread_cond_t _cond;
|
||||
private:
|
||||
ConditionVariablePosix();
|
||||
int Construct();
|
||||
|
||||
private:
|
||||
pthread_cond_t cond_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_POSIX_H_
|
||||
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_POSIX_H_
|
||||
|
@ -21,8 +21,8 @@ namespace webrtc {
|
||||
namespace {
|
||||
|
||||
const int kLogTrace = false; // Set to true to enable debug logging to stdout.
|
||||
const int kLongWaitMs = 100*1000; // A long time in testing terms
|
||||
const int kShortWaitMs = 2*1000; // Long enough for process switches to happen
|
||||
const int kLongWaitMs = 100 * 1000; // A long time in testing terms
|
||||
const int kShortWaitMs = 2 * 1000; // Long enough for process switches to happen
|
||||
|
||||
#define LOG(...) WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, __VA_ARGS__);
|
||||
|
||||
@ -145,7 +145,7 @@ class Baton {
|
||||
// Function that waits on a Baton, and passes it right back.
|
||||
// We expect these calls never to time out.
|
||||
bool WaitingRunFunction(void* obj) {
|
||||
Baton* the_baton = static_cast<Baton*> (obj);
|
||||
Baton* the_baton = static_cast<Baton*>(obj);
|
||||
LOG("Thread waiting");
|
||||
EXPECT_TRUE(the_baton->Grab(kLongWaitMs));
|
||||
LOG("Thread waking parent");
|
||||
@ -200,7 +200,7 @@ TEST_F(CondVarTest, PassBatonMultipleTimes) {
|
||||
ASSERT_TRUE(baton_.Pass(kShortWaitMs));
|
||||
ASSERT_TRUE(baton_.Grab(kShortWaitMs));
|
||||
}
|
||||
EXPECT_EQ(2*kNumberOfRounds, baton_.PassCount());
|
||||
EXPECT_EQ(2 * kNumberOfRounds, baton_.PassCount());
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
@ -19,18 +19,19 @@
|
||||
// implementation into two different files
|
||||
|
||||
#include "condition_variable_win.h"
|
||||
|
||||
#include "critical_section_win.h"
|
||||
#include "trace.h"
|
||||
|
||||
namespace webrtc {
|
||||
bool ConditionVariableWindows::_winSupportConditionVariablesPrimitive = false;
|
||||
|
||||
bool ConditionVariableWindows::win_support_condition_variables_primitive_ =
|
||||
false;
|
||||
static HMODULE library = NULL;
|
||||
|
||||
PInitializeConditionVariable _PInitializeConditionVariable;
|
||||
PSleepConditionVariableCS _PSleepConditionVariableCS;
|
||||
PWakeConditionVariable _PWakeConditionVariable;
|
||||
PWakeAllConditionVariable _PWakeAllConditionVariable;
|
||||
PInitializeConditionVariable PInitializeConditionVariable_;
|
||||
PSleepConditionVariableCS PSleepConditionVariableCS_;
|
||||
PWakeConditionVariable PWakeConditionVariable_;
|
||||
PWakeAllConditionVariable PWakeAllConditionVariable_;
|
||||
|
||||
typedef void (WINAPI *PInitializeConditionVariable)(PCONDITION_VARIABLE);
|
||||
typedef BOOL (WINAPI *PSleepConditionVariableCS)(PCONDITION_VARIABLE,
|
||||
@ -39,186 +40,159 @@ typedef void (WINAPI *PWakeConditionVariable)(PCONDITION_VARIABLE);
|
||||
typedef void (WINAPI *PWakeAllConditionVariable)(PCONDITION_VARIABLE);
|
||||
|
||||
ConditionVariableWindows::ConditionVariableWindows()
|
||||
: _eventID(WAKEALL_0)
|
||||
{
|
||||
if (!library)
|
||||
{
|
||||
// Use native implementation if supported (i.e Vista+)
|
||||
library = LoadLibrary(TEXT("Kernel32.dll"));
|
||||
if (library)
|
||||
{
|
||||
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
|
||||
"Loaded Kernel.dll");
|
||||
: eventID_(WAKEALL_0) {
|
||||
if (!library) {
|
||||
// Use native implementation if supported (i.e Vista+)
|
||||
library = LoadLibrary(TEXT("Kernel32.dll"));
|
||||
if (library) {
|
||||
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, "Loaded Kernel.dll");
|
||||
|
||||
_PInitializeConditionVariable =
|
||||
(PInitializeConditionVariable) GetProcAddress(
|
||||
library,
|
||||
"InitializeConditionVariable");
|
||||
_PSleepConditionVariableCS =
|
||||
(PSleepConditionVariableCS)GetProcAddress(
|
||||
library,
|
||||
"SleepConditionVariableCS");
|
||||
_PWakeConditionVariable =
|
||||
(PWakeConditionVariable)GetProcAddress(
|
||||
library,
|
||||
"WakeConditionVariable");
|
||||
_PWakeAllConditionVariable =
|
||||
(PWakeAllConditionVariable)GetProcAddress(
|
||||
library,
|
||||
"WakeAllConditionVariable");
|
||||
PInitializeConditionVariable_ =
|
||||
(PInitializeConditionVariable) GetProcAddress(
|
||||
library, "InitializeConditionVariable");
|
||||
PSleepConditionVariableCS_ = (PSleepConditionVariableCS) GetProcAddress(
|
||||
library, "SleepConditionVariableCS");
|
||||
PWakeConditionVariable_ = (PWakeConditionVariable) GetProcAddress(
|
||||
library, "WakeConditionVariable");
|
||||
PWakeAllConditionVariable_ = (PWakeAllConditionVariable) GetProcAddress(
|
||||
library, "WakeAllConditionVariable");
|
||||
|
||||
if(_PInitializeConditionVariable &&
|
||||
_PSleepConditionVariableCS &&
|
||||
_PWakeConditionVariable &&
|
||||
_PWakeAllConditionVariable)
|
||||
{
|
||||
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
|
||||
"Loaded native condition variables");
|
||||
_winSupportConditionVariablesPrimitive = true;
|
||||
}
|
||||
}
|
||||
if (PInitializeConditionVariable_ && PSleepConditionVariableCS_
|
||||
&& PWakeConditionVariable_ && PWakeAllConditionVariable_) {
|
||||
WEBRTC_TRACE(
|
||||
kTraceStateInfo, kTraceUtility, -1,
|
||||
"Loaded native condition variables");
|
||||
win_support_condition_variables_primitive_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_winSupportConditionVariablesPrimitive)
|
||||
{
|
||||
_PInitializeConditionVariable(&_conditionVariable);
|
||||
if (win_support_condition_variables_primitive_) {
|
||||
PInitializeConditionVariable_(&condition_variable_);
|
||||
|
||||
_events[WAKEALL_0] = NULL;
|
||||
_events[WAKEALL_1] = NULL;
|
||||
_events[WAKE] = NULL;
|
||||
events_[WAKEALL_0] = NULL;
|
||||
events_[WAKEALL_1] = NULL;
|
||||
events_[WAKE] = NULL;
|
||||
|
||||
} else {
|
||||
memset(&_numWaiters[0],0,sizeof(_numWaiters));
|
||||
} else {
|
||||
memset(&num_waiters_[0], 0, sizeof(num_waiters_));
|
||||
|
||||
InitializeCriticalSection(&_numWaitersCritSect);
|
||||
InitializeCriticalSection(&num_waiters_crit_sect_);
|
||||
|
||||
_events[WAKEALL_0] = CreateEvent(NULL, // no security attributes
|
||||
TRUE, // manual-reset, sticky event
|
||||
FALSE, // initial state non-signaled
|
||||
NULL); // no name for event
|
||||
events_[WAKEALL_0] = CreateEvent(NULL, // no security attributes
|
||||
TRUE, // manual-reset, sticky event
|
||||
FALSE, // initial state non-signaled
|
||||
NULL); // no name for event
|
||||
|
||||
_events[WAKEALL_1] = CreateEvent(NULL, // no security attributes
|
||||
TRUE, // manual-reset, sticky event
|
||||
FALSE, // initial state non-signaled
|
||||
NULL); // no name for event
|
||||
events_[WAKEALL_1] = CreateEvent(NULL, // no security attributes
|
||||
TRUE, // manual-reset, sticky event
|
||||
FALSE, // initial state non-signaled
|
||||
NULL); // no name for event
|
||||
|
||||
_events[WAKE] = CreateEvent(NULL, // no security attributes
|
||||
FALSE, // auto-reset, sticky event
|
||||
FALSE, // initial state non-signaled
|
||||
NULL); // no name for event
|
||||
}
|
||||
events_[WAKE] = CreateEvent(NULL, // no security attributes
|
||||
FALSE, // auto-reset, sticky event
|
||||
FALSE, // initial state non-signaled
|
||||
NULL); // no name for event
|
||||
}
|
||||
}
|
||||
|
||||
ConditionVariableWindows::~ConditionVariableWindows()
|
||||
{
|
||||
if(!_winSupportConditionVariablesPrimitive)
|
||||
{
|
||||
CloseHandle(_events[WAKE]);
|
||||
CloseHandle(_events[WAKEALL_1]);
|
||||
CloseHandle(_events[WAKEALL_0]);
|
||||
ConditionVariableWindows::~ConditionVariableWindows() {
|
||||
if (!win_support_condition_variables_primitive_) {
|
||||
CloseHandle(events_[WAKE]);
|
||||
CloseHandle(events_[WAKEALL_1]);
|
||||
CloseHandle(events_[WAKEALL_0]);
|
||||
|
||||
DeleteCriticalSection(&_numWaitersCritSect);
|
||||
DeleteCriticalSection(&num_waiters_crit_sect_);
|
||||
}
|
||||
}
|
||||
|
||||
void ConditionVariableWindows::SleepCS(CriticalSectionWrapper& crit_sect) {
|
||||
SleepCS(crit_sect, INFINITE);
|
||||
}
|
||||
|
||||
bool ConditionVariableWindows::SleepCS(CriticalSectionWrapper& crit_sect,
|
||||
unsigned long max_time_in_ms) {
|
||||
CriticalSectionWindows* cs =
|
||||
reinterpret_cast<CriticalSectionWindows*>(&crit_sect);
|
||||
|
||||
if (win_support_condition_variables_primitive_) {
|
||||
BOOL ret_val = PSleepConditionVariableCS_(
|
||||
&condition_variable_, &(cs->crit), max_time_in_ms);
|
||||
return (ret_val == 0) ? false : true;
|
||||
} else {
|
||||
EnterCriticalSection(&num_waiters_crit_sect_);
|
||||
|
||||
// Get the eventID for the event that will be triggered by next
|
||||
// WakeAll() call and start waiting for it.
|
||||
const EventWakeUpType eventID =
|
||||
(WAKEALL_0 == eventID_) ? WAKEALL_1 : WAKEALL_0;
|
||||
|
||||
++(num_waiters_[eventID]);
|
||||
LeaveCriticalSection(&num_waiters_crit_sect_);
|
||||
|
||||
LeaveCriticalSection(&cs->crit);
|
||||
HANDLE events[2];
|
||||
events[0] = events_[WAKE];
|
||||
events[1] = events_[eventID];
|
||||
const DWORD result = WaitForMultipleObjects(2, // Wait on 2 events.
|
||||
events, FALSE, // Wait for either.
|
||||
max_time_in_ms);
|
||||
|
||||
const bool ret_val = (result != WAIT_TIMEOUT);
|
||||
|
||||
EnterCriticalSection(&num_waiters_crit_sect_);
|
||||
--(num_waiters_[eventID]);
|
||||
|
||||
// Last waiter should only be true for WakeAll(). WakeAll() correspond
|
||||
// to position 1 in events[] -> (result == WAIT_OBJECT_0 + 1)
|
||||
const bool last_waiter = (result == WAIT_OBJECT_0 + 1)
|
||||
&& (num_waiters_[eventID] == 0);
|
||||
LeaveCriticalSection(&num_waiters_crit_sect_);
|
||||
|
||||
if (last_waiter) {
|
||||
// Reset/unset the WakeAll() event since all threads have been
|
||||
// released.
|
||||
ResetEvent(events_[eventID]);
|
||||
}
|
||||
|
||||
EnterCriticalSection(&cs->crit);
|
||||
return ret_val;
|
||||
}
|
||||
}
|
||||
|
||||
void ConditionVariableWindows::SleepCS(CriticalSectionWrapper& critSect)
|
||||
{
|
||||
SleepCS(critSect, INFINITE);
|
||||
}
|
||||
void ConditionVariableWindows::Wake() {
|
||||
if (win_support_condition_variables_primitive_) {
|
||||
PWakeConditionVariable_(&condition_variable_);
|
||||
} else {
|
||||
EnterCriticalSection(&num_waiters_crit_sect_);
|
||||
const bool have_waiters = (num_waiters_[WAKEALL_0] > 0)
|
||||
|| (num_waiters_[WAKEALL_1] > 0);
|
||||
LeaveCriticalSection(&num_waiters_crit_sect_);
|
||||
|
||||
bool ConditionVariableWindows::SleepCS(CriticalSectionWrapper& critSect,
|
||||
unsigned long maxTimeInMS)
|
||||
{
|
||||
CriticalSectionWindows* cs = reinterpret_cast<CriticalSectionWindows*>(
|
||||
&critSect);
|
||||
|
||||
if(_winSupportConditionVariablesPrimitive)
|
||||
{
|
||||
BOOL retVal = _PSleepConditionVariableCS(&_conditionVariable,
|
||||
&(cs->crit),maxTimeInMS);
|
||||
return (retVal == 0) ? false : true;
|
||||
|
||||
}else
|
||||
{
|
||||
EnterCriticalSection(&_numWaitersCritSect);
|
||||
// Get the eventID for the event that will be triggered by next
|
||||
// WakeAll() call and start waiting for it.
|
||||
const EventWakeUpType eventID = (WAKEALL_0 == _eventID) ?
|
||||
WAKEALL_1 : WAKEALL_0;
|
||||
++(_numWaiters[eventID]);
|
||||
LeaveCriticalSection(&_numWaitersCritSect);
|
||||
|
||||
LeaveCriticalSection(&cs->crit);
|
||||
HANDLE events[2];
|
||||
events[0] = _events[WAKE];
|
||||
events[1] = _events[eventID];
|
||||
const DWORD result = WaitForMultipleObjects(2, // Wait on 2 events.
|
||||
events,
|
||||
FALSE, // Wait for either.
|
||||
maxTimeInMS);
|
||||
|
||||
const bool retVal = (result != WAIT_TIMEOUT);
|
||||
|
||||
EnterCriticalSection(&_numWaitersCritSect);
|
||||
--(_numWaiters[eventID]);
|
||||
// Last waiter should only be true for WakeAll(). WakeAll() correspond
|
||||
// to position 1 in events[] -> (result == WAIT_OBJECT_0 + 1)
|
||||
const bool lastWaiter = (result == WAIT_OBJECT_0 + 1) &&
|
||||
(_numWaiters[eventID] == 0);
|
||||
LeaveCriticalSection(&_numWaitersCritSect);
|
||||
|
||||
if (lastWaiter)
|
||||
{
|
||||
// Reset/unset the WakeAll() event since all threads have been
|
||||
// released.
|
||||
ResetEvent(_events[eventID]);
|
||||
}
|
||||
|
||||
EnterCriticalSection(&cs->crit);
|
||||
return retVal;
|
||||
if (have_waiters) {
|
||||
SetEvent(events_[WAKE]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ConditionVariableWindows::Wake()
|
||||
{
|
||||
if(_winSupportConditionVariablesPrimitive)
|
||||
{
|
||||
_PWakeConditionVariable(&_conditionVariable);
|
||||
}else
|
||||
{
|
||||
EnterCriticalSection(&_numWaitersCritSect);
|
||||
const bool haveWaiters = (_numWaiters[WAKEALL_0] > 0) ||
|
||||
(_numWaiters[WAKEALL_1] > 0);
|
||||
LeaveCriticalSection(&_numWaitersCritSect);
|
||||
void ConditionVariableWindows::WakeAll() {
|
||||
if (win_support_condition_variables_primitive_) {
|
||||
PWakeAllConditionVariable_(&condition_variable_);
|
||||
} else {
|
||||
EnterCriticalSection(&num_waiters_crit_sect_);
|
||||
|
||||
if (haveWaiters)
|
||||
{
|
||||
SetEvent(_events[WAKE]);
|
||||
}
|
||||
// Update current WakeAll() event
|
||||
eventID_ = (WAKEALL_0 == eventID_) ? WAKEALL_1 : WAKEALL_0;
|
||||
|
||||
// Trigger current event
|
||||
const EventWakeUpType eventID = eventID_;
|
||||
const bool have_waiters = num_waiters_[eventID] > 0;
|
||||
LeaveCriticalSection(&num_waiters_crit_sect_);
|
||||
|
||||
if (have_waiters) {
|
||||
SetEvent(events_[eventID]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ConditionVariableWindows::WakeAll()
|
||||
{
|
||||
if(_winSupportConditionVariablesPrimitive)
|
||||
{
|
||||
_PWakeAllConditionVariable(&_conditionVariable);
|
||||
}else
|
||||
{
|
||||
EnterCriticalSection(&_numWaitersCritSect);
|
||||
// Update current WakeAll() event
|
||||
_eventID = (WAKEALL_0 == _eventID) ? WAKEALL_1 : WAKEALL_0;
|
||||
// Trigger current event
|
||||
const EventWakeUpType eventID = _eventID;
|
||||
const bool haveWaiters = _numWaiters[eventID] > 0;
|
||||
LeaveCriticalSection(&_numWaitersCritSect);
|
||||
|
||||
if (haveWaiters)
|
||||
{
|
||||
SetEvent(_events[eventID]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
@ -8,60 +8,58 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_WINDOWS_H_
|
||||
#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_WINDOWS_H_
|
||||
|
||||
#include "condition_variable_wrapper.h"
|
||||
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_WIN_H_
|
||||
#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_WIN_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace webrtc {
|
||||
#if !defined CONDITION_VARIABLE_INIT
|
||||
typedef struct _RTL_CONDITION_VARIABLE
|
||||
{
|
||||
void* Ptr;
|
||||
} RTL_CONDITION_VARIABLE, *PRTL_CONDITION_VARIABLE;
|
||||
#include "condition_variable_wrapper.h"
|
||||
|
||||
typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE;
|
||||
namespace webrtc {
|
||||
|
||||
#if !defined CONDITION_VARIABLE_INIT
|
||||
typedef struct RTL_CONDITION_VARIABLE_ {
|
||||
void* Ptr;
|
||||
} RTL_CONDITION_VARIABLE, *PRTL_CONDITION_VARIABLE;
|
||||
|
||||
typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE;
|
||||
#endif
|
||||
|
||||
typedef void (WINAPI *PInitializeConditionVariable)(PCONDITION_VARIABLE);
|
||||
typedef BOOL (WINAPI *PSleepConditionVariableCS)(PCONDITION_VARIABLE,
|
||||
typedef void (WINAPI* PInitializeConditionVariable)(PCONDITION_VARIABLE);
|
||||
typedef BOOL (WINAPI* PSleepConditionVariableCS)(PCONDITION_VARIABLE,
|
||||
PCRITICAL_SECTION, DWORD);
|
||||
typedef void (WINAPI *PWakeConditionVariable)(PCONDITION_VARIABLE);
|
||||
typedef void (WINAPI *PWakeAllConditionVariable)(PCONDITION_VARIABLE);
|
||||
typedef void (WINAPI* PWakeConditionVariable)(PCONDITION_VARIABLE);
|
||||
typedef void (WINAPI* PWakeAllConditionVariable)(PCONDITION_VARIABLE);
|
||||
|
||||
class ConditionVariableWindows : public ConditionVariableWrapper {
|
||||
public:
|
||||
ConditionVariableWindows();
|
||||
~ConditionVariableWindows();
|
||||
|
||||
class ConditionVariableWindows : public ConditionVariableWrapper
|
||||
{
|
||||
public:
|
||||
ConditionVariableWindows();
|
||||
~ConditionVariableWindows();
|
||||
void SleepCS(CriticalSectionWrapper& crit_sect);
|
||||
bool SleepCS(CriticalSectionWrapper& crit_sect, unsigned long max_time_inMS);
|
||||
void Wake();
|
||||
void WakeAll();
|
||||
|
||||
void SleepCS(CriticalSectionWrapper& critSect);
|
||||
bool SleepCS(CriticalSectionWrapper& critSect, unsigned long maxTimeInMS);
|
||||
void Wake();
|
||||
void WakeAll();
|
||||
private:
|
||||
enum EventWakeUpType {
|
||||
WAKEALL_0 = 0,
|
||||
WAKEALL_1 = 1,
|
||||
WAKE = 2,
|
||||
EVENT_COUNT = 3
|
||||
};
|
||||
|
||||
private:
|
||||
enum EventWakeUpType
|
||||
{
|
||||
WAKEALL_0 = 0,
|
||||
WAKEALL_1 = 1,
|
||||
WAKE = 2,
|
||||
EVENT_COUNT = 3
|
||||
};
|
||||
private:
|
||||
// Native support for Windows Vista+
|
||||
static bool win_support_condition_variables_primitive_;
|
||||
CONDITION_VARIABLE condition_variable_;
|
||||
|
||||
private:
|
||||
// Native support for Windows Vista+
|
||||
static bool _winSupportConditionVariablesPrimitive;
|
||||
CONDITION_VARIABLE _conditionVariable;
|
||||
|
||||
unsigned int _numWaiters[2];
|
||||
EventWakeUpType _eventID;
|
||||
CRITICAL_SECTION _numWaitersCritSect;
|
||||
HANDLE _events[EVENT_COUNT];
|
||||
unsigned int num_waiters_[2];
|
||||
EventWakeUpType eventID_;
|
||||
CRITICAL_SECTION num_waiters_crit_sect_;
|
||||
HANDLE events_[EVENT_COUNT];
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_WINDOWS_H_
|
||||
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_WIN_H_
|
||||
|
Loading…
x
Reference in New Issue
Block a user