Fix data races in ThreadTest.ThreeThreadsInvoke.
R=henrike@webrtc.org
BUG=
Review URL: https://webrtc-codereview.appspot.com/26819004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@7457 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/base/thread_unittest.cc b/webrtc/base/thread_unittest.cc
index bab4f0f..951a7e1 100644
--- a/webrtc/base/thread_unittest.cc
+++ b/webrtc/base/thread_unittest.cc
@@ -313,42 +313,64 @@
thread_b.Start();
thread_c.Start();
+ class LockedBool {
+ public:
+ explicit LockedBool(bool value) : value_(value) {}
+
+ void Set(bool value) {
+ CritScope lock(&crit_);
+ value_ = value;
+ }
+
+ bool Get() {
+ CritScope lock(&crit_);
+ return value_;
+ }
+
+ private:
+ CriticalSection crit_;
+ bool value_ GUARDED_BY(crit_);
+ };
+
struct LocalFuncs {
- static void Set(bool* out) { *out = true; }
- static void InvokeSet(Thread* thread, bool* out) {
+ static void Set(LockedBool* out) { out->Set(true); }
+ static void InvokeSet(Thread* thread, LockedBool* out) {
thread->Invoke<void>(Bind(&Set, out));
}
// Set |out| true and call InvokeSet on |thread|.
- static void SetAndInvokeSet(bool* out, Thread* thread, bool* out_inner) {
- *out = true;
+ static void SetAndInvokeSet(LockedBool* out,
+ Thread* thread,
+ LockedBool* out_inner) {
+ out->Set(true);
InvokeSet(thread, out_inner);
}
// Asynchronously invoke SetAndInvokeSet on |thread1| and wait until
// |thread1| starts the call.
static void AsyncInvokeSetAndWait(
- Thread* thread1, Thread* thread2, bool* out) {
- bool async_invoked = false;
+ Thread* thread1, Thread* thread2, LockedBool* out) {
+ CriticalSection crit;
+ LockedBool async_invoked(false);
AsyncInvoker invoker;
invoker.AsyncInvoke<void>(
thread1, Bind(&SetAndInvokeSet, &async_invoked, thread2, out));
- EXPECT_TRUE_WAIT(async_invoked, 2000);
+ EXPECT_TRUE_WAIT(async_invoked.Get(), 2000);
}
};
- bool thread_a_called = false;
+ LockedBool thread_a_called(false);
// Start the sequence A --(invoke)--> B --(async invoke)--> C --(invoke)--> A.
// Thread B returns when C receives the call and C should be blocked until A
// starts to process messages.
thread_b.Invoke<void>(Bind(&LocalFuncs::AsyncInvokeSetAndWait,
&thread_c, thread_a, &thread_a_called));
- EXPECT_FALSE(thread_a_called);
+ EXPECT_FALSE(thread_a_called.Get());
- EXPECT_TRUE_WAIT(thread_a_called, 2000);
+ EXPECT_TRUE_WAIT(thread_a_called.Get(), 2000);
}
class AsyncInvokeTest : public testing::Test {