Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1283)

Side by Side Diff: webrtc/base/sharedexclusivelock_unittest.cc

Issue 2393023002: Fixed flaky SharedExclusiveLock tests. (Closed)
Patch Set: Removed a temporary build workaround Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2011 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include <memory> 11 #include <memory>
12 12
13 #include "webrtc/base/common.h" 13 #include "webrtc/base/common.h"
14 #include "webrtc/base/gunit.h" 14 #include "webrtc/base/gunit.h"
15 #include "webrtc/base/event.h"
15 #include "webrtc/base/messagehandler.h" 16 #include "webrtc/base/messagehandler.h"
16 #include "webrtc/base/messagequeue.h" 17 #include "webrtc/base/messagequeue.h"
17 #include "webrtc/base/sharedexclusivelock.h" 18 #include "webrtc/base/sharedexclusivelock.h"
18 #include "webrtc/base/thread.h" 19 #include "webrtc/base/thread.h"
19 #include "webrtc/base/timeutils.h" 20 #include "webrtc/base/timeutils.h"
20 21
21 #if defined(MEMORY_SANITIZER)
22 // Flaky under MemorySanitizer, see
23 // https://bugs.chromium.org/p/webrtc/issues/detail?id=5824
24 #define MAYBE_TestSharedExclusive DISABLED_TestSharedExclusive
25 #define MAYBE_TestExclusiveExclusive DISABLED_TestExclusiveExclusive
26 #else
27 #define MAYBE_TestSharedExclusive TestSharedExclusive
28 #define MAYBE_TestExclusiveExclusive TestExclusiveExclusive
29 #endif
30
31 namespace rtc { 22 namespace rtc {
32 23
33 static const uint32_t kMsgRead = 0; 24 static const uint32_t kMsgRead = 0;
34 static const uint32_t kMsgWrite = 0; 25 static const uint32_t kMsgWrite = 0;
35 static const int kNoWaitThresholdInMs = 10; 26 static const int kNoWaitThresholdInMs = 10;
36 static const int kWaitThresholdInMs = 80; 27 static const int kWaitThresholdInMs = 80;
37 static const int kProcessTimeInMs = 100; 28 static const int kProcessTimeInMs = 100;
38 static const int kProcessTimeoutInMs = 5000; 29 static const int kProcessTimeoutInMs = 5000;
39 30
40 class SharedExclusiveTask : public MessageHandler { 31 class SharedExclusiveTask : public MessageHandler {
41 public: 32 public:
42 SharedExclusiveTask(SharedExclusiveLock* shared_exclusive_lock, 33 SharedExclusiveTask(SharedExclusiveLock* shared_exclusive_lock,
43 int* value, 34 int* value,
44 bool* done) 35 Event* done)
45 : shared_exclusive_lock_(shared_exclusive_lock), 36 : shared_exclusive_lock_(shared_exclusive_lock),
46 waiting_time_in_ms_(0),
47 value_(value), 37 value_(value),
48 done_(done) { 38 done_(done) {
49 worker_thread_.reset(new Thread()); 39 worker_thread_.reset(new Thread());
50 worker_thread_->Start(); 40 worker_thread_->Start();
51 } 41 }
52 42
53 int64_t waiting_time_in_ms() const { return waiting_time_in_ms_; }
54
55 protected: 43 protected:
56 std::unique_ptr<Thread> worker_thread_; 44 std::unique_ptr<Thread> worker_thread_;
57 SharedExclusiveLock* shared_exclusive_lock_; 45 SharedExclusiveLock* shared_exclusive_lock_;
58 int64_t waiting_time_in_ms_;
59 int* value_; 46 int* value_;
60 bool* done_; 47 Event* done_;
61 }; 48 };
62 49
63 class ReadTask : public SharedExclusiveTask { 50 class ReadTask : public SharedExclusiveTask {
64 public: 51 public:
65 ReadTask(SharedExclusiveLock* shared_exclusive_lock, int* value, bool* done) 52 ReadTask(SharedExclusiveLock* shared_exclusive_lock, int* value, Event* done)
66 : SharedExclusiveTask(shared_exclusive_lock, value, done) { 53 : SharedExclusiveTask(shared_exclusive_lock, value, done) {
67 } 54 }
68 55
69 void PostRead(int* value) { 56 void PostRead(int* value) {
70 worker_thread_->Post(RTC_FROM_HERE, this, kMsgRead, 57 worker_thread_->Post(RTC_FROM_HERE, this, kMsgRead,
71 new TypedMessageData<int*>(value)); 58 new TypedMessageData<int*>(value));
72 } 59 }
73 60
74 private: 61 private:
75 virtual void OnMessage(Message* message) { 62 virtual void OnMessage(Message* message) {
76 ASSERT(rtc::Thread::Current() == worker_thread_.get()); 63 ASSERT(rtc::Thread::Current() == worker_thread_.get());
77 ASSERT(message != NULL); 64 ASSERT(message != NULL);
78 ASSERT(message->message_id == kMsgRead); 65 ASSERT(message->message_id == kMsgRead);
79 66
80 TypedMessageData<int*>* message_data = 67 TypedMessageData<int*>* message_data =
81 static_cast<TypedMessageData<int*>*>(message->pdata); 68 static_cast<TypedMessageData<int*>*>(message->pdata);
82 69
83 int64_t start_time = TimeMillis();
84 { 70 {
85 SharedScope ss(shared_exclusive_lock_); 71 SharedScope ss(shared_exclusive_lock_);
86 waiting_time_in_ms_ = TimeDiff(TimeMillis(), start_time);
87
88 Thread::SleepMs(kProcessTimeInMs);
89 *message_data->data() = *value_; 72 *message_data->data() = *value_;
90 *done_ = true; 73 done_->Set();
91 } 74 }
92 delete message->pdata; 75 delete message->pdata;
93 message->pdata = NULL; 76 message->pdata = NULL;
94 } 77 }
95 }; 78 };
96 79
97 class WriteTask : public SharedExclusiveTask { 80 class WriteTask : public SharedExclusiveTask {
98 public: 81 public:
99 WriteTask(SharedExclusiveLock* shared_exclusive_lock, int* value, bool* done) 82 WriteTask(SharedExclusiveLock* shared_exclusive_lock, int* value, Event* done)
100 : SharedExclusiveTask(shared_exclusive_lock, value, done) { 83 : SharedExclusiveTask(shared_exclusive_lock, value, done) {
101 } 84 }
102 85
103 void PostWrite(int value) { 86 void PostWrite(int value) {
104 worker_thread_->Post(RTC_FROM_HERE, this, kMsgWrite, 87 worker_thread_->Post(RTC_FROM_HERE, this, kMsgWrite,
105 new TypedMessageData<int>(value)); 88 new TypedMessageData<int>(value));
106 } 89 }
107 90
108 private: 91 private:
109 virtual void OnMessage(Message* message) { 92 virtual void OnMessage(Message* message) {
110 ASSERT(rtc::Thread::Current() == worker_thread_.get()); 93 ASSERT(rtc::Thread::Current() == worker_thread_.get());
111 ASSERT(message != NULL); 94 ASSERT(message != NULL);
112 ASSERT(message->message_id == kMsgWrite); 95 ASSERT(message->message_id == kMsgWrite);
113 96
114 TypedMessageData<int>* message_data = 97 TypedMessageData<int>* message_data =
115 static_cast<TypedMessageData<int>*>(message->pdata); 98 static_cast<TypedMessageData<int>*>(message->pdata);
116 99
117 int64_t start_time = TimeMillis();
118 { 100 {
119 ExclusiveScope es(shared_exclusive_lock_); 101 ExclusiveScope es(shared_exclusive_lock_);
120 waiting_time_in_ms_ = TimeDiff(TimeMillis(), start_time);
121
122 Thread::SleepMs(kProcessTimeInMs);
123 *value_ = message_data->data(); 102 *value_ = message_data->data();
124 *done_ = true; 103 done_->Set();
125 } 104 }
126 delete message->pdata; 105 delete message->pdata;
127 message->pdata = NULL; 106 message->pdata = NULL;
128 } 107 }
129 }; 108 };
130 109
131 // Unit test for SharedExclusiveLock. 110 // Unit test for SharedExclusiveLock.
132 class SharedExclusiveLockTest 111 class SharedExclusiveLockTest
133 : public testing::Test { 112 : public testing::Test {
134 public: 113 public:
135 SharedExclusiveLockTest() : value_(0) { 114 SharedExclusiveLockTest() : value_(0) {
136 } 115 }
137 116
138 virtual void SetUp() { 117 virtual void SetUp() {
139 shared_exclusive_lock_.reset(new SharedExclusiveLock()); 118 shared_exclusive_lock_.reset(new SharedExclusiveLock());
140 } 119 }
141 120
142 protected: 121 protected:
143 std::unique_ptr<SharedExclusiveLock> shared_exclusive_lock_; 122 std::unique_ptr<SharedExclusiveLock> shared_exclusive_lock_;
144 int value_; 123 int value_;
145 }; 124 };
146 125
147 // Flaky: https://code.google.com/p/webrtc/issues/detail?id=3318
148 TEST_F(SharedExclusiveLockTest, TestSharedShared) { 126 TEST_F(SharedExclusiveLockTest, TestSharedShared) {
149 int value0, value1; 127 int value0, value1;
150 bool done0, done1; 128 Event done0(false, false), done1(false, false);
151 ReadTask reader0(shared_exclusive_lock_.get(), &value_, &done0); 129 ReadTask reader0(shared_exclusive_lock_.get(), &value_, &done0);
152 ReadTask reader1(shared_exclusive_lock_.get(), &value_, &done1); 130 ReadTask reader1(shared_exclusive_lock_.get(), &value_, &done1);
153 131
154 // Test shared locks can be shared without waiting. 132 // Test shared locks can be shared without waiting.
155 { 133 {
156 SharedScope ss(shared_exclusive_lock_.get()); 134 SharedScope ss(shared_exclusive_lock_.get());
157 value_ = 1; 135 value_ = 1;
158 done0 = false;
159 done1 = false;
160 reader0.PostRead(&value0); 136 reader0.PostRead(&value0);
161 reader1.PostRead(&value1); 137 reader1.PostRead(&value1);
162 Thread::SleepMs(kProcessTimeInMs); 138
139 EXPECT_TRUE(done0.Wait(kProcessTimeoutInMs));
140 EXPECT_TRUE(done1.Wait(kProcessTimeoutInMs));
141 EXPECT_EQ(1, value0);
142 EXPECT_EQ(1, value1);
163 } 143 }
164
165 EXPECT_TRUE_WAIT(done0, kProcessTimeoutInMs);
166 EXPECT_EQ(1, value0);
167 EXPECT_LE(reader0.waiting_time_in_ms(), kNoWaitThresholdInMs);
168 EXPECT_TRUE_WAIT(done1, kProcessTimeoutInMs);
169 EXPECT_EQ(1, value1);
170 EXPECT_LE(reader1.waiting_time_in_ms(), kNoWaitThresholdInMs);
171 } 144 }
172 145
173 TEST_F(SharedExclusiveLockTest, MAYBE_TestSharedExclusive) { 146 TEST_F(SharedExclusiveLockTest, TestSharedExclusive) {
174 bool done; 147 Event done(false, false);
175 WriteTask writer(shared_exclusive_lock_.get(), &value_, &done); 148 WriteTask writer(shared_exclusive_lock_.get(), &value_, &done);
176 149
177 // Test exclusive lock needs to wait for shared lock. 150 // Test exclusive lock needs to wait for shared lock.
178 { 151 {
179 SharedScope ss(shared_exclusive_lock_.get()); 152 SharedScope ss(shared_exclusive_lock_.get());
180 value_ = 1; 153 value_ = 1;
181 done = false;
182 writer.PostWrite(2); 154 writer.PostWrite(2);
183 Thread::SleepMs(kProcessTimeInMs); 155 EXPECT_FALSE(done.Wait(kProcessTimeInMs));
184 EXPECT_EQ(1, value_);
185 } 156 }
186 157 EXPECT_TRUE(done.Wait(kProcessTimeoutInMs));
187 EXPECT_TRUE_WAIT(done, kProcessTimeoutInMs);
188 EXPECT_EQ(2, value_); 158 EXPECT_EQ(2, value_);
189 EXPECT_GE(writer.waiting_time_in_ms(), kWaitThresholdInMs);
190 } 159 }
191 160
192 TEST_F(SharedExclusiveLockTest, TestExclusiveShared) { 161 TEST_F(SharedExclusiveLockTest, TestExclusiveShared) {
193 int value; 162 int value;
194 bool done; 163 Event done(false, false);
195 ReadTask reader(shared_exclusive_lock_.get(), &value_, &done); 164 ReadTask reader(shared_exclusive_lock_.get(), &value_, &done);
196 165
197 // Test shared lock needs to wait for exclusive lock. 166 // Test shared lock needs to wait for exclusive lock.
198 { 167 {
199 ExclusiveScope es(shared_exclusive_lock_.get()); 168 ExclusiveScope es(shared_exclusive_lock_.get());
200 value_ = 1; 169 value_ = 1;
201 done = false;
202 reader.PostRead(&value); 170 reader.PostRead(&value);
203 Thread::SleepMs(kProcessTimeInMs); 171 EXPECT_FALSE(done.Wait(kProcessTimeInMs));
204 value_ = 2; 172 value_ = 2;
205 } 173 }
206 174
207 EXPECT_TRUE_WAIT(done, kProcessTimeoutInMs); 175 EXPECT_TRUE(done.Wait(kProcessTimeoutInMs));
208 EXPECT_EQ(2, value); 176 EXPECT_EQ(2, value);
209 EXPECT_GE(reader.waiting_time_in_ms(), kWaitThresholdInMs);
210 } 177 }
211 178
212 TEST_F(SharedExclusiveLockTest, MAYBE_TestExclusiveExclusive) { 179 TEST_F(SharedExclusiveLockTest, TestExclusiveExclusive) {
213 bool done; 180 Event done(false, false);
214 WriteTask writer(shared_exclusive_lock_.get(), &value_, &done); 181 WriteTask writer(shared_exclusive_lock_.get(), &value_, &done);
215 182
216 // Test exclusive lock needs to wait for exclusive lock. 183 // Test exclusive lock needs to wait for exclusive lock.
217 { 184 {
218 ExclusiveScope es(shared_exclusive_lock_.get()); 185 ExclusiveScope es(shared_exclusive_lock_.get());
186 // Start the writer task only after holding the lock, to ensure it need
219 value_ = 1; 187 value_ = 1;
220 done = false;
221 writer.PostWrite(2); 188 writer.PostWrite(2);
222 Thread::SleepMs(kProcessTimeInMs); 189 EXPECT_FALSE(done.Wait(kProcessTimeInMs));
223 EXPECT_EQ(1, value_); 190 EXPECT_EQ(1, value_);
224 } 191 }
225 192
226 EXPECT_TRUE_WAIT(done, kProcessTimeoutInMs); 193 EXPECT_TRUE(done.Wait(kProcessTimeoutInMs));
227 EXPECT_EQ(2, value_); 194 EXPECT_EQ(2, value_);
228 EXPECT_GE(writer.waiting_time_in_ms(), kWaitThresholdInMs);
229 } 195 }
230 196
231 } // namespace rtc 197 } // namespace rtc
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698