| 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/edk/system/awakable_list.h" | 10 #include "mojo/edk/system/awakable_list.h" |
| 11 | 11 |
| 12 #include "mojo/edk/platform/thread_utils.h" |
| 12 #include "mojo/edk/system/handle_signals_state.h" | 13 #include "mojo/edk/system/handle_signals_state.h" |
| 13 #include "mojo/edk/system/test/sleep.h" | |
| 14 #include "mojo/edk/system/test/timeouts.h" | 14 #include "mojo/edk/system/test/timeouts.h" |
| 15 #include "mojo/edk/system/waiter.h" | 15 #include "mojo/edk/system/waiter.h" |
| 16 #include "mojo/edk/system/waiter_test_utils.h" | 16 #include "mojo/edk/system/waiter_test_utils.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 | 18 |
| 19 using mojo::platform::ThreadSleep; |
| 20 |
| 19 namespace mojo { | 21 namespace mojo { |
| 20 namespace system { | 22 namespace system { |
| 21 namespace { | 23 namespace { |
| 22 | 24 |
| 23 TEST(AwakableListTest, BasicCancel) { | 25 TEST(AwakableListTest, BasicCancel) { |
| 24 MojoResult result; | 26 MojoResult result; |
| 25 uint32_t context; | 27 uint32_t context; |
| 26 | 28 |
| 27 // Cancel immediately after thread start. | 29 // Cancel immediately after thread start. |
| 28 { | 30 { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 47 } // Join |thread|. | 49 } // Join |thread|. |
| 48 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); | 50 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); |
| 49 EXPECT_EQ(2u, context); | 51 EXPECT_EQ(2u, context); |
| 50 | 52 |
| 51 // Cancel some time after thread start. | 53 // Cancel some time after thread start. |
| 52 { | 54 { |
| 53 AwakableList awakable_list; | 55 AwakableList awakable_list; |
| 54 test::SimpleWaiterThread thread(&result, &context); | 56 test::SimpleWaiterThread thread(&result, &context); |
| 55 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3); | 57 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3); |
| 56 thread.Start(); | 58 thread.Start(); |
| 57 test::Sleep(2 * test::EpsilonTimeout()); | 59 ThreadSleep(2 * test::EpsilonTimeout()); |
| 58 awakable_list.CancelAll(); | 60 awakable_list.CancelAll(); |
| 59 } // Join |thread|. | 61 } // Join |thread|. |
| 60 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); | 62 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); |
| 61 EXPECT_EQ(3u, context); | 63 EXPECT_EQ(3u, context); |
| 62 } | 64 } |
| 63 | 65 |
| 64 TEST(AwakableListTest, BasicAwakeSatisfied) { | 66 TEST(AwakableListTest, BasicAwakeSatisfied) { |
| 65 MojoResult result; | 67 MojoResult result; |
| 66 uint32_t context; | 68 uint32_t context; |
| 67 | 69 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 94 } // Join |thread|. | 96 } // Join |thread|. |
| 95 EXPECT_EQ(MOJO_RESULT_OK, result); | 97 EXPECT_EQ(MOJO_RESULT_OK, result); |
| 96 EXPECT_EQ(2u, context); | 98 EXPECT_EQ(2u, context); |
| 97 | 99 |
| 98 // Awake some time after thread start. | 100 // Awake some time after thread start. |
| 99 { | 101 { |
| 100 AwakableList awakable_list; | 102 AwakableList awakable_list; |
| 101 test::SimpleWaiterThread thread(&result, &context); | 103 test::SimpleWaiterThread thread(&result, &context); |
| 102 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3); | 104 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3); |
| 103 thread.Start(); | 105 thread.Start(); |
| 104 test::Sleep(2 * test::EpsilonTimeout()); | 106 ThreadSleep(2 * test::EpsilonTimeout()); |
| 105 awakable_list.AwakeForStateChange(HandleSignalsState( | 107 awakable_list.AwakeForStateChange(HandleSignalsState( |
| 106 MOJO_HANDLE_SIGNAL_READABLE, | 108 MOJO_HANDLE_SIGNAL_READABLE, |
| 107 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); | 109 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 108 awakable_list.Remove(thread.waiter()); | 110 awakable_list.Remove(thread.waiter()); |
| 109 } // Join |thread|. | 111 } // Join |thread|. |
| 110 EXPECT_EQ(MOJO_RESULT_OK, result); | 112 EXPECT_EQ(MOJO_RESULT_OK, result); |
| 111 EXPECT_EQ(3u, context); | 113 EXPECT_EQ(3u, context); |
| 112 } | 114 } |
| 113 | 115 |
| 114 TEST(AwakableListTest, BasicAwakeUnsatisfiable) { | 116 TEST(AwakableListTest, BasicAwakeUnsatisfiable) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 140 } // Join |thread|. | 142 } // Join |thread|. |
| 141 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); | 143 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); |
| 142 EXPECT_EQ(2u, context); | 144 EXPECT_EQ(2u, context); |
| 143 | 145 |
| 144 // Awake (for unsatisfiability) some time after thread start. | 146 // Awake (for unsatisfiability) some time after thread start. |
| 145 { | 147 { |
| 146 AwakableList awakable_list; | 148 AwakableList awakable_list; |
| 147 test::SimpleWaiterThread thread(&result, &context); | 149 test::SimpleWaiterThread thread(&result, &context); |
| 148 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3); | 150 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3); |
| 149 thread.Start(); | 151 thread.Start(); |
| 150 test::Sleep(2 * test::EpsilonTimeout()); | 152 ThreadSleep(2 * test::EpsilonTimeout()); |
| 151 awakable_list.AwakeForStateChange(HandleSignalsState( | 153 awakable_list.AwakeForStateChange(HandleSignalsState( |
| 152 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE)); | 154 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 153 awakable_list.Remove(thread.waiter()); | 155 awakable_list.Remove(thread.waiter()); |
| 154 // Double-remove okay: | 156 // Double-remove okay: |
| 155 awakable_list.Remove(thread.waiter()); | 157 awakable_list.Remove(thread.waiter()); |
| 156 } // Join |thread|. | 158 } // Join |thread|. |
| 157 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); | 159 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); |
| 158 EXPECT_EQ(3u, context); | 160 EXPECT_EQ(3u, context); |
| 159 } | 161 } |
| 160 | 162 |
| 161 TEST(AwakableListTest, MultipleAwakables) { | 163 TEST(AwakableListTest, MultipleAwakables) { |
| 162 MojoResult result1; | 164 MojoResult result1; |
| 163 MojoResult result2; | 165 MojoResult result2; |
| 164 MojoResult result3; | 166 MojoResult result3; |
| 165 MojoResult result4; | 167 MojoResult result4; |
| 166 uint32_t context1; | 168 uint32_t context1; |
| 167 uint32_t context2; | 169 uint32_t context2; |
| 168 uint32_t context3; | 170 uint32_t context3; |
| 169 uint32_t context4; | 171 uint32_t context4; |
| 170 | 172 |
| 171 // Cancel two awakables. | 173 // Cancel two awakables. |
| 172 { | 174 { |
| 173 AwakableList awakable_list; | 175 AwakableList awakable_list; |
| 174 test::SimpleWaiterThread thread1(&result1, &context1); | 176 test::SimpleWaiterThread thread1(&result1, &context1); |
| 175 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1); | 177 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1); |
| 176 thread1.Start(); | 178 thread1.Start(); |
| 177 test::SimpleWaiterThread thread2(&result2, &context2); | 179 test::SimpleWaiterThread thread2(&result2, &context2); |
| 178 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 2); | 180 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 2); |
| 179 thread2.Start(); | 181 thread2.Start(); |
| 180 test::Sleep(2 * test::EpsilonTimeout()); | 182 ThreadSleep(2 * test::EpsilonTimeout()); |
| 181 awakable_list.CancelAll(); | 183 awakable_list.CancelAll(); |
| 182 } // Join threads. | 184 } // Join threads. |
| 183 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1); | 185 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1); |
| 184 EXPECT_EQ(1u, context1); | 186 EXPECT_EQ(1u, context1); |
| 185 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2); | 187 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2); |
| 186 EXPECT_EQ(2u, context2); | 188 EXPECT_EQ(2u, context2); |
| 187 | 189 |
| 188 // Awake one awakable, cancel other. | 190 // Awake one awakable, cancel other. |
| 189 { | 191 { |
| 190 AwakableList awakable_list; | 192 AwakableList awakable_list; |
| 191 test::SimpleWaiterThread thread1(&result1, &context1); | 193 test::SimpleWaiterThread thread1(&result1, &context1); |
| 192 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3); | 194 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3); |
| 193 thread1.Start(); | 195 thread1.Start(); |
| 194 test::SimpleWaiterThread thread2(&result2, &context2); | 196 test::SimpleWaiterThread thread2(&result2, &context2); |
| 195 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 4); | 197 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 4); |
| 196 thread2.Start(); | 198 thread2.Start(); |
| 197 test::Sleep(2 * test::EpsilonTimeout()); | 199 ThreadSleep(2 * test::EpsilonTimeout()); |
| 198 awakable_list.AwakeForStateChange(HandleSignalsState( | 200 awakable_list.AwakeForStateChange(HandleSignalsState( |
| 199 MOJO_HANDLE_SIGNAL_READABLE, | 201 MOJO_HANDLE_SIGNAL_READABLE, |
| 200 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); | 202 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 201 awakable_list.Remove(thread1.waiter()); | 203 awakable_list.Remove(thread1.waiter()); |
| 202 awakable_list.CancelAll(); | 204 awakable_list.CancelAll(); |
| 203 } // Join threads. | 205 } // Join threads. |
| 204 EXPECT_EQ(MOJO_RESULT_OK, result1); | 206 EXPECT_EQ(MOJO_RESULT_OK, result1); |
| 205 EXPECT_EQ(3u, context1); | 207 EXPECT_EQ(3u, context1); |
| 206 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2); | 208 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2); |
| 207 EXPECT_EQ(4u, context2); | 209 EXPECT_EQ(4u, context2); |
| 208 | 210 |
| 209 // Cancel one awakable, awake other for unsatisfiability. | 211 // Cancel one awakable, awake other for unsatisfiability. |
| 210 { | 212 { |
| 211 AwakableList awakable_list; | 213 AwakableList awakable_list; |
| 212 test::SimpleWaiterThread thread1(&result1, &context1); | 214 test::SimpleWaiterThread thread1(&result1, &context1); |
| 213 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 5); | 215 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 5); |
| 214 thread1.Start(); | 216 thread1.Start(); |
| 215 test::SimpleWaiterThread thread2(&result2, &context2); | 217 test::SimpleWaiterThread thread2(&result2, &context2); |
| 216 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 6); | 218 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 6); |
| 217 thread2.Start(); | 219 thread2.Start(); |
| 218 test::Sleep(2 * test::EpsilonTimeout()); | 220 ThreadSleep(2 * test::EpsilonTimeout()); |
| 219 awakable_list.AwakeForStateChange(HandleSignalsState( | 221 awakable_list.AwakeForStateChange(HandleSignalsState( |
| 220 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_READABLE)); | 222 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_READABLE)); |
| 221 awakable_list.Remove(thread2.waiter()); | 223 awakable_list.Remove(thread2.waiter()); |
| 222 awakable_list.CancelAll(); | 224 awakable_list.CancelAll(); |
| 223 } // Join threads. | 225 } // Join threads. |
| 224 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1); | 226 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1); |
| 225 EXPECT_EQ(5u, context1); | 227 EXPECT_EQ(5u, context1); |
| 226 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2); | 228 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2); |
| 227 EXPECT_EQ(6u, context2); | 229 EXPECT_EQ(6u, context2); |
| 228 | 230 |
| 229 // Cancel one awakable, awake other for unsatisfiability. | 231 // Cancel one awakable, awake other for unsatisfiability. |
| 230 { | 232 { |
| 231 AwakableList awakable_list; | 233 AwakableList awakable_list; |
| 232 test::SimpleWaiterThread thread1(&result1, &context1); | 234 test::SimpleWaiterThread thread1(&result1, &context1); |
| 233 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 7); | 235 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 7); |
| 234 thread1.Start(); | 236 thread1.Start(); |
| 235 | 237 |
| 236 test::Sleep(1 * test::EpsilonTimeout()); | 238 ThreadSleep(1 * test::EpsilonTimeout()); |
| 237 | 239 |
| 238 // Should do nothing. | 240 // Should do nothing. |
| 239 awakable_list.AwakeForStateChange(HandleSignalsState( | 241 awakable_list.AwakeForStateChange(HandleSignalsState( |
| 240 MOJO_HANDLE_SIGNAL_NONE, | 242 MOJO_HANDLE_SIGNAL_NONE, |
| 241 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); | 243 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 242 | 244 |
| 243 test::SimpleWaiterThread thread2(&result2, &context2); | 245 test::SimpleWaiterThread thread2(&result2, &context2); |
| 244 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 8); | 246 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 8); |
| 245 thread2.Start(); | 247 thread2.Start(); |
| 246 | 248 |
| 247 test::Sleep(1 * test::EpsilonTimeout()); | 249 ThreadSleep(1 * test::EpsilonTimeout()); |
| 248 | 250 |
| 249 // Awake #1. | 251 // Awake #1. |
| 250 awakable_list.AwakeForStateChange(HandleSignalsState( | 252 awakable_list.AwakeForStateChange(HandleSignalsState( |
| 251 MOJO_HANDLE_SIGNAL_READABLE, | 253 MOJO_HANDLE_SIGNAL_READABLE, |
| 252 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); | 254 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 253 awakable_list.Remove(thread1.waiter()); | 255 awakable_list.Remove(thread1.waiter()); |
| 254 | 256 |
| 255 test::Sleep(1 * test::EpsilonTimeout()); | 257 ThreadSleep(1 * test::EpsilonTimeout()); |
| 256 | 258 |
| 257 test::SimpleWaiterThread thread3(&result3, &context3); | 259 test::SimpleWaiterThread thread3(&result3, &context3); |
| 258 awakable_list.Add(thread3.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 9); | 260 awakable_list.Add(thread3.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 9); |
| 259 thread3.Start(); | 261 thread3.Start(); |
| 260 | 262 |
| 261 test::SimpleWaiterThread thread4(&result4, &context4); | 263 test::SimpleWaiterThread thread4(&result4, &context4); |
| 262 awakable_list.Add(thread4.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 10); | 264 awakable_list.Add(thread4.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 10); |
| 263 thread4.Start(); | 265 thread4.Start(); |
| 264 | 266 |
| 265 test::Sleep(1 * test::EpsilonTimeout()); | 267 ThreadSleep(1 * test::EpsilonTimeout()); |
| 266 | 268 |
| 267 // Awake #2 and #3 for unsatisfiability. | 269 // Awake #2 and #3 for unsatisfiability. |
| 268 awakable_list.AwakeForStateChange(HandleSignalsState( | 270 awakable_list.AwakeForStateChange(HandleSignalsState( |
| 269 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_READABLE)); | 271 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_READABLE)); |
| 270 awakable_list.Remove(thread2.waiter()); | 272 awakable_list.Remove(thread2.waiter()); |
| 271 awakable_list.Remove(thread3.waiter()); | 273 awakable_list.Remove(thread3.waiter()); |
| 272 | 274 |
| 273 // Cancel #4. | 275 // Cancel #4. |
| 274 awakable_list.CancelAll(); | 276 awakable_list.CancelAll(); |
| 275 } // Join threads. | 277 } // Join threads. |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 EXPECT_EQ(keep1.awake_count, 2); | 350 EXPECT_EQ(keep1.awake_count, 2); |
| 349 EXPECT_EQ(remove2.awake_count, 1); | 351 EXPECT_EQ(remove2.awake_count, 1); |
| 350 | 352 |
| 351 remove_first.Remove(&keep0); | 353 remove_first.Remove(&keep0); |
| 352 remove_first.Remove(&keep1); | 354 remove_first.Remove(&keep1); |
| 353 } | 355 } |
| 354 | 356 |
| 355 } // namespace | 357 } // namespace |
| 356 } // namespace system | 358 } // namespace system |
| 357 } // namespace mojo | 359 } // namespace mojo |
| OLD | NEW |