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:
phoglund@webrtc.org
2012-11-30 10:44:49 +00:00
parent 219df91095
commit 99f7c917d2
8 changed files with 110 additions and 117 deletions

View File

@ -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_

View File

@ -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;
} }
} }

View File

@ -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

View File

@ -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

View File

@ -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_

View File

@ -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);

View File

@ -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

View File

@ -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_