| 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" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 namespace { | 23 namespace { |
| 24 | 24 |
| 25 TEST(AwakableListTest, BasicCancel) { | 25 TEST(AwakableListTest, BasicCancel) { |
| 26 MojoResult result; | 26 MojoResult result; |
| 27 uint64_t context; | 27 uint64_t context; |
| 28 | 28 |
| 29 // Cancel immediately after thread start. | 29 // Cancel immediately after thread start. |
| 30 { | 30 { |
| 31 AwakableList awakable_list; | 31 AwakableList awakable_list; |
| 32 test::SimpleWaiterThread thread(&result, &context); | 32 test::SimpleWaiterThread thread(&result, &context); |
| 33 awakable_list.Add(thread.waiter(), 1, MOJO_HANDLE_SIGNAL_READABLE); | 33 awakable_list.Add(thread.waiter(), 1, false, MOJO_HANDLE_SIGNAL_READABLE); |
| 34 thread.Start(); | 34 thread.Start(); |
| 35 awakable_list.CancelAll(); | 35 awakable_list.CancelAndRemoveAll(); |
| 36 // Double-remove okay: | 36 // Double-remove okay: |
| 37 awakable_list.Remove(false, thread.waiter(), 0); | 37 awakable_list.Remove(false, thread.waiter(), 0); |
| 38 } // Join |thread|. | 38 } // Join |thread|. |
| 39 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); | 39 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); |
| 40 EXPECT_EQ(1u, context); | 40 EXPECT_EQ(1u, context); |
| 41 | 41 |
| 42 // Cancel before after thread start. | 42 // Cancel before after thread start. |
| 43 { | 43 { |
| 44 AwakableList awakable_list; | 44 AwakableList awakable_list; |
| 45 test::SimpleWaiterThread thread(&result, &context); | 45 test::SimpleWaiterThread thread(&result, &context); |
| 46 awakable_list.Add(thread.waiter(), 2, MOJO_HANDLE_SIGNAL_WRITABLE); | 46 awakable_list.Add(thread.waiter(), 2, false, MOJO_HANDLE_SIGNAL_WRITABLE); |
| 47 awakable_list.CancelAll(); | 47 awakable_list.CancelAndRemoveAll(); |
| 48 thread.Start(); | 48 thread.Start(); |
| 49 } // Join |thread|. | 49 } // Join |thread|. |
| 50 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); | 50 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); |
| 51 EXPECT_EQ(2u, context); | 51 EXPECT_EQ(2u, context); |
| 52 | 52 |
| 53 // Cancel some time after thread start. | 53 // Cancel some time after thread start. |
| 54 { | 54 { |
| 55 AwakableList awakable_list; | 55 AwakableList awakable_list; |
| 56 test::SimpleWaiterThread thread(&result, &context); | 56 test::SimpleWaiterThread thread(&result, &context); |
| 57 awakable_list.Add(thread.waiter(), 3, MOJO_HANDLE_SIGNAL_READABLE); | 57 awakable_list.Add(thread.waiter(), 3, false, MOJO_HANDLE_SIGNAL_READABLE); |
| 58 thread.Start(); | 58 thread.Start(); |
| 59 ThreadSleep(2 * test::EpsilonTimeout()); | 59 ThreadSleep(2 * test::EpsilonTimeout()); |
| 60 awakable_list.CancelAll(); | 60 awakable_list.CancelAndRemoveAll(); |
| 61 } // Join |thread|. | 61 } // Join |thread|. |
| 62 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); | 62 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); |
| 63 EXPECT_EQ(3u, context); | 63 EXPECT_EQ(3u, context); |
| 64 } | 64 } |
| 65 | 65 |
| 66 TEST(AwakableListTest, BasicAwakeSatisfied) { | 66 TEST(AwakableListTest, BasicAwakeSatisfied) { |
| 67 MojoResult result; | 67 MojoResult result; |
| 68 uint64_t context; | 68 uint64_t context; |
| 69 | 69 |
| 70 // Awake immediately after thread start. | 70 // Awake immediately after thread start. |
| 71 { | 71 { |
| 72 AwakableList awakable_list; | 72 AwakableList awakable_list; |
| 73 test::SimpleWaiterThread thread(&result, &context); | 73 test::SimpleWaiterThread thread(&result, &context); |
| 74 awakable_list.Add(thread.waiter(), 1, MOJO_HANDLE_SIGNAL_READABLE); | 74 awakable_list.Add(thread.waiter(), 1, false, MOJO_HANDLE_SIGNAL_READABLE); |
| 75 thread.Start(); | 75 thread.Start(); |
| 76 awakable_list.OnStateChange( | 76 awakable_list.OnStateChange( |
| 77 HandleSignalsState( | 77 HandleSignalsState( |
| 78 MOJO_HANDLE_SIGNAL_NONE, | 78 MOJO_HANDLE_SIGNAL_NONE, |
| 79 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), | 79 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), |
| 80 HandleSignalsState( | 80 HandleSignalsState( |
| 81 MOJO_HANDLE_SIGNAL_READABLE, | 81 MOJO_HANDLE_SIGNAL_READABLE, |
| 82 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); | 82 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 83 awakable_list.Remove(false, thread.waiter(), 0); | 83 awakable_list.Remove(false, thread.waiter(), 0); |
| 84 } // Join |thread|. | 84 } // Join |thread|. |
| 85 EXPECT_EQ(MOJO_RESULT_OK, result); | 85 EXPECT_EQ(MOJO_RESULT_OK, result); |
| 86 EXPECT_EQ(1u, context); | 86 EXPECT_EQ(1u, context); |
| 87 | 87 |
| 88 // Awake before after thread start. | 88 // Awake before after thread start. |
| 89 { | 89 { |
| 90 AwakableList awakable_list; | 90 AwakableList awakable_list; |
| 91 test::SimpleWaiterThread thread(&result, &context); | 91 test::SimpleWaiterThread thread(&result, &context); |
| 92 awakable_list.Add(thread.waiter(), 2, MOJO_HANDLE_SIGNAL_WRITABLE); | 92 awakable_list.Add(thread.waiter(), 2, false, MOJO_HANDLE_SIGNAL_WRITABLE); |
| 93 awakable_list.OnStateChange( | 93 awakable_list.OnStateChange( |
| 94 HandleSignalsState( | 94 HandleSignalsState( |
| 95 MOJO_HANDLE_SIGNAL_NONE, | 95 MOJO_HANDLE_SIGNAL_NONE, |
| 96 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), | 96 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), |
| 97 HandleSignalsState( | 97 HandleSignalsState( |
| 98 MOJO_HANDLE_SIGNAL_WRITABLE, | 98 MOJO_HANDLE_SIGNAL_WRITABLE, |
| 99 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); | 99 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 100 awakable_list.Remove(false, thread.waiter(), 0); | 100 awakable_list.Remove(false, thread.waiter(), 0); |
| 101 // Double-remove okay: | 101 // Double-remove okay: |
| 102 awakable_list.Remove(false, thread.waiter(), 0); | 102 awakable_list.Remove(false, thread.waiter(), 0); |
| 103 thread.Start(); | 103 thread.Start(); |
| 104 } // Join |thread|. | 104 } // Join |thread|. |
| 105 EXPECT_EQ(MOJO_RESULT_OK, result); | 105 EXPECT_EQ(MOJO_RESULT_OK, result); |
| 106 EXPECT_EQ(2u, context); | 106 EXPECT_EQ(2u, context); |
| 107 | 107 |
| 108 // Awake some time after thread start. | 108 // Awake some time after thread start. |
| 109 { | 109 { |
| 110 AwakableList awakable_list; | 110 AwakableList awakable_list; |
| 111 test::SimpleWaiterThread thread(&result, &context); | 111 test::SimpleWaiterThread thread(&result, &context); |
| 112 awakable_list.Add(thread.waiter(), 3, MOJO_HANDLE_SIGNAL_READABLE); | 112 awakable_list.Add(thread.waiter(), 3, false, MOJO_HANDLE_SIGNAL_READABLE); |
| 113 thread.Start(); | 113 thread.Start(); |
| 114 ThreadSleep(2 * test::EpsilonTimeout()); | 114 ThreadSleep(2 * test::EpsilonTimeout()); |
| 115 awakable_list.OnStateChange( | 115 awakable_list.OnStateChange( |
| 116 HandleSignalsState( | 116 HandleSignalsState( |
| 117 MOJO_HANDLE_SIGNAL_NONE, | 117 MOJO_HANDLE_SIGNAL_NONE, |
| 118 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), | 118 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), |
| 119 HandleSignalsState( | 119 HandleSignalsState( |
| 120 MOJO_HANDLE_SIGNAL_READABLE, | 120 MOJO_HANDLE_SIGNAL_READABLE, |
| 121 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); | 121 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 122 awakable_list.Remove(false, thread.waiter(), 0); | 122 awakable_list.Remove(false, thread.waiter(), 0); |
| 123 } // Join |thread|. | 123 } // Join |thread|. |
| 124 EXPECT_EQ(MOJO_RESULT_OK, result); | 124 EXPECT_EQ(MOJO_RESULT_OK, result); |
| 125 EXPECT_EQ(3u, context); | 125 EXPECT_EQ(3u, context); |
| 126 } | 126 } |
| 127 | 127 |
| 128 TEST(AwakableListTest, BasicAwakeUnsatisfiable) { | 128 TEST(AwakableListTest, BasicAwakeUnsatisfiable) { |
| 129 MojoResult result; | 129 MojoResult result; |
| 130 uint64_t context; | 130 uint64_t context; |
| 131 | 131 |
| 132 // Awake (for unsatisfiability) immediately after thread start. | 132 // Awake (for unsatisfiability) immediately after thread start. |
| 133 { | 133 { |
| 134 AwakableList awakable_list; | 134 AwakableList awakable_list; |
| 135 test::SimpleWaiterThread thread(&result, &context); | 135 test::SimpleWaiterThread thread(&result, &context); |
| 136 awakable_list.Add(thread.waiter(), 1, MOJO_HANDLE_SIGNAL_READABLE); | 136 awakable_list.Add(thread.waiter(), 1, false, MOJO_HANDLE_SIGNAL_READABLE); |
| 137 thread.Start(); | 137 thread.Start(); |
| 138 awakable_list.OnStateChange( | 138 awakable_list.OnStateChange( |
| 139 HandleSignalsState( | 139 HandleSignalsState( |
| 140 MOJO_HANDLE_SIGNAL_NONE, | 140 MOJO_HANDLE_SIGNAL_NONE, |
| 141 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), | 141 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), |
| 142 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, | 142 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, |
| 143 MOJO_HANDLE_SIGNAL_WRITABLE)); | 143 MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 144 awakable_list.Remove(false, thread.waiter(), 0); | 144 awakable_list.Remove(false, thread.waiter(), 0); |
| 145 } // Join |thread|. | 145 } // Join |thread|. |
| 146 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); | 146 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); |
| 147 EXPECT_EQ(1u, context); | 147 EXPECT_EQ(1u, context); |
| 148 | 148 |
| 149 // Awake (for unsatisfiability) before after thread start. | 149 // Awake (for unsatisfiability) before after thread start. |
| 150 { | 150 { |
| 151 AwakableList awakable_list; | 151 AwakableList awakable_list; |
| 152 test::SimpleWaiterThread thread(&result, &context); | 152 test::SimpleWaiterThread thread(&result, &context); |
| 153 awakable_list.Add(thread.waiter(), 2, MOJO_HANDLE_SIGNAL_WRITABLE); | 153 awakable_list.Add(thread.waiter(), 2, false, MOJO_HANDLE_SIGNAL_WRITABLE); |
| 154 awakable_list.OnStateChange( | 154 awakable_list.OnStateChange( |
| 155 HandleSignalsState( | 155 HandleSignalsState( |
| 156 MOJO_HANDLE_SIGNAL_NONE, | 156 MOJO_HANDLE_SIGNAL_NONE, |
| 157 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), | 157 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), |
| 158 HandleSignalsState(MOJO_HANDLE_SIGNAL_READABLE, | 158 HandleSignalsState(MOJO_HANDLE_SIGNAL_READABLE, |
| 159 MOJO_HANDLE_SIGNAL_READABLE)); | 159 MOJO_HANDLE_SIGNAL_READABLE)); |
| 160 awakable_list.Remove(false, thread.waiter(), 0); | 160 awakable_list.Remove(false, thread.waiter(), 0); |
| 161 thread.Start(); | 161 thread.Start(); |
| 162 } // Join |thread|. | 162 } // Join |thread|. |
| 163 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); | 163 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); |
| 164 EXPECT_EQ(2u, context); | 164 EXPECT_EQ(2u, context); |
| 165 | 165 |
| 166 // Awake (for unsatisfiability) some time after thread start. | 166 // Awake (for unsatisfiability) some time after thread start. |
| 167 { | 167 { |
| 168 AwakableList awakable_list; | 168 AwakableList awakable_list; |
| 169 test::SimpleWaiterThread thread(&result, &context); | 169 test::SimpleWaiterThread thread(&result, &context); |
| 170 awakable_list.Add(thread.waiter(), 3, MOJO_HANDLE_SIGNAL_READABLE); | 170 awakable_list.Add(thread.waiter(), 3, false, MOJO_HANDLE_SIGNAL_READABLE); |
| 171 thread.Start(); | 171 thread.Start(); |
| 172 ThreadSleep(2 * test::EpsilonTimeout()); | 172 ThreadSleep(2 * test::EpsilonTimeout()); |
| 173 awakable_list.OnStateChange( | 173 awakable_list.OnStateChange( |
| 174 HandleSignalsState( | 174 HandleSignalsState( |
| 175 MOJO_HANDLE_SIGNAL_NONE, | 175 MOJO_HANDLE_SIGNAL_NONE, |
| 176 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), | 176 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), |
| 177 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, | 177 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, |
| 178 MOJO_HANDLE_SIGNAL_WRITABLE)); | 178 MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 179 awakable_list.Remove(false, thread.waiter(), 0); | 179 awakable_list.Remove(false, thread.waiter(), 0); |
| 180 // Double-remove okay: | 180 // Double-remove okay: |
| (...skipping 10 matching lines...) Expand all Loading... |
| 191 MojoResult result4; | 191 MojoResult result4; |
| 192 uint64_t context1; | 192 uint64_t context1; |
| 193 uint64_t context2; | 193 uint64_t context2; |
| 194 uint64_t context3; | 194 uint64_t context3; |
| 195 uint64_t context4; | 195 uint64_t context4; |
| 196 | 196 |
| 197 // Cancel two awakables. | 197 // Cancel two awakables. |
| 198 { | 198 { |
| 199 AwakableList awakable_list; | 199 AwakableList awakable_list; |
| 200 test::SimpleWaiterThread thread1(&result1, &context1); | 200 test::SimpleWaiterThread thread1(&result1, &context1); |
| 201 awakable_list.Add(thread1.waiter(), 1, MOJO_HANDLE_SIGNAL_READABLE); | 201 awakable_list.Add(thread1.waiter(), 1, false, MOJO_HANDLE_SIGNAL_READABLE); |
| 202 thread1.Start(); | 202 thread1.Start(); |
| 203 test::SimpleWaiterThread thread2(&result2, &context2); | 203 test::SimpleWaiterThread thread2(&result2, &context2); |
| 204 awakable_list.Add(thread2.waiter(), 2, MOJO_HANDLE_SIGNAL_WRITABLE); | 204 awakable_list.Add(thread2.waiter(), 2, false, MOJO_HANDLE_SIGNAL_WRITABLE); |
| 205 thread2.Start(); | 205 thread2.Start(); |
| 206 ThreadSleep(2 * test::EpsilonTimeout()); | 206 ThreadSleep(2 * test::EpsilonTimeout()); |
| 207 awakable_list.CancelAll(); | 207 awakable_list.CancelAndRemoveAll(); |
| 208 } // Join threads. | 208 } // Join threads. |
| 209 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1); | 209 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1); |
| 210 EXPECT_EQ(1u, context1); | 210 EXPECT_EQ(1u, context1); |
| 211 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2); | 211 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2); |
| 212 EXPECT_EQ(2u, context2); | 212 EXPECT_EQ(2u, context2); |
| 213 | 213 |
| 214 // Awake one awakable, cancel other. | 214 // Awake one awakable, cancel other. |
| 215 { | 215 { |
| 216 AwakableList awakable_list; | 216 AwakableList awakable_list; |
| 217 test::SimpleWaiterThread thread1(&result1, &context1); | 217 test::SimpleWaiterThread thread1(&result1, &context1); |
| 218 awakable_list.Add(thread1.waiter(), 3, MOJO_HANDLE_SIGNAL_READABLE); | 218 awakable_list.Add(thread1.waiter(), 3, false, MOJO_HANDLE_SIGNAL_READABLE); |
| 219 thread1.Start(); | 219 thread1.Start(); |
| 220 test::SimpleWaiterThread thread2(&result2, &context2); | 220 test::SimpleWaiterThread thread2(&result2, &context2); |
| 221 awakable_list.Add(thread2.waiter(), 4, MOJO_HANDLE_SIGNAL_WRITABLE); | 221 awakable_list.Add(thread2.waiter(), 4, false, MOJO_HANDLE_SIGNAL_WRITABLE); |
| 222 thread2.Start(); | 222 thread2.Start(); |
| 223 ThreadSleep(2 * test::EpsilonTimeout()); | 223 ThreadSleep(2 * test::EpsilonTimeout()); |
| 224 awakable_list.OnStateChange( | 224 awakable_list.OnStateChange( |
| 225 HandleSignalsState( | 225 HandleSignalsState( |
| 226 MOJO_HANDLE_SIGNAL_NONE, | 226 MOJO_HANDLE_SIGNAL_NONE, |
| 227 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), | 227 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), |
| 228 HandleSignalsState( | 228 HandleSignalsState( |
| 229 MOJO_HANDLE_SIGNAL_READABLE, | 229 MOJO_HANDLE_SIGNAL_READABLE, |
| 230 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); | 230 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 231 awakable_list.Remove(false, thread1.waiter(), 0); | 231 awakable_list.Remove(false, thread1.waiter(), 0); |
| 232 awakable_list.CancelAll(); | 232 awakable_list.CancelAndRemoveAll(); |
| 233 } // Join threads. | 233 } // Join threads. |
| 234 EXPECT_EQ(MOJO_RESULT_OK, result1); | 234 EXPECT_EQ(MOJO_RESULT_OK, result1); |
| 235 EXPECT_EQ(3u, context1); | 235 EXPECT_EQ(3u, context1); |
| 236 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2); | 236 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2); |
| 237 EXPECT_EQ(4u, context2); | 237 EXPECT_EQ(4u, context2); |
| 238 | 238 |
| 239 // Cancel one awakable, awake other for unsatisfiability. | 239 // Cancel one awakable, awake other for unsatisfiability. |
| 240 { | 240 { |
| 241 AwakableList awakable_list; | 241 AwakableList awakable_list; |
| 242 test::SimpleWaiterThread thread1(&result1, &context1); | 242 test::SimpleWaiterThread thread1(&result1, &context1); |
| 243 awakable_list.Add(thread1.waiter(), 5, MOJO_HANDLE_SIGNAL_READABLE); | 243 awakable_list.Add(thread1.waiter(), 5, false, MOJO_HANDLE_SIGNAL_READABLE); |
| 244 thread1.Start(); | 244 thread1.Start(); |
| 245 test::SimpleWaiterThread thread2(&result2, &context2); | 245 test::SimpleWaiterThread thread2(&result2, &context2); |
| 246 awakable_list.Add(thread2.waiter(), 6, MOJO_HANDLE_SIGNAL_WRITABLE); | 246 awakable_list.Add(thread2.waiter(), 6, false, MOJO_HANDLE_SIGNAL_WRITABLE); |
| 247 thread2.Start(); | 247 thread2.Start(); |
| 248 ThreadSleep(2 * test::EpsilonTimeout()); | 248 ThreadSleep(2 * test::EpsilonTimeout()); |
| 249 awakable_list.OnStateChange( | 249 awakable_list.OnStateChange( |
| 250 HandleSignalsState( | 250 HandleSignalsState( |
| 251 MOJO_HANDLE_SIGNAL_NONE, | 251 MOJO_HANDLE_SIGNAL_NONE, |
| 252 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), | 252 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), |
| 253 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, | 253 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, |
| 254 MOJO_HANDLE_SIGNAL_READABLE)); | 254 MOJO_HANDLE_SIGNAL_READABLE)); |
| 255 awakable_list.Remove(false, thread2.waiter(), 0); | 255 awakable_list.Remove(false, thread2.waiter(), 0); |
| 256 awakable_list.CancelAll(); | 256 awakable_list.CancelAndRemoveAll(); |
| 257 } // Join threads. | 257 } // Join threads. |
| 258 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1); | 258 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1); |
| 259 EXPECT_EQ(5u, context1); | 259 EXPECT_EQ(5u, context1); |
| 260 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2); | 260 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2); |
| 261 EXPECT_EQ(6u, context2); | 261 EXPECT_EQ(6u, context2); |
| 262 | 262 |
| 263 // Cancel one awakable, awake other for unsatisfiability. | 263 // Cancel one awakable, awake other for unsatisfiability. |
| 264 { | 264 { |
| 265 AwakableList awakable_list; | 265 AwakableList awakable_list; |
| 266 test::SimpleWaiterThread thread1(&result1, &context1); | 266 test::SimpleWaiterThread thread1(&result1, &context1); |
| 267 awakable_list.Add(thread1.waiter(), 7, MOJO_HANDLE_SIGNAL_READABLE); | 267 awakable_list.Add(thread1.waiter(), 7, false, MOJO_HANDLE_SIGNAL_READABLE); |
| 268 thread1.Start(); | 268 thread1.Start(); |
| 269 | 269 |
| 270 ThreadSleep(1 * test::EpsilonTimeout()); | 270 ThreadSleep(1 * test::EpsilonTimeout()); |
| 271 | 271 |
| 272 // Should do nothing. | 272 // Should do nothing. |
| 273 awakable_list.OnStateChange( | 273 awakable_list.OnStateChange( |
| 274 HandleSignalsState( | 274 HandleSignalsState( |
| 275 MOJO_HANDLE_SIGNAL_NONE, | 275 MOJO_HANDLE_SIGNAL_NONE, |
| 276 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), | 276 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), |
| 277 HandleSignalsState( | 277 HandleSignalsState( |
| 278 MOJO_HANDLE_SIGNAL_NONE, | 278 MOJO_HANDLE_SIGNAL_NONE, |
| 279 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); | 279 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 280 | 280 |
| 281 test::SimpleWaiterThread thread2(&result2, &context2); | 281 test::SimpleWaiterThread thread2(&result2, &context2); |
| 282 awakable_list.Add(thread2.waiter(), 8, MOJO_HANDLE_SIGNAL_WRITABLE); | 282 awakable_list.Add(thread2.waiter(), 8, false, MOJO_HANDLE_SIGNAL_WRITABLE); |
| 283 thread2.Start(); | 283 thread2.Start(); |
| 284 | 284 |
| 285 ThreadSleep(1 * test::EpsilonTimeout()); | 285 ThreadSleep(1 * test::EpsilonTimeout()); |
| 286 | 286 |
| 287 // Awake #1. | 287 // Awake #1. |
| 288 awakable_list.OnStateChange( | 288 awakable_list.OnStateChange( |
| 289 HandleSignalsState( | 289 HandleSignalsState( |
| 290 MOJO_HANDLE_SIGNAL_NONE, | 290 MOJO_HANDLE_SIGNAL_NONE, |
| 291 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), | 291 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), |
| 292 HandleSignalsState( | 292 HandleSignalsState( |
| 293 MOJO_HANDLE_SIGNAL_READABLE, | 293 MOJO_HANDLE_SIGNAL_READABLE, |
| 294 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); | 294 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 295 awakable_list.Remove(false, thread1.waiter(), 0); | 295 awakable_list.Remove(false, thread1.waiter(), 0); |
| 296 | 296 |
| 297 ThreadSleep(1 * test::EpsilonTimeout()); | 297 ThreadSleep(1 * test::EpsilonTimeout()); |
| 298 | 298 |
| 299 test::SimpleWaiterThread thread3(&result3, &context3); | 299 test::SimpleWaiterThread thread3(&result3, &context3); |
| 300 awakable_list.Add(thread3.waiter(), 9, MOJO_HANDLE_SIGNAL_WRITABLE); | 300 awakable_list.Add(thread3.waiter(), 9, false, MOJO_HANDLE_SIGNAL_WRITABLE); |
| 301 thread3.Start(); | 301 thread3.Start(); |
| 302 | 302 |
| 303 test::SimpleWaiterThread thread4(&result4, &context4); | 303 test::SimpleWaiterThread thread4(&result4, &context4); |
| 304 awakable_list.Add(thread4.waiter(), 10, MOJO_HANDLE_SIGNAL_READABLE); | 304 awakable_list.Add(thread4.waiter(), 10, false, MOJO_HANDLE_SIGNAL_READABLE); |
| 305 thread4.Start(); | 305 thread4.Start(); |
| 306 | 306 |
| 307 ThreadSleep(1 * test::EpsilonTimeout()); | 307 ThreadSleep(1 * test::EpsilonTimeout()); |
| 308 | 308 |
| 309 // Awake #2 and #3 for unsatisfiability. | 309 // Awake #2 and #3 for unsatisfiability. |
| 310 awakable_list.OnStateChange( | 310 awakable_list.OnStateChange( |
| 311 HandleSignalsState( | 311 HandleSignalsState( |
| 312 MOJO_HANDLE_SIGNAL_NONE, | 312 MOJO_HANDLE_SIGNAL_NONE, |
| 313 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), | 313 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), |
| 314 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, | 314 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, |
| 315 MOJO_HANDLE_SIGNAL_READABLE)); | 315 MOJO_HANDLE_SIGNAL_READABLE)); |
| 316 awakable_list.Remove(false, thread2.waiter(), 0); | 316 awakable_list.Remove(false, thread2.waiter(), 0); |
| 317 awakable_list.Remove(false, thread3.waiter(), 0); | 317 awakable_list.Remove(false, thread3.waiter(), 0); |
| 318 | 318 |
| 319 // Cancel #4. | 319 // Cancel #4. |
| 320 awakable_list.CancelAll(); | 320 awakable_list.CancelAndRemoveAll(); |
| 321 } // Join threads. | 321 } // Join threads. |
| 322 EXPECT_EQ(MOJO_RESULT_OK, result1); | 322 EXPECT_EQ(MOJO_RESULT_OK, result1); |
| 323 EXPECT_EQ(7u, context1); | 323 EXPECT_EQ(7u, context1); |
| 324 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2); | 324 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2); |
| 325 EXPECT_EQ(8u, context2); | 325 EXPECT_EQ(8u, context2); |
| 326 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result3); | 326 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result3); |
| 327 EXPECT_EQ(9u, context3); | 327 EXPECT_EQ(9u, context3); |
| 328 EXPECT_EQ(MOJO_RESULT_CANCELLED, result4); | 328 EXPECT_EQ(MOJO_RESULT_CANCELLED, result4); |
| 329 EXPECT_EQ(10u, context4); | 329 EXPECT_EQ(10u, context4); |
| 330 } | 330 } |
| 331 | 331 |
| 332 TEST(AwakableListTest, RemoveMatchContext) { | 332 TEST(AwakableListTest, RemoveMatchContext) { |
| 333 MojoResult result; | 333 MojoResult result; |
| 334 uint64_t context; | 334 uint64_t context; |
| 335 | 335 |
| 336 { | 336 { |
| 337 AwakableList awakable_list; | 337 AwakableList awakable_list; |
| 338 test::SimpleWaiterThread thread(&result, &context); | 338 test::SimpleWaiterThread thread(&result, &context); |
| 339 awakable_list.Add(thread.waiter(), 1, MOJO_HANDLE_SIGNAL_READABLE); | 339 awakable_list.Add(thread.waiter(), 1, false, MOJO_HANDLE_SIGNAL_READABLE); |
| 340 awakable_list.Add(thread.waiter(), 2, MOJO_HANDLE_SIGNAL_READABLE); | 340 awakable_list.Add(thread.waiter(), 2, false, MOJO_HANDLE_SIGNAL_READABLE); |
| 341 thread.Start(); | 341 thread.Start(); |
| 342 awakable_list.Remove(true, thread.waiter(), 2); | 342 awakable_list.Remove(true, thread.waiter(), 2); |
| 343 awakable_list.OnStateChange( | 343 awakable_list.OnStateChange( |
| 344 HandleSignalsState( | 344 HandleSignalsState( |
| 345 MOJO_HANDLE_SIGNAL_NONE, | 345 MOJO_HANDLE_SIGNAL_NONE, |
| 346 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), | 346 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), |
| 347 HandleSignalsState( | 347 HandleSignalsState( |
| 348 MOJO_HANDLE_SIGNAL_READABLE, | 348 MOJO_HANDLE_SIGNAL_READABLE, |
| 349 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); | 349 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 350 awakable_list.Remove(true, thread.waiter(), 1); | 350 awakable_list.Remove(true, thread.waiter(), 1); |
| 351 // Double-remove okay: | 351 // Double-remove okay: |
| 352 awakable_list.Remove(true, thread.waiter(), 1); | 352 awakable_list.Remove(true, thread.waiter(), 1); |
| 353 } // Join |thread|. | 353 } // Join |thread|. |
| 354 EXPECT_EQ(MOJO_RESULT_OK, result); | 354 EXPECT_EQ(MOJO_RESULT_OK, result); |
| 355 EXPECT_EQ(1u, context); | 355 EXPECT_EQ(1u, context); |
| 356 | 356 |
| 357 // Try the same thing, but remove "1" before the awake instead. | 357 // Try the same thing, but remove "1" before the awake instead. |
| 358 { | 358 { |
| 359 AwakableList awakable_list; | 359 AwakableList awakable_list; |
| 360 test::SimpleWaiterThread thread(&result, &context); | 360 test::SimpleWaiterThread thread(&result, &context); |
| 361 awakable_list.Add(thread.waiter(), 1, MOJO_HANDLE_SIGNAL_READABLE); | 361 awakable_list.Add(thread.waiter(), 1, false, MOJO_HANDLE_SIGNAL_READABLE); |
| 362 awakable_list.Add(thread.waiter(), 2, MOJO_HANDLE_SIGNAL_READABLE); | 362 awakable_list.Add(thread.waiter(), 2, false, MOJO_HANDLE_SIGNAL_READABLE); |
| 363 thread.Start(); | 363 thread.Start(); |
| 364 awakable_list.Remove(true, thread.waiter(), 1); | 364 awakable_list.Remove(true, thread.waiter(), 1); |
| 365 awakable_list.OnStateChange( | 365 awakable_list.OnStateChange( |
| 366 HandleSignalsState( | 366 HandleSignalsState( |
| 367 MOJO_HANDLE_SIGNAL_NONE, | 367 MOJO_HANDLE_SIGNAL_NONE, |
| 368 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), | 368 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE), |
| 369 HandleSignalsState( | 369 HandleSignalsState( |
| 370 MOJO_HANDLE_SIGNAL_READABLE, | 370 MOJO_HANDLE_SIGNAL_READABLE, |
| 371 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); | 371 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 372 awakable_list.Remove(true, thread.waiter(), 2); | 372 awakable_list.Remove(true, thread.waiter(), 2); |
| 373 } // Join |thread|. | 373 } // Join |thread|. |
| 374 EXPECT_EQ(MOJO_RESULT_OK, result); | 374 EXPECT_EQ(MOJO_RESULT_OK, result); |
| 375 EXPECT_EQ(2u, context); | 375 EXPECT_EQ(2u, context); |
| 376 } | 376 } |
| 377 | 377 |
| 378 class KeepAwakable : public Awakable { | 378 class TestAwakable : public Awakable { |
| 379 public: | 379 public: |
| 380 KeepAwakable() : awake_count(0) {} | 380 TestAwakable() {} |
| 381 | 381 |
| 382 bool Awake(uint64_t context, | 382 void Awake(uint64_t /*context*/, |
| 383 AwakeReason reason, | |
| 384 const HandleSignalsState& signals_state) override { | |
| 385 awake_count++; | |
| 386 return true; | |
| 387 } | |
| 388 | |
| 389 int awake_count; | |
| 390 | |
| 391 MOJO_DISALLOW_COPY_AND_ASSIGN(KeepAwakable); | |
| 392 }; | |
| 393 | |
| 394 class RemoveAwakable : public Awakable { | |
| 395 public: | |
| 396 RemoveAwakable() : awake_count(0) {} | |
| 397 | |
| 398 bool Awake(uint64_t /*context*/, | |
| 399 AwakeReason /*reason*/, | 383 AwakeReason /*reason*/, |
| 400 const HandleSignalsState& /*signals_state*/) override { | 384 const HandleSignalsState& /*signals_state*/) override { |
| 401 awake_count++; | 385 awake_count++; |
| 402 return false; | |
| 403 } | 386 } |
| 404 | 387 |
| 405 int awake_count; | 388 unsigned awake_count = 0; |
| 406 | 389 |
| 407 MOJO_DISALLOW_COPY_AND_ASSIGN(RemoveAwakable); | 390 MOJO_DISALLOW_COPY_AND_ASSIGN(TestAwakable); |
| 408 }; | 391 }; |
| 409 | 392 |
| 410 TEST(AwakableListTest, KeepAwakablesReturningTrue) { | 393 TEST(AwakableListTest, PersistentVsNonPersistent) { |
| 411 KeepAwakable keep0; | 394 TestAwakable persistent0; |
| 412 KeepAwakable keep1; | 395 TestAwakable persistent1; |
| 413 RemoveAwakable remove0; | 396 TestAwakable oneshot0; |
| 414 RemoveAwakable remove1; | 397 TestAwakable oneshot1; |
| 415 RemoveAwakable remove2; | 398 TestAwakable oneshot2; |
| 416 | 399 |
| 417 AwakableList remove_all; | 400 AwakableList remove_all; |
| 418 remove_all.Add(&remove0, 0, MOJO_HANDLE_SIGNAL_WRITABLE); | 401 remove_all.Add(&oneshot0, 0, false, MOJO_HANDLE_SIGNAL_WRITABLE); |
| 419 remove_all.Add(&remove1, 0, MOJO_HANDLE_SIGNAL_WRITABLE); | 402 remove_all.Add(&oneshot1, 0, false, MOJO_HANDLE_SIGNAL_WRITABLE); |
| 420 | 403 |
| 421 remove_all.OnStateChange( | 404 remove_all.OnStateChange( |
| 422 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE), | 405 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE), |
| 423 HandleSignalsState(MOJO_HANDLE_SIGNAL_WRITABLE, | 406 HandleSignalsState(MOJO_HANDLE_SIGNAL_WRITABLE, |
| 424 MOJO_HANDLE_SIGNAL_WRITABLE)); | 407 MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 425 EXPECT_EQ(remove0.awake_count, 1); | 408 EXPECT_EQ(oneshot0.awake_count, 1u); |
| 426 EXPECT_EQ(remove1.awake_count, 1); | 409 EXPECT_EQ(oneshot1.awake_count, 1u); |
| 427 | 410 |
| 428 remove_all.OnStateChange( | 411 remove_all.OnStateChange( |
| 429 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE), | 412 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE), |
| 430 HandleSignalsState(MOJO_HANDLE_SIGNAL_WRITABLE, | 413 HandleSignalsState(MOJO_HANDLE_SIGNAL_WRITABLE, |
| 431 MOJO_HANDLE_SIGNAL_WRITABLE)); | 414 MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 432 EXPECT_EQ(remove0.awake_count, 1); | 415 EXPECT_EQ(oneshot0.awake_count, 1u); |
| 433 EXPECT_EQ(remove1.awake_count, 1); | 416 EXPECT_EQ(oneshot1.awake_count, 1u); |
| 434 | 417 |
| 435 AwakableList remove_first; | 418 AwakableList remove_first; |
| 436 remove_first.Add(&remove2, 0, MOJO_HANDLE_SIGNAL_WRITABLE); | 419 remove_first.Add(&oneshot2, 0, false, MOJO_HANDLE_SIGNAL_WRITABLE); |
| 437 remove_first.Add(&keep0, 0, MOJO_HANDLE_SIGNAL_WRITABLE); | 420 remove_first.Add(&persistent0, 0, true, MOJO_HANDLE_SIGNAL_WRITABLE); |
| 438 remove_first.Add(&keep1, 0, MOJO_HANDLE_SIGNAL_WRITABLE); | 421 remove_first.Add(&persistent1, 0, true, MOJO_HANDLE_SIGNAL_WRITABLE); |
| 439 | 422 |
| 440 remove_first.OnStateChange( | 423 remove_first.OnStateChange( |
| 441 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE), | 424 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE), |
| 442 HandleSignalsState(MOJO_HANDLE_SIGNAL_WRITABLE, | 425 HandleSignalsState(MOJO_HANDLE_SIGNAL_WRITABLE, |
| 443 MOJO_HANDLE_SIGNAL_WRITABLE)); | 426 MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 444 EXPECT_EQ(keep0.awake_count, 1); | 427 EXPECT_EQ(persistent0.awake_count, 1u); |
| 445 EXPECT_EQ(keep1.awake_count, 1); | 428 EXPECT_EQ(persistent1.awake_count, 1u); |
| 446 EXPECT_EQ(remove2.awake_count, 1); | 429 EXPECT_EQ(oneshot2.awake_count, 1u); |
| 447 | 430 |
| 448 remove_first.OnStateChange( | 431 remove_first.OnStateChange( |
| 449 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE), | 432 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE), |
| 450 HandleSignalsState(MOJO_HANDLE_SIGNAL_WRITABLE, | 433 HandleSignalsState(MOJO_HANDLE_SIGNAL_WRITABLE, |
| 451 MOJO_HANDLE_SIGNAL_WRITABLE)); | 434 MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 452 EXPECT_EQ(keep0.awake_count, 2); | 435 EXPECT_EQ(persistent0.awake_count, 2u); |
| 453 EXPECT_EQ(keep1.awake_count, 2); | 436 EXPECT_EQ(persistent1.awake_count, 2u); |
| 454 EXPECT_EQ(remove2.awake_count, 1); | 437 EXPECT_EQ(oneshot2.awake_count, 1u); |
| 455 | 438 |
| 456 remove_first.Remove(false, &keep0, 0); | 439 remove_first.Remove(false, &persistent0, 0); |
| 457 remove_first.Remove(false, &keep1, 0); | 440 remove_first.Remove(false, &persistent1, 0); |
| 458 } | 441 } |
| 459 | 442 |
| 460 } // namespace | 443 } // namespace |
| 461 } // namespace system | 444 } // namespace system |
| 462 } // namespace mojo | 445 } // namespace mojo |
| OLD | NEW |