| 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 |