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

Side by Side Diff: mojo/system/waiter_list_unittest.cc

Issue 23621056: Initial in-process implementation of some Mojo primitives. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: build fix Created 7 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // NOTE(vtl): These tests are inherently flaky (e.g., if run on a heavily-loaded
6 // system). Sorry. |kEpsilonMicros| may be increased to increase tolerance and
7 // reduce observed flakiness.
8
9 #include "mojo/system/waiter_list.h"
10
11 #include "base/threading/platform_thread.h" // For |Sleep()|.
12 #include "base/time/time.h"
13 #include "mojo/system/waiter.h"
14 #include "mojo/system/waiter_test_utils.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace mojo {
18 namespace system {
19 namespace {
20
21 const int64_t kMicrosPerMs = 1000;
22 const int64_t kEpsilonMicros = 15 * kMicrosPerMs; // 15 ms.
23
24 TEST(WaiterListTest, BasicCancel) {
25 MojoResult result;
26
27 // Cancel immediately after thread start.
28 {
29 WaiterList waiter_list;
30 test::SimpleWaiterThread thread(&result);
31 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 0);
32 thread.Start();
33 waiter_list.CancelAllWaiters();
34 waiter_list.RemoveWaiter(thread.waiter()); // Double-remove okay.
35 } // Join |thread|.
36 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
37
38 // Cancel before after thread start.
39 {
40 WaiterList waiter_list;
41 test::SimpleWaiterThread thread(&result);
42 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_WRITABLE, 1);
43 waiter_list.CancelAllWaiters();
44 thread.Start();
45 } // Join |thread|.
46 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
47
48 // Cancel some time after thread start.
49 {
50 WaiterList waiter_list;
51 test::SimpleWaiterThread thread(&result);
52 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 2);
53 thread.Start();
54 base::PlatformThread::Sleep(
55 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
56 waiter_list.CancelAllWaiters();
57 } // Join |thread|.
58 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
59 }
60
61 TEST(WaiterListTest, BasicAwakeSatisfied) {
62 MojoResult result;
63
64 // Awake immediately after thread start.
65 {
66 WaiterList waiter_list;
67 test::SimpleWaiterThread thread(&result);
68 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 0);
69 thread.Start();
70 waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE,
71 MOJO_WAIT_FLAG_READABLE |
72 MOJO_WAIT_FLAG_WRITABLE);
73 waiter_list.RemoveWaiter(thread.waiter());
74 } // Join |thread|.
75 EXPECT_EQ(0, result);
76
77 // Awake before after thread start.
78 {
79 WaiterList waiter_list;
80 test::SimpleWaiterThread thread(&result);
81 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_WRITABLE, 1);
82 waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_WRITABLE,
83 MOJO_WAIT_FLAG_READABLE |
84 MOJO_WAIT_FLAG_WRITABLE);
85 waiter_list.RemoveWaiter(thread.waiter());
86 waiter_list.RemoveWaiter(thread.waiter()); // Double-remove okay.
87 thread.Start();
88 } // Join |thread|.
89 EXPECT_EQ(1, result);
90
91 // Awake some time after thread start.
92 {
93 WaiterList waiter_list;
94 test::SimpleWaiterThread thread(&result);
95 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 2);
96 thread.Start();
97 base::PlatformThread::Sleep(
98 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
99 waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE,
100 MOJO_WAIT_FLAG_READABLE |
101 MOJO_WAIT_FLAG_WRITABLE);
102 waiter_list.RemoveWaiter(thread.waiter());
103 } // Join |thread|.
104 EXPECT_EQ(2, result);
105 }
106
107 TEST(WaiterListTest, BasicAwakeUnsatisfiable) {
108 MojoResult result;
109
110 // Awake (for unsatisfiability) immediately after thread start.
111 {
112 WaiterList waiter_list;
113 test::SimpleWaiterThread thread(&result);
114 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 0);
115 thread.Start();
116 waiter_list.AwakeWaitersForStateChange(0, MOJO_WAIT_FLAG_WRITABLE);
117 waiter_list.RemoveWaiter(thread.waiter());
118 } // Join |thread|.
119 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
120
121 // Awake (for unsatisfiability) before after thread start.
122 {
123 WaiterList waiter_list;
124 test::SimpleWaiterThread thread(&result);
125 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_WRITABLE, 1);
126 waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE,
127 MOJO_WAIT_FLAG_READABLE);
128 waiter_list.RemoveWaiter(thread.waiter());
129 thread.Start();
130 } // Join |thread|.
131 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
132
133 // Awake (for unsatisfiability) some time after thread start.
134 {
135 WaiterList waiter_list;
136 test::SimpleWaiterThread thread(&result);
137 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 2);
138 thread.Start();
139 base::PlatformThread::Sleep(
140 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
141 waiter_list.AwakeWaitersForStateChange(0, MOJO_WAIT_FLAG_WRITABLE);
142 waiter_list.RemoveWaiter(thread.waiter());
143 waiter_list.RemoveWaiter(thread.waiter()); // Double-remove okay.
144 } // Join |thread|.
145 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
146 }
147
148 TEST(WaiterListTest, MultipleWaiters) {
149 MojoResult result_1;
150 MojoResult result_2;
151 MojoResult result_3;
152 MojoResult result_4;
153
154 // Cancel two waiters.
155 {
156 WaiterList waiter_list;
157 test::SimpleWaiterThread thread_1(&result_1);
158 waiter_list.AddWaiter(thread_1.waiter(), MOJO_WAIT_FLAG_READABLE, 0);
159 thread_1.Start();
160 test::SimpleWaiterThread thread_2(&result_2);
161 waiter_list.AddWaiter(thread_2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 1);
162 thread_2.Start();
163 base::PlatformThread::Sleep(
164 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
165 waiter_list.CancelAllWaiters();
166 } // Join threads.
167 EXPECT_EQ(MOJO_RESULT_CANCELLED, result_1);
168 EXPECT_EQ(MOJO_RESULT_CANCELLED, result_2);
169
170 // Awake one waiter, cancel other.
171 {
172 WaiterList waiter_list;
173 test::SimpleWaiterThread thread_1(&result_1);
174 waiter_list.AddWaiter(thread_1.waiter(), MOJO_WAIT_FLAG_READABLE, 2);
175 thread_1.Start();
176 test::SimpleWaiterThread thread_2(&result_2);
177 waiter_list.AddWaiter(thread_2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 3);
178 thread_2.Start();
179 base::PlatformThread::Sleep(
180 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
181 waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE,
182 MOJO_WAIT_FLAG_READABLE |
183 MOJO_WAIT_FLAG_WRITABLE);
184 waiter_list.RemoveWaiter(thread_1.waiter());
185 waiter_list.CancelAllWaiters();
186 } // Join threads.
187 EXPECT_EQ(2, result_1);
188 EXPECT_EQ(MOJO_RESULT_CANCELLED, result_2);
189
190 // Cancel one waiter, awake other for unsatisfiability.
191 {
192 WaiterList waiter_list;
193 test::SimpleWaiterThread thread_1(&result_1);
194 waiter_list.AddWaiter(thread_1.waiter(), MOJO_WAIT_FLAG_READABLE, 4);
195 thread_1.Start();
196 test::SimpleWaiterThread thread_2(&result_2);
197 waiter_list.AddWaiter(thread_2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 5);
198 thread_2.Start();
199 base::PlatformThread::Sleep(
200 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
201 waiter_list.AwakeWaitersForStateChange(0, MOJO_WAIT_FLAG_READABLE);
202 waiter_list.RemoveWaiter(thread_2.waiter());
203 waiter_list.CancelAllWaiters();
204 } // Join threads.
205 EXPECT_EQ(MOJO_RESULT_CANCELLED, result_1);
206 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result_2);
207
208 // Cancel one waiter, awake other for unsatisfiability.
209 {
210 WaiterList waiter_list;
211 test::SimpleWaiterThread thread_1(&result_1);
212 waiter_list.AddWaiter(thread_1.waiter(), MOJO_WAIT_FLAG_READABLE, 6);
213 thread_1.Start();
214
215 base::PlatformThread::Sleep(
216 base::TimeDelta::FromMicroseconds(1 * kEpsilonMicros));
217
218 // Should do nothing.
219 waiter_list.AwakeWaitersForStateChange(0,
220 MOJO_WAIT_FLAG_READABLE |
221 MOJO_WAIT_FLAG_WRITABLE);
222
223 test::SimpleWaiterThread thread_2(&result_2);
224 waiter_list.AddWaiter(thread_2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 7);
225 thread_2.Start();
226
227 base::PlatformThread::Sleep(
228 base::TimeDelta::FromMicroseconds(1 * kEpsilonMicros));
229
230 // Awake #1.
231 waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE,
232 MOJO_WAIT_FLAG_READABLE |
233 MOJO_WAIT_FLAG_WRITABLE);
234 waiter_list.RemoveWaiter(thread_1.waiter());
235
236 base::PlatformThread::Sleep(
237 base::TimeDelta::FromMicroseconds(1 * kEpsilonMicros));
238
239 test::SimpleWaiterThread thread_3(&result_3);
240 waiter_list.AddWaiter(thread_3.waiter(), MOJO_WAIT_FLAG_WRITABLE, 8);
241 thread_3.Start();
242
243 test::SimpleWaiterThread thread_4(&result_4);
244 waiter_list.AddWaiter(thread_4.waiter(), MOJO_WAIT_FLAG_READABLE, 9);
245 thread_4.Start();
246
247 base::PlatformThread::Sleep(
248 base::TimeDelta::FromMicroseconds(1 * kEpsilonMicros));
249
250 // Awake #2 and #3 for unsatisfiability.
251 waiter_list.AwakeWaitersForStateChange(0, MOJO_WAIT_FLAG_READABLE);
252 waiter_list.RemoveWaiter(thread_2.waiter());
253 waiter_list.RemoveWaiter(thread_3.waiter());
254
255 // Cancel #4.
256 waiter_list.CancelAllWaiters();
257 } // Join threads.
258 EXPECT_EQ(6, result_1);
259 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result_2);
260 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result_3);
261 EXPECT_EQ(MOJO_RESULT_CANCELLED, result_4);
262 }
263
264 } // namespace
265 } // namespace system
266 } // namespace mojo
OLDNEW
« mojo/mojo.gyp ('K') | « mojo/system/waiter_list.cc ('k') | mojo/system/waiter_test_utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698