Thread annotation of rtc::CriticalSection.

Effectively re-lands r5516 which was reverted because talk/-only
checkouts existed. This now resides in webrtc/base/, so no talk/-only
checkouts should be possible.

This change also enables -Wthread-safety for talk/ and fixes a bug in
talk/media/webrtc/webrtcvideoengine2.cc where a guarded variable was
read without taking the corresponding lock.

R=andresp@webrtc.org, mflodman@webrtc.org, pthatcher@webrtc.org
BUG=

Review URL: https://webrtc-codereview.appspot.com/27569004

git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@7284 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/base/criticalsection.h b/base/criticalsection.h
index a950a47..a2d9bca 100644
--- a/base/criticalsection.h
+++ b/base/criticalsection.h
@@ -12,6 +12,7 @@
 #define WEBRTC_BASE_CRITICALSECTION_H__
 
 #include "webrtc/base/constructormagic.h"
+#include "webrtc/base/thread_annotations.h"
 
 #if defined(WEBRTC_WIN)
 #include "webrtc/base/win32.h"
@@ -34,7 +35,7 @@
 namespace rtc {
 
 #if defined(WEBRTC_WIN)
-class CriticalSection {
+class LOCKABLE CriticalSection {
  public:
   CriticalSection() {
     InitializeCriticalSection(&crit_);
@@ -44,18 +45,18 @@
   ~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_);
   }
@@ -71,7 +72,7 @@
 #endif // WEBRTC_WIN 
 
 #if defined(WEBRTC_POSIX)
-class CriticalSection {
+class LOCKABLE CriticalSection {
  public:
   CriticalSection() {
     pthread_mutexattr_t mutex_attribute;
@@ -84,18 +85,18 @@
   ~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_);
   }
@@ -111,13 +112,13 @@
 #endif // WEBRTC_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/base/sharedexclusivelock.h b/base/sharedexclusivelock.h
index f64d7cf..aaaba3b 100644
--- a/base/sharedexclusivelock.h
+++ b/base/sharedexclusivelock.h
@@ -19,14 +19,14 @@
 
 // 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();
 
@@ -39,15 +39,14 @@
   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() {
-    lock_->UnlockShared();
-  }
+  ~SharedScope() UNLOCK_FUNCTION() { lock_->UnlockShared(); }
 
  private:
   SharedExclusiveLock* lock_;
@@ -55,15 +54,15 @@
   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() {
-    lock_->UnlockExclusive();
-  }
+  ~ExclusiveScope() UNLOCK_FUNCTION() { lock_->UnlockExclusive(); }
 
  private:
   SharedExclusiveLock* lock_;
diff --git a/base/signalthread.h b/base/signalthread.h
index a97bda1..8e18be6 100644
--- a/base/signalthread.h
+++ b/base/signalthread.h
@@ -115,16 +115,17 @@
     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)