Reformatted critical_section wrappers.
BUG= TEST=ran trybots Review URL: https://webrtc-codereview.appspot.com/971012 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3210 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@ -14,52 +14,48 @@
|
|||||||
// If the critical section is heavily contended it may be beneficial to use
|
// If the critical section is heavily contended it may be beneficial to use
|
||||||
// read/write locks instead.
|
// read/write locks instead.
|
||||||
|
|
||||||
#include "common_types.h"
|
#include "webrtc/common_types.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
class CriticalSectionWrapper
|
class CriticalSectionWrapper {
|
||||||
{
|
public:
|
||||||
public:
|
// Factory method, constructor disabled
|
||||||
// Factory method, constructor disabled
|
static CriticalSectionWrapper* CreateCriticalSection();
|
||||||
static CriticalSectionWrapper* CreateCriticalSection();
|
|
||||||
|
|
||||||
virtual ~CriticalSectionWrapper() {}
|
virtual ~CriticalSectionWrapper() {}
|
||||||
|
|
||||||
// Tries to grab lock, beginning of a critical section. Will wait for the
|
// Tries to grab lock, beginning of a critical section. Will wait for the
|
||||||
// lock to become available if the grab failed.
|
// lock to become available if the grab failed.
|
||||||
virtual void Enter() = 0;
|
virtual void Enter() = 0;
|
||||||
|
|
||||||
// Returns a grabbed lock, end of critical section.
|
// Returns a grabbed lock, end of critical section.
|
||||||
virtual void Leave() = 0;
|
virtual void Leave() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// RAII extension of the critical section. Prevents Enter/Leave mismatches and
|
// RAII extension of the critical section. Prevents Enter/Leave mismatches and
|
||||||
// provides more compact critical section syntax.
|
// provides more compact critical section syntax.
|
||||||
class CriticalSectionScoped
|
class CriticalSectionScoped {
|
||||||
{
|
public:
|
||||||
public:
|
explicit CriticalSectionScoped(CriticalSectionWrapper* critsec)
|
||||||
explicit CriticalSectionScoped(CriticalSectionWrapper* critsec)
|
: ptr_crit_sec_(critsec) {
|
||||||
: _ptrCritSec(critsec)
|
ptr_crit_sec_->Enter();
|
||||||
{
|
}
|
||||||
_ptrCritSec->Enter();
|
|
||||||
}
|
|
||||||
|
|
||||||
~CriticalSectionScoped()
|
~CriticalSectionScoped() {
|
||||||
{
|
if (ptr_crit_sec_) {
|
||||||
if (_ptrCritSec)
|
Leave();
|
||||||
{
|
|
||||||
Leave();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Leave()
|
void Leave() {
|
||||||
{
|
ptr_crit_sec_->Leave();
|
||||||
_ptrCritSec->Leave();
|
ptr_crit_sec_ = 0;
|
||||||
_ptrCritSec = 0;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
CriticalSectionWrapper* _ptrCritSec;
|
CriticalSectionWrapper* ptr_crit_sec_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_
|
|
||||||
|
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_
|
||||||
|
@ -72,7 +72,7 @@ ConditionVariablePosix::~ConditionVariablePosix() {
|
|||||||
void ConditionVariablePosix::SleepCS(CriticalSectionWrapper& crit_sect) {
|
void ConditionVariablePosix::SleepCS(CriticalSectionWrapper& crit_sect) {
|
||||||
CriticalSectionPosix* cs = reinterpret_cast<CriticalSectionPosix*>(
|
CriticalSectionPosix* cs = reinterpret_cast<CriticalSectionPosix*>(
|
||||||
&crit_sect);
|
&crit_sect);
|
||||||
pthread_cond_wait(&cond_, &cs->_mutex);
|
pthread_cond_wait(&cond_, &cs->mutex_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConditionVariablePosix::SleepCS(CriticalSectionWrapper& crit_sect,
|
bool ConditionVariablePosix::SleepCS(CriticalSectionWrapper& crit_sect,
|
||||||
@ -113,10 +113,10 @@ bool ConditionVariablePosix::SleepCS(CriticalSectionWrapper& crit_sect,
|
|||||||
ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
|
ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
|
||||||
ts.tv_nsec %= NANOSECONDS_PER_SECOND;
|
ts.tv_nsec %= NANOSECONDS_PER_SECOND;
|
||||||
}
|
}
|
||||||
const int res = pthread_cond_timedwait(&cond_, &cs->_mutex, &ts);
|
const int res = pthread_cond_timedwait(&cond_, &cs->mutex_, &ts);
|
||||||
return (res == ETIMEDOUT) ? false : true;
|
return (res == ETIMEDOUT) ? false : true;
|
||||||
} else {
|
} else {
|
||||||
pthread_cond_wait(&cond_, &cs->_mutex);
|
pthread_cond_wait(&cond_, &cs->mutex_);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,19 +9,20 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "critical_section_win.h"
|
#include "webrtc/system_wrappers/source/critical_section_win.h"
|
||||||
#else
|
#else
|
||||||
#include "critical_section_posix.h"
|
#include "webrtc/system_wrappers/source/critical_section_posix.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
CriticalSectionWrapper* CriticalSectionWrapper::CreateCriticalSection()
|
|
||||||
{
|
CriticalSectionWrapper* CriticalSectionWrapper::CreateCriticalSection() {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
return new CriticalSectionWindows();
|
return new CriticalSectionWindows();
|
||||||
#else
|
#else
|
||||||
return new CriticalSectionPosix();
|
return new CriticalSectionPosix();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -14,33 +14,29 @@
|
|||||||
// no equivalent to DCHECK_EQ in WebRTC code so this is the best we can do here.
|
// no equivalent to DCHECK_EQ in WebRTC code so this is the best we can do here.
|
||||||
// TODO(henrike): add logging when pthread synchronization APIs are failing.
|
// TODO(henrike): add logging when pthread synchronization APIs are failing.
|
||||||
|
|
||||||
#include "critical_section_posix.h"
|
#include "webrtc/system_wrappers/source/critical_section_posix.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
CriticalSectionPosix::CriticalSectionPosix()
|
CriticalSectionPosix::CriticalSectionPosix() {
|
||||||
{
|
pthread_mutexattr_t attr;
|
||||||
pthread_mutexattr_t attr;
|
(void) pthread_mutexattr_init(&attr);
|
||||||
(void) pthread_mutexattr_init(&attr);
|
(void) pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||||
(void) pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
(void) pthread_mutex_init(&mutex_, &attr);
|
||||||
(void) pthread_mutex_init(&_mutex, &attr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CriticalSectionPosix::~CriticalSectionPosix()
|
CriticalSectionPosix::~CriticalSectionPosix() {
|
||||||
{
|
(void) pthread_mutex_destroy(&mutex_);
|
||||||
(void) pthread_mutex_destroy(&_mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CriticalSectionPosix::Enter()
|
CriticalSectionPosix::Enter() {
|
||||||
{
|
(void) pthread_mutex_lock(&mutex_);
|
||||||
(void) pthread_mutex_lock(&_mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CriticalSectionPosix::Leave()
|
CriticalSectionPosix::Leave() {
|
||||||
{
|
(void) pthread_mutex_unlock(&mutex_);
|
||||||
(void) pthread_mutex_unlock(&_mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -11,25 +11,26 @@
|
|||||||
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_POSIX_H_
|
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_POSIX_H_
|
||||||
#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_POSIX_H_
|
#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_POSIX_H_
|
||||||
|
|
||||||
#include "critical_section_wrapper.h"
|
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
class CriticalSectionPosix : public CriticalSectionWrapper
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CriticalSectionPosix();
|
|
||||||
|
|
||||||
virtual ~CriticalSectionPosix();
|
class CriticalSectionPosix : public CriticalSectionWrapper {
|
||||||
|
public:
|
||||||
|
CriticalSectionPosix();
|
||||||
|
|
||||||
virtual void Enter();
|
virtual ~CriticalSectionPosix();
|
||||||
virtual void Leave();
|
|
||||||
|
|
||||||
private:
|
virtual void Enter();
|
||||||
pthread_mutex_t _mutex;
|
virtual void Leave();
|
||||||
friend class ConditionVariablePosix;
|
|
||||||
|
private:
|
||||||
|
pthread_mutex_t mutex_;
|
||||||
|
friend class ConditionVariablePosix;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_POSIX_H_
|
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_POSIX_H_
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// For Sleep()
|
// For Sleep()
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
@ -16,13 +18,11 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "system_wrappers/interface/critical_section_wrapper.h"
|
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "system_wrappers/interface/sleep.h"
|
#include "webrtc/system_wrappers/interface/sleep.h"
|
||||||
#include "system_wrappers/interface/thread_wrapper.h"
|
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
|
||||||
#include "system_wrappers/interface/trace.h"
|
#include "webrtc/system_wrappers/interface/trace.h"
|
||||||
#include "system_wrappers/source/unittest_utilities.h"
|
#include "webrtc/system_wrappers/source/unittest_utilities.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ static void SwitchProcess() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ProtectedCount {
|
class ProtectedCount {
|
||||||
public:
|
public:
|
||||||
explicit ProtectedCount(CriticalSectionWrapper* crit_sect)
|
explicit ProtectedCount(CriticalSectionWrapper* crit_sect)
|
||||||
: crit_sect_(crit_sect),
|
: crit_sect_(crit_sect),
|
||||||
count_(0) {
|
count_(0) {
|
||||||
@ -55,13 +55,13 @@ class ProtectedCount {
|
|||||||
return count_;
|
return count_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CriticalSectionWrapper* crit_sect_;
|
CriticalSectionWrapper* crit_sect_;
|
||||||
int count_;
|
int count_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CritSectTest : public ::testing::Test {
|
class CritSectTest : public ::testing::Test {
|
||||||
public:
|
public:
|
||||||
CritSectTest() : trace_(kLogTrace) {
|
CritSectTest() : trace_(kLogTrace) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,26 +72,26 @@ class CritSectTest : public ::testing::Test {
|
|||||||
// On Posix, this SwitchProcess() needs to be in a loop to make the
|
// On Posix, this SwitchProcess() needs to be in a loop to make the
|
||||||
// test both fast and non-flaky.
|
// test both fast and non-flaky.
|
||||||
// With 1 us wait as the switch, up to 7 rounds have been observed.
|
// With 1 us wait as the switch, up to 7 rounds have been observed.
|
||||||
while (count->Count() < target && loop_counter < 100*target) {
|
while (count->Count() < target && loop_counter < 100 * target) {
|
||||||
++loop_counter;
|
++loop_counter;
|
||||||
SwitchProcess();
|
SwitchProcess();
|
||||||
}
|
}
|
||||||
return (count->Count() >= target);
|
return (count->Count() >= target);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ScopedTracing trace_;
|
ScopedTracing trace_;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool LockUnlockThenStopRunFunction(void* obj) {
|
bool LockUnlockThenStopRunFunction(void* obj) {
|
||||||
ProtectedCount* the_count = static_cast<ProtectedCount*> (obj);
|
ProtectedCount* the_count = static_cast<ProtectedCount*>(obj);
|
||||||
the_count->Increment();
|
the_count->Increment();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CritSectTest, ThreadWakesOnce) {
|
TEST_F(CritSectTest, ThreadWakesOnce) {
|
||||||
CriticalSectionWrapper* crit_sect
|
CriticalSectionWrapper* crit_sect =
|
||||||
= CriticalSectionWrapper::CreateCriticalSection();
|
CriticalSectionWrapper::CreateCriticalSection();
|
||||||
ProtectedCount count(crit_sect);
|
ProtectedCount count(crit_sect);
|
||||||
ThreadWrapper* thread = ThreadWrapper::CreateThread(
|
ThreadWrapper* thread = ThreadWrapper::CreateThread(
|
||||||
&LockUnlockThenStopRunFunction, &count);
|
&LockUnlockThenStopRunFunction, &count);
|
||||||
@ -112,15 +112,15 @@ TEST_F(CritSectTest, ThreadWakesOnce) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool LockUnlockRunFunction(void* obj) {
|
bool LockUnlockRunFunction(void* obj) {
|
||||||
ProtectedCount* the_count = static_cast<ProtectedCount*> (obj);
|
ProtectedCount* the_count = static_cast<ProtectedCount*>(obj);
|
||||||
the_count->Increment();
|
the_count->Increment();
|
||||||
SwitchProcess();
|
SwitchProcess();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CritSectTest, ThreadWakesTwice) {
|
TEST_F(CritSectTest, ThreadWakesTwice) {
|
||||||
CriticalSectionWrapper* crit_sect
|
CriticalSectionWrapper* crit_sect =
|
||||||
= CriticalSectionWrapper::CreateCriticalSection();
|
CriticalSectionWrapper::CreateCriticalSection();
|
||||||
ProtectedCount count(crit_sect);
|
ProtectedCount count(crit_sect);
|
||||||
ThreadWrapper* thread = ThreadWrapper::CreateThread(&LockUnlockRunFunction,
|
ThreadWrapper* thread = ThreadWrapper::CreateThread(&LockUnlockRunFunction,
|
||||||
&count);
|
&count);
|
||||||
|
@ -8,28 +8,26 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "critical_section_win.h"
|
#include "webrtc/system_wrappers/source/critical_section_win.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
CriticalSectionWindows::CriticalSectionWindows()
|
|
||||||
{
|
CriticalSectionWindows::CriticalSectionWindows() {
|
||||||
InitializeCriticalSection(&crit);
|
InitializeCriticalSection(&crit);
|
||||||
}
|
}
|
||||||
|
|
||||||
CriticalSectionWindows::~CriticalSectionWindows()
|
CriticalSectionWindows::~CriticalSectionWindows() {
|
||||||
{
|
DeleteCriticalSection(&crit);
|
||||||
DeleteCriticalSection(&crit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CriticalSectionWindows::Enter()
|
CriticalSectionWindows::Enter() {
|
||||||
{
|
EnterCriticalSection(&crit);
|
||||||
EnterCriticalSection(&crit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CriticalSectionWindows::Leave()
|
CriticalSectionWindows::Leave() {
|
||||||
{
|
LeaveCriticalSection(&crit);
|
||||||
LeaveCriticalSection(&crit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -8,29 +8,30 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WINDOWS_H_
|
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WIN_H_
|
||||||
#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WINDOWS_H_
|
#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WIN_H_
|
||||||
|
|
||||||
#include "typedefs.h"
|
#include "webrtc/typedefs.h"
|
||||||
#include "critical_section_wrapper.h"
|
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
class CriticalSectionWindows : public CriticalSectionWrapper
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CriticalSectionWindows();
|
|
||||||
|
|
||||||
virtual ~CriticalSectionWindows();
|
class CriticalSectionWindows : public CriticalSectionWrapper {
|
||||||
|
public:
|
||||||
|
CriticalSectionWindows();
|
||||||
|
|
||||||
virtual void Enter();
|
virtual ~CriticalSectionWindows();
|
||||||
virtual void Leave();
|
|
||||||
|
|
||||||
private:
|
virtual void Enter();
|
||||||
CRITICAL_SECTION crit;
|
virtual void Leave();
|
||||||
|
|
||||||
friend class ConditionVariableWindows;
|
private:
|
||||||
|
CRITICAL_SECTION crit;
|
||||||
|
|
||||||
|
friend class ConditionVariableWindows;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WINDOWS_H_
|
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WIN_H_
|
||||||
|
Reference in New Issue
Block a user