Moving src/webrtc into src/.
In order to eliminate the WebRTC Subtree mirror in Chromium, WebRTC is moving the content of the src/webrtc directory up to the src/ directory. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true TBR=tommi@webrtc.org Bug: chromium:611808 Change-Id: Iac59c5b51b950f174119565bac87955a7994bc38 Reviewed-on: https://webrtc-review.googlesource.com/1560 Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org> Reviewed-by: Henrik Kjellander <kjellander@webrtc.org> Cr-Commit-Position: refs/heads/master@{#19845}
This commit is contained in:
committed by
Commit Bot
parent
6674846b4a
commit
bb547203bf
153
rtc_base/thread_annotations_unittest.cc
Normal file
153
rtc_base/thread_annotations_unittest.cc
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/rtc_base/thread_annotations.h"
|
||||
#include "webrtc/test/gtest.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class RTC_LOCKABLE Lock {
|
||||
public:
|
||||
void EnterWrite() const RTC_EXCLUSIVE_LOCK_FUNCTION() {}
|
||||
void EnterRead() const RTC_SHARED_LOCK_FUNCTION() {}
|
||||
bool TryEnterWrite() const RTC_EXCLUSIVE_TRYLOCK_FUNCTION(true) {
|
||||
return true;
|
||||
}
|
||||
bool TryEnterRead() const RTC_SHARED_TRYLOCK_FUNCTION(true) { return true; }
|
||||
void Leave() const RTC_UNLOCK_FUNCTION() {}
|
||||
};
|
||||
|
||||
class RTC_SCOPED_LOCKABLE ScopeLock {
|
||||
public:
|
||||
explicit ScopeLock(const Lock& lock) RTC_EXCLUSIVE_LOCK_FUNCTION(lock) {}
|
||||
~ScopeLock() RTC_UNLOCK_FUNCTION() {}
|
||||
};
|
||||
|
||||
class ThreadSafe {
|
||||
public:
|
||||
ThreadSafe() {
|
||||
pt_protected_by_lock_ = new int;
|
||||
pt_protected_by_anything_ = new int;
|
||||
}
|
||||
|
||||
~ThreadSafe() {
|
||||
delete pt_protected_by_lock_;
|
||||
delete pt_protected_by_anything_;
|
||||
}
|
||||
|
||||
void LockInOrder() {
|
||||
anylock_.EnterWrite();
|
||||
lock_.EnterWrite();
|
||||
pt_lock_.EnterWrite();
|
||||
|
||||
pt_lock_.Leave();
|
||||
lock_.Leave();
|
||||
anylock_.Leave();
|
||||
}
|
||||
|
||||
void UnprotectedFunction() RTC_LOCKS_EXCLUDED(anylock_, lock_, pt_lock_) {
|
||||
// Can access unprotected Value.
|
||||
unprotected_ = 15;
|
||||
// Can access pointers themself, but not data they point to.
|
||||
int* tmp = pt_protected_by_lock_;
|
||||
pt_protected_by_lock_ = pt_protected_by_anything_;
|
||||
pt_protected_by_anything_ = tmp;
|
||||
}
|
||||
|
||||
void ReadProtected() {
|
||||
lock_.EnterRead();
|
||||
unprotected_ = protected_by_anything_;
|
||||
unprotected_ = protected_by_lock_;
|
||||
lock_.Leave();
|
||||
|
||||
if (pt_lock_.TryEnterRead()) {
|
||||
unprotected_ = *pt_protected_by_anything_;
|
||||
unprotected_ = *pt_protected_by_lock_;
|
||||
pt_lock_.Leave();
|
||||
}
|
||||
|
||||
anylock_.EnterRead();
|
||||
unprotected_ = protected_by_anything_;
|
||||
unprotected_ = *pt_protected_by_anything_;
|
||||
anylock_.Leave();
|
||||
}
|
||||
|
||||
void WriteProtected() {
|
||||
lock_.EnterWrite();
|
||||
protected_by_anything_ = unprotected_;
|
||||
protected_by_lock_ = unprotected_;
|
||||
lock_.Leave();
|
||||
|
||||
if (pt_lock_.TryEnterWrite()) {
|
||||
*pt_protected_by_anything_ = unprotected_;
|
||||
*pt_protected_by_lock_ = unprotected_;
|
||||
pt_lock_.Leave();
|
||||
}
|
||||
|
||||
anylock_.EnterWrite();
|
||||
protected_by_anything_ = unprotected_;
|
||||
*pt_protected_by_anything_ = unprotected_;
|
||||
anylock_.Leave();
|
||||
}
|
||||
|
||||
void CallReadProtectedFunction() {
|
||||
lock_.EnterRead();
|
||||
pt_lock_.EnterRead();
|
||||
ReadProtectedFunction();
|
||||
pt_lock_.Leave();
|
||||
lock_.Leave();
|
||||
}
|
||||
|
||||
void CallWriteProtectedFunction() {
|
||||
ScopeLock scope_lock(GetLock());
|
||||
ScopeLock pt_scope_lock(pt_lock_);
|
||||
WriteProtectedFunction();
|
||||
}
|
||||
|
||||
private:
|
||||
void ReadProtectedFunction() RTC_SHARED_LOCKS_REQUIRED(lock_, pt_lock_) {
|
||||
unprotected_ = protected_by_lock_;
|
||||
unprotected_ = *pt_protected_by_lock_;
|
||||
}
|
||||
|
||||
void WriteProtectedFunction() RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_, pt_lock_) {
|
||||
int x = protected_by_lock_;
|
||||
*pt_protected_by_lock_ = x;
|
||||
protected_by_lock_ = unprotected_;
|
||||
}
|
||||
|
||||
const Lock& GetLock() RTC_LOCK_RETURNED(lock_) { return lock_; }
|
||||
|
||||
Lock anylock_ RTC_ACQUIRED_BEFORE(lock_);
|
||||
Lock lock_;
|
||||
Lock pt_lock_ RTC_ACQUIRED_AFTER(lock_);
|
||||
|
||||
int unprotected_ = 0;
|
||||
|
||||
int protected_by_lock_ RTC_GUARDED_BY(lock_) = 0;
|
||||
int protected_by_anything_ RTC_GUARDED_VAR = 0;
|
||||
|
||||
int* pt_protected_by_lock_ RTC_PT_GUARDED_BY(pt_lock_);
|
||||
int* pt_protected_by_anything_ RTC_PT_GUARDED_VAR;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(ThreadAnnotationsTest, Test) {
|
||||
// This test ensure thread annotations doesn't break compilation.
|
||||
// Thus no run-time expectations.
|
||||
ThreadSafe t;
|
||||
t.LockInOrder();
|
||||
t.UnprotectedFunction();
|
||||
t.ReadProtected();
|
||||
t.WriteProtected();
|
||||
t.CallReadProtectedFunction();
|
||||
t.CallWriteProtectedFunction();
|
||||
}
|
||||
Reference in New Issue
Block a user