diff --git a/talk/base/criticalsection.h b/talk/base/criticalsection.h index c6ffbc0d9..92745ce77 100644 --- a/talk/base/criticalsection.h +++ b/talk/base/criticalsection.h @@ -29,6 +29,7 @@ #define TALK_BASE_CRITICALSECTION_H__ #include "talk/base/constructormagic.h" +#include "webrtc/system_wrappers/interface/thread_annotations.h" #ifdef WIN32 #include "talk/base/win32.h" @@ -51,7 +52,7 @@ namespace talk_base { #ifdef WIN32 -class CriticalSection { +class LOCKABLE CriticalSection { public: CriticalSection() { InitializeCriticalSection(&crit_); @@ -61,18 +62,18 @@ class CriticalSection { ~CriticalSection() { DeleteCriticalSection(&crit_); } - void Enter() { + void Enter() EXCLUSIVE_LOCK_FUNCTION() { EnterCriticalSection(&crit_); TRACK_OWNER(thread_ = GetCurrentThreadId()); } - bool TryEnter() { + bool TryEnter() EXCLUSIVE_TRYLOCK_FUNCTION(true) { if (TryEnterCriticalSection(&crit_) != FALSE) { TRACK_OWNER(thread_ = GetCurrentThreadId()); return true; } return false; } - void Leave() { + void Leave() UNLOCK_FUNCTION() { TRACK_OWNER(thread_ = 0); LeaveCriticalSection(&crit_); } @@ -88,7 +89,7 @@ class CriticalSection { #endif // WIN32 #ifdef POSIX -class CriticalSection { +class LOCKABLE CriticalSection { public: CriticalSection() { pthread_mutexattr_t mutex_attribute; @@ -101,18 +102,18 @@ class CriticalSection { ~CriticalSection() { pthread_mutex_destroy(&mutex_); } - void Enter() { + void Enter() EXCLUSIVE_LOCK_FUNCTION() { pthread_mutex_lock(&mutex_); TRACK_OWNER(thread_ = pthread_self()); } - bool TryEnter() { + bool TryEnter() EXCLUSIVE_TRYLOCK_FUNCTION(true) { if (pthread_mutex_trylock(&mutex_) == 0) { TRACK_OWNER(thread_ = pthread_self()); return true; } return false; } - void Leave() { + void Leave() UNLOCK_FUNCTION() { TRACK_OWNER(thread_ = 0); pthread_mutex_unlock(&mutex_); } @@ -128,13 +129,13 @@ class CriticalSection { #endif // POSIX // CritScope, for serializing execution through a scope. -class CritScope { +class SCOPED_LOCKABLE CritScope { public: - explicit CritScope(CriticalSection *pcrit) { + explicit CritScope(CriticalSection *pcrit) EXCLUSIVE_LOCK_FUNCTION(pcrit) { pcrit_ = pcrit; pcrit_->Enter(); } - ~CritScope() { + ~CritScope() UNLOCK_FUNCTION() { pcrit_->Leave(); } private: diff --git a/talk/base/sharedexclusivelock.h b/talk/base/sharedexclusivelock.h index 2bdd85483..d06aa0101 100644 --- a/talk/base/sharedexclusivelock.h +++ b/talk/base/sharedexclusivelock.h @@ -36,14 +36,14 @@ namespace talk_base { // This class provides shared-exclusive lock. It can be used in cases like // multiple-readers/single-writer model. -class SharedExclusiveLock { +class LOCKABLE SharedExclusiveLock { public: SharedExclusiveLock(); // Locking/unlocking methods. It is encouraged to use SharedScope or // ExclusiveScope for protection. - void LockExclusive(); - void UnlockExclusive(); + void LockExclusive() EXCLUSIVE_LOCK_FUNCTION(); + void UnlockExclusive() UNLOCK_FUNCTION(); void LockShared(); void UnlockShared(); @@ -56,13 +56,14 @@ class SharedExclusiveLock { DISALLOW_COPY_AND_ASSIGN(SharedExclusiveLock); }; -class SharedScope { +class SCOPED_LOCKABLE SharedScope { public: - explicit SharedScope(SharedExclusiveLock* lock) : lock_(lock) { + explicit SharedScope(SharedExclusiveLock* lock) SHARED_LOCK_FUNCTION(lock) + : lock_(lock) { lock_->LockShared(); } - ~SharedScope() { + ~SharedScope() UNLOCK_FUNCTION() { lock_->UnlockShared(); } @@ -72,13 +73,15 @@ class SharedScope { DISALLOW_COPY_AND_ASSIGN(SharedScope); }; -class ExclusiveScope { +class SCOPED_LOCKABLE ExclusiveScope { public: - explicit ExclusiveScope(SharedExclusiveLock* lock) : lock_(lock) { + explicit ExclusiveScope(SharedExclusiveLock* lock) + EXCLUSIVE_LOCK_FUNCTION(lock) + : lock_(lock) { lock_->LockExclusive(); } - ~ExclusiveScope() { + ~ExclusiveScope() UNLOCK_FUNCTION() { lock_->UnlockExclusive(); } diff --git a/talk/base/signalthread.h b/talk/base/signalthread.h index 46dd0a3ba..5865bf9fe 100644 --- a/talk/base/signalthread.h +++ b/talk/base/signalthread.h @@ -132,16 +132,17 @@ class SignalThread DISALLOW_IMPLICIT_CONSTRUCTORS(Worker); }; - class EnterExit { + class SCOPED_LOCKABLE EnterExit { public: - explicit EnterExit(SignalThread* t) : t_(t) { + explicit EnterExit(SignalThread* t) EXCLUSIVE_LOCK_FUNCTION(t->cs_) + : t_(t) { t_->cs_.Enter(); // If refcount_ is zero then the object has already been deleted and we // will be double-deleting it in ~EnterExit()! (shouldn't happen) ASSERT(t_->refcount_ != 0); ++t_->refcount_; } - ~EnterExit() { + ~EnterExit() UNLOCK_FUNCTION() { bool d = (0 == --t_->refcount_); t_->cs_.Leave(); if (d) diff --git a/talk/build/common.gypi b/talk/build/common.gypi index 4c762d1dd..7bd1992d1 100644 --- a/talk/build/common.gypi +++ b/talk/build/common.gypi @@ -89,6 +89,7 @@ # LateBindingSymbolTable::TableInfo from # latebindingsymboltable.cc.def and remove below flag. '-Wno-address-of-array-temporary', + '-Wthread-safety', ], }], ], diff --git a/talk/session/media/mediamonitor.h b/talk/session/media/mediamonitor.h index a9ce88959..7a416be77 100644 --- a/talk/session/media/mediamonitor.h +++ b/talk/session/media/mediamonitor.h @@ -77,7 +77,7 @@ class MediaMonitorT : public MediaMonitor { media_info_.Clear(); media_channel_->GetStats(&media_info_); } - virtual void Update() { + virtual void Update() EXCLUSIVE_LOCKS_REQUIRED(crit_) { MI stats(media_info_); crit_.Leave(); SignalUpdate(media_channel_, stats);