OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // NOTE(vtl): Some of these tests are inherently flaky (e.g., if run on a | 5 // NOTE(vtl): Some of these tests are inherently flaky (e.g., if run on a |
6 // heavily-loaded system). Sorry. |test::EpsilonTimeout()| may be increased to | 6 // heavily-loaded system). Sorry. |test::EpsilonTimeout()| may be increased to |
7 // increase tolerance and reduce observed flakiness (though doing so reduces the | 7 // increase tolerance and reduce observed flakiness (though doing so reduces the |
8 // meaningfulness of the test). | 8 // meaningfulness of the test). |
9 | 9 |
10 #include "mojo/system/waiter_list.h" | 10 #include "mojo/system/waiter_list.h" |
11 | 11 |
12 #include "base/threading/platform_thread.h" // For |Sleep()|. | 12 #include "base/threading/platform_thread.h" // For |Sleep()|. |
13 #include "base/time/time.h" | 13 #include "base/time/time.h" |
14 #include "mojo/system/test_utils.h" | 14 #include "mojo/system/test_utils.h" |
| 15 #include "mojo/system/wait_flags_state.h" |
15 #include "mojo/system/waiter.h" | 16 #include "mojo/system/waiter.h" |
16 #include "mojo/system/waiter_test_utils.h" | 17 #include "mojo/system/waiter_test_utils.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
18 | 19 |
19 namespace mojo { | 20 namespace mojo { |
20 namespace system { | 21 namespace system { |
21 namespace { | 22 namespace { |
22 | 23 |
23 TEST(WaiterListTest, BasicCancel) { | 24 TEST(WaiterListTest, BasicCancel) { |
24 MojoResult result; | 25 MojoResult result; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 | 59 |
59 TEST(WaiterListTest, BasicAwakeSatisfied) { | 60 TEST(WaiterListTest, BasicAwakeSatisfied) { |
60 MojoResult result; | 61 MojoResult result; |
61 | 62 |
62 // Awake immediately after thread start. | 63 // Awake immediately after thread start. |
63 { | 64 { |
64 WaiterList waiter_list; | 65 WaiterList waiter_list; |
65 test::SimpleWaiterThread thread(&result); | 66 test::SimpleWaiterThread thread(&result); |
66 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 0); | 67 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 0); |
67 thread.Start(); | 68 thread.Start(); |
68 waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE, | 69 waiter_list.AwakeWaitersForStateChange( |
69 MOJO_WAIT_FLAG_READABLE | | 70 WaitFlagsState(MOJO_WAIT_FLAG_READABLE, |
70 MOJO_WAIT_FLAG_WRITABLE); | 71 MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE)); |
71 waiter_list.RemoveWaiter(thread.waiter()); | 72 waiter_list.RemoveWaiter(thread.waiter()); |
72 } // Join |thread|. | 73 } // Join |thread|. |
73 EXPECT_EQ(0, result); | 74 EXPECT_EQ(0, result); |
74 | 75 |
75 // Awake before after thread start. | 76 // Awake before after thread start. |
76 { | 77 { |
77 WaiterList waiter_list; | 78 WaiterList waiter_list; |
78 test::SimpleWaiterThread thread(&result); | 79 test::SimpleWaiterThread thread(&result); |
79 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_WRITABLE, 1); | 80 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_WRITABLE, 1); |
80 waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_WRITABLE, | 81 waiter_list.AwakeWaitersForStateChange( |
81 MOJO_WAIT_FLAG_READABLE | | 82 WaitFlagsState(MOJO_WAIT_FLAG_WRITABLE, |
82 MOJO_WAIT_FLAG_WRITABLE); | 83 MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE)); |
83 waiter_list.RemoveWaiter(thread.waiter()); | 84 waiter_list.RemoveWaiter(thread.waiter()); |
84 waiter_list.RemoveWaiter(thread.waiter()); // Double-remove okay. | 85 waiter_list.RemoveWaiter(thread.waiter()); // Double-remove okay. |
85 thread.Start(); | 86 thread.Start(); |
86 } // Join |thread|. | 87 } // Join |thread|. |
87 EXPECT_EQ(1, result); | 88 EXPECT_EQ(1, result); |
88 | 89 |
89 // Awake some time after thread start. | 90 // Awake some time after thread start. |
90 { | 91 { |
91 WaiterList waiter_list; | 92 WaiterList waiter_list; |
92 test::SimpleWaiterThread thread(&result); | 93 test::SimpleWaiterThread thread(&result); |
93 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 2); | 94 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 2); |
94 thread.Start(); | 95 thread.Start(); |
95 base::PlatformThread::Sleep(2 * test::EpsilonTimeout()); | 96 base::PlatformThread::Sleep(2 * test::EpsilonTimeout()); |
96 waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE, | 97 waiter_list.AwakeWaitersForStateChange( |
97 MOJO_WAIT_FLAG_READABLE | | 98 WaitFlagsState(MOJO_WAIT_FLAG_READABLE, |
98 MOJO_WAIT_FLAG_WRITABLE); | 99 MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE)); |
99 waiter_list.RemoveWaiter(thread.waiter()); | 100 waiter_list.RemoveWaiter(thread.waiter()); |
100 } // Join |thread|. | 101 } // Join |thread|. |
101 EXPECT_EQ(2, result); | 102 EXPECT_EQ(2, result); |
102 } | 103 } |
103 | 104 |
104 TEST(WaiterListTest, BasicAwakeUnsatisfiable) { | 105 TEST(WaiterListTest, BasicAwakeUnsatisfiable) { |
105 MojoResult result; | 106 MojoResult result; |
106 | 107 |
107 // Awake (for unsatisfiability) immediately after thread start. | 108 // Awake (for unsatisfiability) immediately after thread start. |
108 { | 109 { |
109 WaiterList waiter_list; | 110 WaiterList waiter_list; |
110 test::SimpleWaiterThread thread(&result); | 111 test::SimpleWaiterThread thread(&result); |
111 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 0); | 112 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 0); |
112 thread.Start(); | 113 thread.Start(); |
113 waiter_list.AwakeWaitersForStateChange(0, MOJO_WAIT_FLAG_WRITABLE); | 114 waiter_list.AwakeWaitersForStateChange( |
| 115 WaitFlagsState(MOJO_WAIT_FLAG_NONE, MOJO_WAIT_FLAG_WRITABLE)); |
114 waiter_list.RemoveWaiter(thread.waiter()); | 116 waiter_list.RemoveWaiter(thread.waiter()); |
115 } // Join |thread|. | 117 } // Join |thread|. |
116 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); | 118 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); |
117 | 119 |
118 // Awake (for unsatisfiability) before after thread start. | 120 // Awake (for unsatisfiability) before after thread start. |
119 { | 121 { |
120 WaiterList waiter_list; | 122 WaiterList waiter_list; |
121 test::SimpleWaiterThread thread(&result); | 123 test::SimpleWaiterThread thread(&result); |
122 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_WRITABLE, 1); | 124 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_WRITABLE, 1); |
123 waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE, | 125 waiter_list.AwakeWaitersForStateChange( |
124 MOJO_WAIT_FLAG_READABLE); | 126 WaitFlagsState(MOJO_WAIT_FLAG_READABLE, MOJO_WAIT_FLAG_READABLE)); |
125 waiter_list.RemoveWaiter(thread.waiter()); | 127 waiter_list.RemoveWaiter(thread.waiter()); |
126 thread.Start(); | 128 thread.Start(); |
127 } // Join |thread|. | 129 } // Join |thread|. |
128 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); | 130 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); |
129 | 131 |
130 // Awake (for unsatisfiability) some time after thread start. | 132 // Awake (for unsatisfiability) some time after thread start. |
131 { | 133 { |
132 WaiterList waiter_list; | 134 WaiterList waiter_list; |
133 test::SimpleWaiterThread thread(&result); | 135 test::SimpleWaiterThread thread(&result); |
134 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 2); | 136 waiter_list.AddWaiter(thread.waiter(), MOJO_WAIT_FLAG_READABLE, 2); |
135 thread.Start(); | 137 thread.Start(); |
136 base::PlatformThread::Sleep(2 * test::EpsilonTimeout()); | 138 base::PlatformThread::Sleep(2 * test::EpsilonTimeout()); |
137 waiter_list.AwakeWaitersForStateChange(0, MOJO_WAIT_FLAG_WRITABLE); | 139 waiter_list.AwakeWaitersForStateChange( |
| 140 WaitFlagsState(MOJO_WAIT_FLAG_NONE, MOJO_WAIT_FLAG_WRITABLE)); |
138 waiter_list.RemoveWaiter(thread.waiter()); | 141 waiter_list.RemoveWaiter(thread.waiter()); |
139 waiter_list.RemoveWaiter(thread.waiter()); // Double-remove okay. | 142 waiter_list.RemoveWaiter(thread.waiter()); // Double-remove okay. |
140 } // Join |thread|. | 143 } // Join |thread|. |
141 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); | 144 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); |
142 } | 145 } |
143 | 146 |
144 TEST(WaiterListTest, MultipleWaiters) { | 147 TEST(WaiterListTest, MultipleWaiters) { |
145 MojoResult result1; | 148 MojoResult result1; |
146 MojoResult result2; | 149 MojoResult result2; |
147 MojoResult result3; | 150 MojoResult result3; |
(...skipping 17 matching lines...) Expand all Loading... |
165 // Awake one waiter, cancel other. | 168 // Awake one waiter, cancel other. |
166 { | 169 { |
167 WaiterList waiter_list; | 170 WaiterList waiter_list; |
168 test::SimpleWaiterThread thread1(&result1); | 171 test::SimpleWaiterThread thread1(&result1); |
169 waiter_list.AddWaiter(thread1.waiter(), MOJO_WAIT_FLAG_READABLE, 2); | 172 waiter_list.AddWaiter(thread1.waiter(), MOJO_WAIT_FLAG_READABLE, 2); |
170 thread1.Start(); | 173 thread1.Start(); |
171 test::SimpleWaiterThread thread2(&result2); | 174 test::SimpleWaiterThread thread2(&result2); |
172 waiter_list.AddWaiter(thread2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 3); | 175 waiter_list.AddWaiter(thread2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 3); |
173 thread2.Start(); | 176 thread2.Start(); |
174 base::PlatformThread::Sleep(2 * test::EpsilonTimeout()); | 177 base::PlatformThread::Sleep(2 * test::EpsilonTimeout()); |
175 waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE, | 178 waiter_list.AwakeWaitersForStateChange( |
176 MOJO_WAIT_FLAG_READABLE | | 179 WaitFlagsState(MOJO_WAIT_FLAG_READABLE, |
177 MOJO_WAIT_FLAG_WRITABLE); | 180 MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE)); |
178 waiter_list.RemoveWaiter(thread1.waiter()); | 181 waiter_list.RemoveWaiter(thread1.waiter()); |
179 waiter_list.CancelAllWaiters(); | 182 waiter_list.CancelAllWaiters(); |
180 } // Join threads. | 183 } // Join threads. |
181 EXPECT_EQ(2, result1); | 184 EXPECT_EQ(2, result1); |
182 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2); | 185 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2); |
183 | 186 |
184 // Cancel one waiter, awake other for unsatisfiability. | 187 // Cancel one waiter, awake other for unsatisfiability. |
185 { | 188 { |
186 WaiterList waiter_list; | 189 WaiterList waiter_list; |
187 test::SimpleWaiterThread thread1(&result1); | 190 test::SimpleWaiterThread thread1(&result1); |
188 waiter_list.AddWaiter(thread1.waiter(), MOJO_WAIT_FLAG_READABLE, 4); | 191 waiter_list.AddWaiter(thread1.waiter(), MOJO_WAIT_FLAG_READABLE, 4); |
189 thread1.Start(); | 192 thread1.Start(); |
190 test::SimpleWaiterThread thread2(&result2); | 193 test::SimpleWaiterThread thread2(&result2); |
191 waiter_list.AddWaiter(thread2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 5); | 194 waiter_list.AddWaiter(thread2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 5); |
192 thread2.Start(); | 195 thread2.Start(); |
193 base::PlatformThread::Sleep(2 * test::EpsilonTimeout()); | 196 base::PlatformThread::Sleep(2 * test::EpsilonTimeout()); |
194 waiter_list.AwakeWaitersForStateChange(0, MOJO_WAIT_FLAG_READABLE); | 197 waiter_list.AwakeWaitersForStateChange( |
| 198 WaitFlagsState(MOJO_WAIT_FLAG_NONE, MOJO_WAIT_FLAG_READABLE)); |
195 waiter_list.RemoveWaiter(thread2.waiter()); | 199 waiter_list.RemoveWaiter(thread2.waiter()); |
196 waiter_list.CancelAllWaiters(); | 200 waiter_list.CancelAllWaiters(); |
197 } // Join threads. | 201 } // Join threads. |
198 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1); | 202 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1); |
199 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2); | 203 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2); |
200 | 204 |
201 // Cancel one waiter, awake other for unsatisfiability. | 205 // Cancel one waiter, awake other for unsatisfiability. |
202 { | 206 { |
203 WaiterList waiter_list; | 207 WaiterList waiter_list; |
204 test::SimpleWaiterThread thread1(&result1); | 208 test::SimpleWaiterThread thread1(&result1); |
205 waiter_list.AddWaiter(thread1.waiter(), MOJO_WAIT_FLAG_READABLE, 6); | 209 waiter_list.AddWaiter(thread1.waiter(), MOJO_WAIT_FLAG_READABLE, 6); |
206 thread1.Start(); | 210 thread1.Start(); |
207 | 211 |
208 base::PlatformThread::Sleep(1 * test::EpsilonTimeout()); | 212 base::PlatformThread::Sleep(1 * test::EpsilonTimeout()); |
209 | 213 |
210 // Should do nothing. | 214 // Should do nothing. |
211 waiter_list.AwakeWaitersForStateChange(0, | 215 waiter_list.AwakeWaitersForStateChange( |
212 MOJO_WAIT_FLAG_READABLE | | 216 WaitFlagsState(MOJO_WAIT_FLAG_NONE, |
213 MOJO_WAIT_FLAG_WRITABLE); | 217 MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE)); |
214 | 218 |
215 test::SimpleWaiterThread thread2(&result2); | 219 test::SimpleWaiterThread thread2(&result2); |
216 waiter_list.AddWaiter(thread2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 7); | 220 waiter_list.AddWaiter(thread2.waiter(), MOJO_WAIT_FLAG_WRITABLE, 7); |
217 thread2.Start(); | 221 thread2.Start(); |
218 | 222 |
219 base::PlatformThread::Sleep(1 * test::EpsilonTimeout()); | 223 base::PlatformThread::Sleep(1 * test::EpsilonTimeout()); |
220 | 224 |
221 // Awake #1. | 225 // Awake #1. |
222 waiter_list.AwakeWaitersForStateChange(MOJO_WAIT_FLAG_READABLE, | 226 waiter_list.AwakeWaitersForStateChange( |
223 MOJO_WAIT_FLAG_READABLE | | 227 WaitFlagsState(MOJO_WAIT_FLAG_READABLE, |
224 MOJO_WAIT_FLAG_WRITABLE); | 228 MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE)); |
225 waiter_list.RemoveWaiter(thread1.waiter()); | 229 waiter_list.RemoveWaiter(thread1.waiter()); |
226 | 230 |
227 base::PlatformThread::Sleep(1 * test::EpsilonTimeout()); | 231 base::PlatformThread::Sleep(1 * test::EpsilonTimeout()); |
228 | 232 |
229 test::SimpleWaiterThread thread3(&result3); | 233 test::SimpleWaiterThread thread3(&result3); |
230 waiter_list.AddWaiter(thread3.waiter(), MOJO_WAIT_FLAG_WRITABLE, 8); | 234 waiter_list.AddWaiter(thread3.waiter(), MOJO_WAIT_FLAG_WRITABLE, 8); |
231 thread3.Start(); | 235 thread3.Start(); |
232 | 236 |
233 test::SimpleWaiterThread thread4(&result4); | 237 test::SimpleWaiterThread thread4(&result4); |
234 waiter_list.AddWaiter(thread4.waiter(), MOJO_WAIT_FLAG_READABLE, 9); | 238 waiter_list.AddWaiter(thread4.waiter(), MOJO_WAIT_FLAG_READABLE, 9); |
235 thread4.Start(); | 239 thread4.Start(); |
236 | 240 |
237 base::PlatformThread::Sleep(1 * test::EpsilonTimeout()); | 241 base::PlatformThread::Sleep(1 * test::EpsilonTimeout()); |
238 | 242 |
239 // Awake #2 and #3 for unsatisfiability. | 243 // Awake #2 and #3 for unsatisfiability. |
240 waiter_list.AwakeWaitersForStateChange(0, MOJO_WAIT_FLAG_READABLE); | 244 waiter_list.AwakeWaitersForStateChange( |
| 245 WaitFlagsState(MOJO_WAIT_FLAG_NONE, MOJO_WAIT_FLAG_READABLE)); |
241 waiter_list.RemoveWaiter(thread2.waiter()); | 246 waiter_list.RemoveWaiter(thread2.waiter()); |
242 waiter_list.RemoveWaiter(thread3.waiter()); | 247 waiter_list.RemoveWaiter(thread3.waiter()); |
243 | 248 |
244 // Cancel #4. | 249 // Cancel #4. |
245 waiter_list.CancelAllWaiters(); | 250 waiter_list.CancelAllWaiters(); |
246 } // Join threads. | 251 } // Join threads. |
247 EXPECT_EQ(6, result1); | 252 EXPECT_EQ(6, result1); |
248 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2); | 253 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2); |
249 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result3); | 254 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result3); |
250 EXPECT_EQ(MOJO_RESULT_CANCELLED, result4); | 255 EXPECT_EQ(MOJO_RESULT_CANCELLED, result4); |
251 } | 256 } |
252 | 257 |
253 } // namespace | 258 } // namespace |
254 } // namespace system | 259 } // namespace system |
255 } // namespace mojo | 260 } // namespace mojo |
OLD | NEW |