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

Side by Side Diff: mojo/public/cpp/system/tests/wait_set_unittest.cc

Issue 2754143005: Use WaitableEvents to wake up sync IPC waiting (Closed)
Patch Set: . Created 3 years, 9 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
« no previous file with comments | « mojo/public/cpp/bindings/sync_handle_registry.h ('k') | mojo/public/cpp/system/wait_set.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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 #include "mojo/public/cpp/system/wait_set.h" 5 #include "mojo/public/cpp/system/wait_set.h"
6 6
7 #include <set>
8 #include <vector>
9
7 #include "base/bind.h" 10 #include "base/bind.h"
8 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/memory/ptr_util.h"
13 #include "base/synchronization/waitable_event.h"
9 #include "base/threading/platform_thread.h" 14 #include "base/threading/platform_thread.h"
10 #include "base/threading/simple_thread.h" 15 #include "base/threading/simple_thread.h"
11 #include "mojo/public/cpp/system/message_pipe.h" 16 #include "mojo/public/cpp/system/message_pipe.h"
17 #include "mojo/public/cpp/system/wait.h"
12 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
13 19
14 namespace mojo { 20 namespace mojo {
15 namespace { 21 namespace {
16 22
17 using WaitSetTest = testing::Test; 23 using WaitSetTest = testing::Test;
18 24
19 void WriteMessage(const ScopedMessagePipeHandle& handle, 25 void WriteMessage(const ScopedMessagePipeHandle& handle,
20 const base::StringPiece& message) { 26 const base::StringPiece& message) {
21 MojoResult rv = WriteMessageRaw(handle.get(), message.data(), 27 MojoResult rv = WriteMessageRaw(handle.get(), message.data(),
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 67
62 // Watch only one handle and write to the other. 68 // Watch only one handle and write to the other.
63 69
64 wait_set.AddHandle(p.handle1.get(), MOJO_HANDLE_SIGNAL_READABLE); 70 wait_set.AddHandle(p.handle1.get(), MOJO_HANDLE_SIGNAL_READABLE);
65 WriteMessage(p.handle0, kTestMessage1); 71 WriteMessage(p.handle0, kTestMessage1);
66 72
67 size_t num_ready_handles = 2; 73 size_t num_ready_handles = 2;
68 Handle ready_handles[2]; 74 Handle ready_handles[2];
69 MojoResult ready_results[2] = {MOJO_RESULT_UNKNOWN, MOJO_RESULT_UNKNOWN}; 75 MojoResult ready_results[2] = {MOJO_RESULT_UNKNOWN, MOJO_RESULT_UNKNOWN};
70 HandleSignalsState hss[2]; 76 HandleSignalsState hss[2];
71 wait_set.Wait(&num_ready_handles, ready_handles, ready_results, hss); 77 wait_set.Wait(nullptr, &num_ready_handles, ready_handles, ready_results, hss);
72 78
73 EXPECT_EQ(1u, num_ready_handles); 79 EXPECT_EQ(1u, num_ready_handles);
74 EXPECT_EQ(p.handle1.get(), ready_handles[0]); 80 EXPECT_EQ(p.handle1.get(), ready_handles[0]);
75 EXPECT_EQ(MOJO_RESULT_OK, ready_results[0]); 81 EXPECT_EQ(MOJO_RESULT_OK, ready_results[0]);
76 EXPECT_TRUE(hss[0].readable() && hss[0].writable() && !hss[0].peer_closed()); 82 EXPECT_TRUE(hss[0].readable() && hss[0].writable() && !hss[0].peer_closed());
77 83
78 wait_set.RemoveHandle(p.handle1.get()); 84 wait_set.RemoveHandle(p.handle1.get());
79 85
80 // Now watch only the other handle and write to the first one. 86 // Now watch only the other handle and write to the first one.
81 87
82 wait_set.AddHandle(p.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE); 88 wait_set.AddHandle(p.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE);
83 WriteMessage(p.handle1, kTestMessage1); 89 WriteMessage(p.handle1, kTestMessage1);
84 90
85 num_ready_handles = 2; 91 num_ready_handles = 2;
86 ready_results[0] = MOJO_RESULT_UNKNOWN; 92 ready_results[0] = MOJO_RESULT_UNKNOWN;
87 ready_results[1] = MOJO_RESULT_UNKNOWN; 93 ready_results[1] = MOJO_RESULT_UNKNOWN;
88 wait_set.Wait(&num_ready_handles, ready_handles, ready_results, hss); 94 wait_set.Wait(nullptr, &num_ready_handles, ready_handles, ready_results, hss);
89 95
90 EXPECT_EQ(1u, num_ready_handles); 96 EXPECT_EQ(1u, num_ready_handles);
91 EXPECT_EQ(p.handle0.get(), ready_handles[0]); 97 EXPECT_EQ(p.handle0.get(), ready_handles[0]);
92 EXPECT_EQ(MOJO_RESULT_OK, ready_results[0]); 98 EXPECT_EQ(MOJO_RESULT_OK, ready_results[0]);
93 EXPECT_TRUE(hss[0].readable() && hss[0].writable() && !hss[0].peer_closed()); 99 EXPECT_TRUE(hss[0].readable() && hss[0].writable() && !hss[0].peer_closed());
94 100
95 // Now wait on both of them. 101 // Now wait on both of them.
96 wait_set.AddHandle(p.handle1.get(), MOJO_HANDLE_SIGNAL_READABLE); 102 wait_set.AddHandle(p.handle1.get(), MOJO_HANDLE_SIGNAL_READABLE);
97 103
98 num_ready_handles = 2; 104 num_ready_handles = 2;
99 ready_results[0] = MOJO_RESULT_UNKNOWN; 105 ready_results[0] = MOJO_RESULT_UNKNOWN;
100 ready_results[1] = MOJO_RESULT_UNKNOWN; 106 ready_results[1] = MOJO_RESULT_UNKNOWN;
101 wait_set.Wait(&num_ready_handles, ready_handles, ready_results, hss); 107 wait_set.Wait(nullptr, &num_ready_handles, ready_handles, ready_results, hss);
102 EXPECT_EQ(2u, num_ready_handles); 108 EXPECT_EQ(2u, num_ready_handles);
103 EXPECT_TRUE((ready_handles[0] == p.handle0.get() && 109 EXPECT_TRUE((ready_handles[0] == p.handle0.get() &&
104 ready_handles[1] == p.handle1.get()) || 110 ready_handles[1] == p.handle1.get()) ||
105 (ready_handles[0] == p.handle1.get() && 111 (ready_handles[0] == p.handle1.get() &&
106 ready_handles[1] == p.handle0.get())); 112 ready_handles[1] == p.handle0.get()));
107 EXPECT_EQ(MOJO_RESULT_OK, ready_results[0]); 113 EXPECT_EQ(MOJO_RESULT_OK, ready_results[0]);
108 EXPECT_EQ(MOJO_RESULT_OK, ready_results[1]); 114 EXPECT_EQ(MOJO_RESULT_OK, ready_results[1]);
109 EXPECT_TRUE(hss[0].readable() && hss[0].writable() && !hss[0].peer_closed()); 115 EXPECT_TRUE(hss[0].readable() && hss[0].writable() && !hss[0].peer_closed());
110 EXPECT_TRUE(hss[1].readable() && hss[1].writable() && !hss[1].peer_closed()); 116 EXPECT_TRUE(hss[1].readable() && hss[1].writable() && !hss[1].peer_closed());
111 117
112 // Wait on both again, but with only enough output space for one result. 118 // Wait on both again, but with only enough output space for one result.
113 num_ready_handles = 1; 119 num_ready_handles = 1;
114 ready_results[0] = MOJO_RESULT_UNKNOWN; 120 ready_results[0] = MOJO_RESULT_UNKNOWN;
115 wait_set.Wait(&num_ready_handles, ready_handles, ready_results, hss); 121 wait_set.Wait(nullptr, &num_ready_handles, ready_handles, ready_results, hss);
116 EXPECT_EQ(1u, num_ready_handles); 122 EXPECT_EQ(1u, num_ready_handles);
117 EXPECT_TRUE(ready_handles[0] == p.handle0.get() || 123 EXPECT_TRUE(ready_handles[0] == p.handle0.get() ||
118 ready_handles[0] == p.handle1.get()); 124 ready_handles[0] == p.handle1.get());
119 EXPECT_EQ(MOJO_RESULT_OK, ready_results[0]); 125 EXPECT_EQ(MOJO_RESULT_OK, ready_results[0]);
120 126
121 // Remove the ready handle from the set and wait one more time. 127 // Remove the ready handle from the set and wait one more time.
122 EXPECT_EQ(MOJO_RESULT_OK, wait_set.RemoveHandle(ready_handles[0])); 128 EXPECT_EQ(MOJO_RESULT_OK, wait_set.RemoveHandle(ready_handles[0]));
123 129
124 num_ready_handles = 1; 130 num_ready_handles = 1;
125 ready_results[0] = MOJO_RESULT_UNKNOWN; 131 ready_results[0] = MOJO_RESULT_UNKNOWN;
126 wait_set.Wait(&num_ready_handles, ready_handles, ready_results, hss); 132 wait_set.Wait(nullptr, &num_ready_handles, ready_handles, ready_results, hss);
127 EXPECT_EQ(1u, num_ready_handles); 133 EXPECT_EQ(1u, num_ready_handles);
128 EXPECT_TRUE(ready_handles[0] == p.handle0.get() || 134 EXPECT_TRUE(ready_handles[0] == p.handle0.get() ||
129 ready_handles[0] == p.handle1.get()); 135 ready_handles[0] == p.handle1.get());
130 EXPECT_EQ(MOJO_RESULT_OK, ready_results[0]); 136 EXPECT_EQ(MOJO_RESULT_OK, ready_results[0]);
131 137
132 EXPECT_EQ(MOJO_RESULT_OK, wait_set.RemoveHandle(ready_handles[0])); 138 EXPECT_EQ(MOJO_RESULT_OK, wait_set.RemoveHandle(ready_handles[0]));
133 139
134 // The wait set should be empty now. Nothing to wait on. 140 // The wait set should be empty now. Nothing to wait on.
135 num_ready_handles = 2; 141 num_ready_handles = 2;
136 wait_set.Wait(&num_ready_handles, ready_handles, ready_results); 142 wait_set.Wait(nullptr, &num_ready_handles, ready_handles, ready_results);
137 EXPECT_EQ(0u, num_ready_handles); 143 EXPECT_EQ(0u, num_ready_handles);
138 } 144 }
139 145
140 TEST_F(WaitSetTest, Unsatisfiable) { 146 TEST_F(WaitSetTest, Unsatisfiable) {
141 MessagePipe p, q; 147 MessagePipe p, q;
142 WaitSet wait_set; 148 WaitSet wait_set;
143 149
144 wait_set.AddHandle(q.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE); 150 wait_set.AddHandle(q.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE);
145 wait_set.AddHandle(q.handle1.get(), MOJO_HANDLE_SIGNAL_READABLE); 151 wait_set.AddHandle(q.handle1.get(), MOJO_HANDLE_SIGNAL_READABLE);
146 wait_set.AddHandle(p.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE); 152 wait_set.AddHandle(p.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE);
147 153
148 size_t num_ready_handles = 2; 154 size_t num_ready_handles = 2;
149 Handle ready_handles[2]; 155 Handle ready_handles[2];
150 MojoResult ready_results[2] = {MOJO_RESULT_UNKNOWN, MOJO_RESULT_UNKNOWN}; 156 MojoResult ready_results[2] = {MOJO_RESULT_UNKNOWN, MOJO_RESULT_UNKNOWN};
151 157
152 p.handle1.reset(); 158 p.handle1.reset();
153 wait_set.Wait(&num_ready_handles, ready_handles, ready_results); 159 wait_set.Wait(nullptr, &num_ready_handles, ready_handles, ready_results);
154 EXPECT_EQ(1u, num_ready_handles); 160 EXPECT_EQ(1u, num_ready_handles);
155 EXPECT_EQ(p.handle0.get(), ready_handles[0]); 161 EXPECT_EQ(p.handle0.get(), ready_handles[0]);
156 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, ready_results[0]); 162 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, ready_results[0]);
157 } 163 }
158 164
159 TEST_F(WaitSetTest, CloseWhileWaiting) { 165 TEST_F(WaitSetTest, CloseWhileWaiting) {
160 MessagePipe p; 166 MessagePipe p;
161 WaitSet wait_set; 167 WaitSet wait_set;
162 168
163 wait_set.AddHandle(p.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE); 169 wait_set.AddHandle(p.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE);
164 170
165 const Handle handle0_value = p.handle0.get(); 171 const Handle handle0_value = p.handle0.get();
166 ThreadedRunner close_after_delay(base::Bind( 172 ThreadedRunner close_after_delay(base::Bind(
167 [](ScopedMessagePipeHandle* handle) { 173 [](ScopedMessagePipeHandle* handle) {
168 // Wait a little while, then close the handle. 174 // Wait a little while, then close the handle.
169 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(200)); 175 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(200));
170 handle->reset(); 176 handle->reset();
171 }, 177 },
172 &p.handle0)); 178 &p.handle0));
173 close_after_delay.Start(); 179 close_after_delay.Start();
174 180
175 size_t num_ready_handles = 2; 181 size_t num_ready_handles = 2;
176 Handle ready_handles[2]; 182 Handle ready_handles[2];
177 MojoResult ready_results[2] = {MOJO_RESULT_UNKNOWN, MOJO_RESULT_UNKNOWN}; 183 MojoResult ready_results[2] = {MOJO_RESULT_UNKNOWN, MOJO_RESULT_UNKNOWN};
178 wait_set.Wait(&num_ready_handles, ready_handles, ready_results); 184 wait_set.Wait(nullptr, &num_ready_handles, ready_handles, ready_results);
179 EXPECT_EQ(1u, num_ready_handles); 185 EXPECT_EQ(1u, num_ready_handles);
180 EXPECT_EQ(handle0_value, ready_handles[0]); 186 EXPECT_EQ(handle0_value, ready_handles[0]);
181 EXPECT_EQ(MOJO_RESULT_CANCELLED, ready_results[0]); 187 EXPECT_EQ(MOJO_RESULT_CANCELLED, ready_results[0]);
182 188
183 EXPECT_EQ(MOJO_RESULT_NOT_FOUND, wait_set.RemoveHandle(handle0_value)); 189 EXPECT_EQ(MOJO_RESULT_NOT_FOUND, wait_set.RemoveHandle(handle0_value));
184 } 190 }
185 191
186 TEST_F(WaitSetTest, CloseBeforeWaiting) { 192 TEST_F(WaitSetTest, CloseBeforeWaiting) {
187 MessagePipe p; 193 MessagePipe p;
188 WaitSet wait_set; 194 WaitSet wait_set;
189 195
190 wait_set.AddHandle(p.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE); 196 wait_set.AddHandle(p.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE);
191 wait_set.AddHandle(p.handle1.get(), MOJO_HANDLE_SIGNAL_READABLE); 197 wait_set.AddHandle(p.handle1.get(), MOJO_HANDLE_SIGNAL_READABLE);
192 198
193 Handle handle0_value = p.handle0.get(); 199 Handle handle0_value = p.handle0.get();
194 Handle handle1_value = p.handle1.get(); 200 Handle handle1_value = p.handle1.get();
195 201
196 p.handle0.reset(); 202 p.handle0.reset();
197 p.handle1.reset(); 203 p.handle1.reset();
198 204
199 // Ensure that the WaitSet user is always made aware of all cancellations even 205 // Ensure that the WaitSet user is always made aware of all cancellations even
200 // if they happen while not waiting, or they have to be returned over the span 206 // if they happen while not waiting, or they have to be returned over the span
201 // of multiple Wait() calls due to insufficient output storage. 207 // of multiple Wait() calls due to insufficient output storage.
202 208
203 size_t num_ready_handles = 1; 209 size_t num_ready_handles = 1;
204 Handle ready_handle; 210 Handle ready_handle;
205 MojoResult ready_result = MOJO_RESULT_UNKNOWN; 211 MojoResult ready_result = MOJO_RESULT_UNKNOWN;
206 wait_set.Wait(&num_ready_handles, &ready_handle, &ready_result); 212 wait_set.Wait(nullptr, &num_ready_handles, &ready_handle, &ready_result);
207 EXPECT_EQ(1u, num_ready_handles); 213 EXPECT_EQ(1u, num_ready_handles);
208 EXPECT_TRUE(ready_handle == handle0_value || ready_handle == handle1_value); 214 EXPECT_TRUE(ready_handle == handle0_value || ready_handle == handle1_value);
209 EXPECT_EQ(MOJO_RESULT_CANCELLED, ready_result); 215 EXPECT_EQ(MOJO_RESULT_CANCELLED, ready_result);
210 EXPECT_EQ(MOJO_RESULT_NOT_FOUND, wait_set.RemoveHandle(handle0_value)); 216 EXPECT_EQ(MOJO_RESULT_NOT_FOUND, wait_set.RemoveHandle(handle0_value));
211 217
212 wait_set.Wait(&num_ready_handles, &ready_handle, &ready_result); 218 wait_set.Wait(nullptr, &num_ready_handles, &ready_handle, &ready_result);
213 EXPECT_EQ(1u, num_ready_handles); 219 EXPECT_EQ(1u, num_ready_handles);
214 EXPECT_TRUE(ready_handle == handle0_value || ready_handle == handle1_value); 220 EXPECT_TRUE(ready_handle == handle0_value || ready_handle == handle1_value);
215 EXPECT_EQ(MOJO_RESULT_CANCELLED, ready_result); 221 EXPECT_EQ(MOJO_RESULT_CANCELLED, ready_result);
216 EXPECT_EQ(MOJO_RESULT_NOT_FOUND, wait_set.RemoveHandle(handle0_value)); 222 EXPECT_EQ(MOJO_RESULT_NOT_FOUND, wait_set.RemoveHandle(handle0_value));
217 223
218 // Nothing more to wait on. 224 // Nothing more to wait on.
219 wait_set.Wait(&num_ready_handles, &ready_handle, &ready_result); 225 wait_set.Wait(nullptr, &num_ready_handles, &ready_handle, &ready_result);
220 EXPECT_EQ(0u, num_ready_handles); 226 EXPECT_EQ(0u, num_ready_handles);
221 } 227 }
222 228
223 TEST_F(WaitSetTest, SatisfiedThenUnsatisfied) { 229 TEST_F(WaitSetTest, SatisfiedThenUnsatisfied) {
224 MessagePipe p; 230 MessagePipe p;
225 WaitSet wait_set; 231 WaitSet wait_set;
226 232
227 wait_set.AddHandle(p.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE); 233 wait_set.AddHandle(p.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE);
228 wait_set.AddHandle(p.handle1.get(), MOJO_HANDLE_SIGNAL_READABLE); 234 wait_set.AddHandle(p.handle1.get(), MOJO_HANDLE_SIGNAL_READABLE);
229 235
230 const char kTestMessage1[] = "testing testing testing"; 236 const char kTestMessage1[] = "testing testing testing";
231 WriteMessage(p.handle0, kTestMessage1); 237 WriteMessage(p.handle0, kTestMessage1);
232 238
233 size_t num_ready_handles = 2; 239 size_t num_ready_handles = 2;
234 Handle ready_handles[2]; 240 Handle ready_handles[2];
235 MojoResult ready_results[2] = {MOJO_RESULT_UNKNOWN, MOJO_RESULT_UNKNOWN}; 241 MojoResult ready_results[2] = {MOJO_RESULT_UNKNOWN, MOJO_RESULT_UNKNOWN};
236 wait_set.Wait(&num_ready_handles, ready_handles, ready_results); 242 wait_set.Wait(nullptr, &num_ready_handles, ready_handles, ready_results);
237 EXPECT_EQ(1u, num_ready_handles); 243 EXPECT_EQ(1u, num_ready_handles);
238 EXPECT_EQ(p.handle1.get(), ready_handles[0]); 244 EXPECT_EQ(p.handle1.get(), ready_handles[0]);
239 EXPECT_EQ(MOJO_RESULT_OK, ready_results[0]); 245 EXPECT_EQ(MOJO_RESULT_OK, ready_results[0]);
240 246
241 EXPECT_EQ(kTestMessage1, ReadMessage(p.handle1)); 247 EXPECT_EQ(kTestMessage1, ReadMessage(p.handle1));
242 248
243 ThreadedRunner write_after_delay(base::Bind( 249 ThreadedRunner write_after_delay(base::Bind(
244 [](ScopedMessagePipeHandle* handle) { 250 [](ScopedMessagePipeHandle* handle) {
245 // Wait a little while, then write a message. 251 // Wait a little while, then write a message.
246 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(200)); 252 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(200));
247 WriteMessage(*handle, "wakey wakey"); 253 WriteMessage(*handle, "wakey wakey");
248 }, 254 },
249 &p.handle1)); 255 &p.handle1));
250 write_after_delay.Start(); 256 write_after_delay.Start();
251 257
252 num_ready_handles = 2; 258 num_ready_handles = 2;
253 wait_set.Wait(&num_ready_handles, ready_handles, ready_results); 259 wait_set.Wait(nullptr, &num_ready_handles, ready_handles, ready_results);
254 EXPECT_EQ(1u, num_ready_handles); 260 EXPECT_EQ(1u, num_ready_handles);
255 EXPECT_EQ(p.handle0.get(), ready_handles[0]); 261 EXPECT_EQ(p.handle0.get(), ready_handles[0]);
256 EXPECT_EQ(MOJO_RESULT_OK, ready_results[0]); 262 EXPECT_EQ(MOJO_RESULT_OK, ready_results[0]);
257 } 263 }
258 264
265 TEST_F(WaitSetTest, EventOnly) {
266 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
267 base::WaitableEvent::InitialState::SIGNALED);
268 WaitSet wait_set;
269 wait_set.AddEvent(&event);
270
271 base::WaitableEvent* ready_event = nullptr;
272 size_t num_ready_handles = 1;
273 Handle ready_handle;
274 MojoResult ready_result = MOJO_RESULT_UNKNOWN;
275 wait_set.Wait(&ready_event, &num_ready_handles, &ready_handle, &ready_result);
276 EXPECT_EQ(0u, num_ready_handles);
277 EXPECT_EQ(&event, ready_event);
278 }
279
280 TEST_F(WaitSetTest, EventAndHandle) {
281 const char kTestMessage[] = "hello hello";
282
283 MessagePipe p;
284 WriteMessage(p.handle0, kTestMessage);
285
286 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
287 base::WaitableEvent::InitialState::NOT_SIGNALED);
288
289 WaitSet wait_set;
290 wait_set.AddHandle(p.handle1.get(), MOJO_HANDLE_SIGNAL_READABLE);
291 wait_set.AddEvent(&event);
292
293 base::WaitableEvent* ready_event = nullptr;
294 size_t num_ready_handles = 1;
295 Handle ready_handle;
296 MojoResult ready_result = MOJO_RESULT_UNKNOWN;
297 wait_set.Wait(&ready_event, &num_ready_handles, &ready_handle, &ready_result);
298 EXPECT_EQ(1u, num_ready_handles);
299 EXPECT_EQ(nullptr, ready_event);
300 EXPECT_EQ(p.handle1.get(), ready_handle);
301 EXPECT_EQ(MOJO_RESULT_OK, ready_result);
302
303 EXPECT_EQ(kTestMessage, ReadMessage(p.handle1));
304
305 ThreadedRunner signal_after_delay(base::Bind(
306 [](base::WaitableEvent* event) {
307 // Wait a little while, then close the handle.
308 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(200));
309 event->Signal();
310 },
311 &event));
312 signal_after_delay.Start();
313
314 wait_set.Wait(&ready_event, &num_ready_handles, &ready_handle, &ready_result);
315 EXPECT_EQ(0u, num_ready_handles);
316 EXPECT_EQ(&event, ready_event);
317 }
318
319 TEST_F(WaitSetTest, NoStarvation) {
320 const char kTestMessage[] = "wait for it";
321 const size_t kNumTestPipes = 50;
322 const size_t kNumTestEvents = 10;
323
324 // Create a bunch of handles and events which are always ready and add them
325 // to a shared WaitSet.
326
327 WaitSet wait_set;
328
329 MessagePipe pipes[kNumTestPipes];
330 for (size_t i = 0; i < kNumTestPipes; ++i) {
331 WriteMessage(pipes[i].handle0, kTestMessage);
332 Wait(pipes[i].handle1.get(), MOJO_HANDLE_SIGNAL_READABLE);
333
334 WriteMessage(pipes[i].handle1, kTestMessage);
335 Wait(pipes[i].handle0.get(), MOJO_HANDLE_SIGNAL_READABLE);
336
337 wait_set.AddHandle(pipes[i].handle0.get(), MOJO_HANDLE_SIGNAL_READABLE);
338 wait_set.AddHandle(pipes[i].handle1.get(), MOJO_HANDLE_SIGNAL_READABLE);
339 }
340
341 std::vector<std::unique_ptr<base::WaitableEvent>> events(kNumTestEvents);
342 for (auto& event_ptr : events) {
343 event_ptr = base::MakeUnique<base::WaitableEvent>(
344 base::WaitableEvent::ResetPolicy::MANUAL,
345 base::WaitableEvent::InitialState::NOT_SIGNALED);
346 event_ptr->Signal();
347 wait_set.AddEvent(event_ptr.get());
348 }
349
350 // Now verify that all handle and event signals are deteceted within a finite
351 // number of consecutive Wait() calls. Do it a few times for good measure.
352 for (size_t i = 0; i < 3; ++i) {
353 std::set<base::WaitableEvent*> ready_events;
354 std::set<Handle> ready_handles;
355 while (ready_events.size() < kNumTestEvents ||
356 ready_handles.size() < kNumTestPipes * 2) {
357 base::WaitableEvent* ready_event = nullptr;
358 size_t num_ready_handles = 1;
359 Handle ready_handle;
360 MojoResult ready_result = MOJO_RESULT_UNKNOWN;
361 wait_set.Wait(&ready_event, &num_ready_handles, &ready_handle,
362 &ready_result);
363 if (ready_event)
364 ready_events.insert(ready_event);
365
366 if (num_ready_handles) {
367 EXPECT_EQ(1u, num_ready_handles);
368 EXPECT_EQ(MOJO_RESULT_OK, ready_result);
369 ready_handles.insert(ready_handle);
370 }
371 }
372 }
373 }
374
259 } // namespace 375 } // namespace
260 } // namespace mojo 376 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/sync_handle_registry.h ('k') | mojo/public/cpp/system/wait_set.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698