OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/edk/system/wait_set_dispatcher.h" | 5 #include "mojo/edk/system/wait_set_dispatcher.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
11 | 11 |
12 #include "base/macros.h" | 12 #include "base/macros.h" |
13 #include "base/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" |
14 #include "mojo/edk/embedder/embedder_internal.h" | 14 #include "mojo/edk/embedder/embedder_internal.h" |
15 #include "mojo/edk/system/core.h" | 15 #include "mojo/edk/system/core.h" |
| 16 #include "mojo/edk/system/message_for_transit.h" |
16 #include "mojo/edk/system/message_pipe_dispatcher.h" | 17 #include "mojo/edk/system/message_pipe_dispatcher.h" |
17 #include "mojo/edk/system/request_context.h" | 18 #include "mojo/edk/system/request_context.h" |
18 #include "mojo/edk/system/test_utils.h" | 19 #include "mojo/edk/system/test_utils.h" |
19 #include "mojo/edk/system/waiter.h" | 20 #include "mojo/edk/system/waiter.h" |
20 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
21 | 22 |
22 namespace mojo { | 23 namespace mojo { |
23 namespace edk { | 24 namespace edk { |
24 namespace { | 25 namespace { |
25 | 26 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 pipe_id_generator_++; | 68 pipe_id_generator_++; |
68 | 69 |
69 dispatchers_to_close_.push_back(*d0); | 70 dispatchers_to_close_.push_back(*d0); |
70 dispatchers_to_close_.push_back(*d1); | 71 dispatchers_to_close_.push_back(*d1); |
71 } | 72 } |
72 | 73 |
73 void CloseOnShutdown(const scoped_refptr<Dispatcher>& dispatcher) { | 74 void CloseOnShutdown(const scoped_refptr<Dispatcher>& dispatcher) { |
74 dispatchers_to_close_.push_back(dispatcher); | 75 dispatchers_to_close_.push_back(dispatcher); |
75 } | 76 } |
76 | 77 |
| 78 void WriteMessage(MessagePipeDispatcher* dispatcher, |
| 79 const void* bytes, |
| 80 size_t num_bytes) { |
| 81 Core* core = mojo::edk::internal::g_core; |
| 82 void* msg; |
| 83 ASSERT_EQ(MOJO_RESULT_OK, |
| 84 core->CreateMessage(num_bytes, nullptr, 0, |
| 85 MOJO_CREATE_MESSAGE_FLAG_NONE, &msg)); |
| 86 void* buffer; |
| 87 ASSERT_EQ(MOJO_RESULT_OK, core->GetMessageBuffer(msg, &buffer)); |
| 88 memcpy(buffer, bytes, num_bytes); |
| 89 |
| 90 std::unique_ptr<MessageForTransit> message( |
| 91 static_cast<MessageForTransit*>(msg)); |
| 92 ASSERT_EQ(MOJO_RESULT_OK, |
| 93 dispatcher->WriteMessage(std::move(message), |
| 94 MOJO_WRITE_MESSAGE_FLAG_NONE)); |
| 95 } |
| 96 |
| 97 void ReadMessage(MessagePipeDispatcher* dispatcher, |
| 98 void* bytes, |
| 99 uint32_t* num_bytes) { |
| 100 Core* core = mojo::edk::internal::g_core; |
| 101 std::unique_ptr<MessageForTransit> message; |
| 102 ASSERT_EQ(MOJO_RESULT_OK, |
| 103 dispatcher->ReadMessage(&message, num_bytes, nullptr, 0, |
| 104 MOJO_READ_MESSAGE_FLAG_NONE, false)); |
| 105 void* buffer; |
| 106 ASSERT_EQ(MOJO_RESULT_OK, |
| 107 core->GetMessageBuffer(static_cast<void*>(message.get()), |
| 108 &buffer)); |
| 109 memcpy(buffer, bytes, *num_bytes); |
| 110 } |
| 111 |
77 protected: | 112 protected: |
78 scoped_refptr<MessagePipeDispatcher> dispatcher0_; | 113 scoped_refptr<MessagePipeDispatcher> dispatcher0_; |
79 scoped_refptr<MessagePipeDispatcher> dispatcher1_; | 114 scoped_refptr<MessagePipeDispatcher> dispatcher1_; |
80 | 115 |
81 private: | 116 private: |
82 // We keep an active RequestContext for the duration of each test. It's unused | 117 // We keep an active RequestContext for the duration of each test. It's unused |
83 // since these tests don't rely on the MojoWatch API. | 118 // since these tests don't rely on the MojoWatch API. |
84 const RequestContext request_context_; | 119 const RequestContext request_context_; |
85 | 120 |
86 static uint64_t pipe_id_generator_; | 121 static uint64_t pipe_id_generator_; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 EXPECT_EQ(MOJO_RESULT_OK, | 168 EXPECT_EQ(MOJO_RESULT_OK, |
134 wait_set->AddAwakable(&w, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss)); | 169 wait_set->AddAwakable(&w, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss)); |
135 EXPECT_FALSE(hss.satisfies(MOJO_HANDLE_SIGNAL_READABLE)); | 170 EXPECT_FALSE(hss.satisfies(MOJO_HANDLE_SIGNAL_READABLE)); |
136 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, w.Wait(0, nullptr)); | 171 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, w.Wait(0, nullptr)); |
137 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | 172 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, |
138 GetOneReadyDispatcher(wait_set, &woken_dispatcher, nullptr)); | 173 GetOneReadyDispatcher(wait_set, &woken_dispatcher, nullptr)); |
139 | 174 |
140 // Write to |dispatcher1_|, which should make |dispatcher0_| readable. | 175 // Write to |dispatcher1_|, which should make |dispatcher0_| readable. |
141 char buffer[] = "abcd"; | 176 char buffer[] = "abcd"; |
142 w.Init(); | 177 w.Init(); |
143 ASSERT_EQ(MOJO_RESULT_OK, | 178 WriteMessage(dispatcher1_.get(), buffer, sizeof(buffer)); |
144 dispatcher1_->WriteMessage(buffer, sizeof(buffer), nullptr, 0, | |
145 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
146 EXPECT_EQ(MOJO_RESULT_OK, w.Wait(MOJO_DEADLINE_INDEFINITE, nullptr)); | 179 EXPECT_EQ(MOJO_RESULT_OK, w.Wait(MOJO_DEADLINE_INDEFINITE, nullptr)); |
147 woken_dispatcher = nullptr; | 180 woken_dispatcher = nullptr; |
148 context = 0; | 181 context = 0; |
149 EXPECT_EQ(MOJO_RESULT_OK, | 182 EXPECT_EQ(MOJO_RESULT_OK, |
150 GetOneReadyDispatcher(wait_set, &woken_dispatcher, &context)); | 183 GetOneReadyDispatcher(wait_set, &woken_dispatcher, &context)); |
151 EXPECT_EQ(dispatcher0_, woken_dispatcher); | 184 EXPECT_EQ(dispatcher0_, woken_dispatcher); |
152 EXPECT_EQ(1u, context); | 185 EXPECT_EQ(1u, context); |
153 | 186 |
154 // Again, if a ready dispatcher isn't removed, it will continue to be | 187 // Again, if a ready dispatcher isn't removed, it will continue to be |
155 // returned. | 188 // returned. |
(...skipping 24 matching lines...) Expand all Loading... |
180 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, w.Wait(0, nullptr)); | 213 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, w.Wait(0, nullptr)); |
181 scoped_refptr<Dispatcher> woken_dispatcher; | 214 scoped_refptr<Dispatcher> woken_dispatcher; |
182 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | 215 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, |
183 GetOneReadyDispatcher(wait_set, &woken_dispatcher, nullptr)); | 216 GetOneReadyDispatcher(wait_set, &woken_dispatcher, nullptr)); |
184 | 217 |
185 // The tested behaviour below should be repeatable. | 218 // The tested behaviour below should be repeatable. |
186 for (size_t i = 0; i < 3; i++) { | 219 for (size_t i = 0; i < 3; i++) { |
187 // Write to |dispatcher1_|, which should make |dispatcher0_| readable. | 220 // Write to |dispatcher1_|, which should make |dispatcher0_| readable. |
188 char buffer[] = "abcd"; | 221 char buffer[] = "abcd"; |
189 w.Init(); | 222 w.Init(); |
190 ASSERT_EQ(MOJO_RESULT_OK, | 223 WriteMessage(dispatcher1_.get(), buffer, sizeof(buffer)); |
191 dispatcher1_->WriteMessage(buffer, sizeof(buffer), nullptr, 0, | |
192 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
193 EXPECT_EQ(MOJO_RESULT_OK, w.Wait(MOJO_DEADLINE_INDEFINITE, nullptr)); | 224 EXPECT_EQ(MOJO_RESULT_OK, w.Wait(MOJO_DEADLINE_INDEFINITE, nullptr)); |
194 woken_dispatcher = nullptr; | 225 woken_dispatcher = nullptr; |
195 context = 0; | 226 context = 0; |
196 EXPECT_EQ(MOJO_RESULT_OK, | 227 EXPECT_EQ(MOJO_RESULT_OK, |
197 GetOneReadyDispatcher(wait_set, &woken_dispatcher, &context)); | 228 GetOneReadyDispatcher(wait_set, &woken_dispatcher, &context)); |
198 EXPECT_EQ(dispatcher0_, woken_dispatcher); | 229 EXPECT_EQ(dispatcher0_, woken_dispatcher); |
199 EXPECT_EQ(1u, context); | 230 EXPECT_EQ(1u, context); |
200 | 231 |
201 // Read from |dispatcher0_| which should change it's state to non-readable. | 232 // Read from |dispatcher0_| which should change it's state to non-readable. |
202 char read_buffer[sizeof(buffer) + 5]; | 233 char read_buffer[sizeof(buffer) + 5]; |
203 uint32_t num_bytes = sizeof(read_buffer); | 234 uint32_t num_bytes = sizeof(read_buffer); |
204 ASSERT_EQ(MOJO_RESULT_OK, | 235 ReadMessage(dispatcher0_.get(), read_buffer, &num_bytes); |
205 dispatcher0_->ReadMessage(read_buffer, &num_bytes, nullptr, | |
206 nullptr, MOJO_READ_MESSAGE_FLAG_NONE)); | |
207 EXPECT_EQ(sizeof(buffer), num_bytes); | 236 EXPECT_EQ(sizeof(buffer), num_bytes); |
208 | 237 |
209 // No dispatchers are ready. | 238 // No dispatchers are ready. |
210 w.Init(); | 239 w.Init(); |
211 woken_dispatcher = nullptr; | 240 woken_dispatcher = nullptr; |
212 context = 0; | 241 context = 0; |
213 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | 242 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, |
214 GetOneReadyDispatcher(wait_set, &woken_dispatcher, &context)); | 243 GetOneReadyDispatcher(wait_set, &woken_dispatcher, &context)); |
215 EXPECT_EQ(nullptr, woken_dispatcher); | 244 EXPECT_EQ(nullptr, woken_dispatcher); |
216 EXPECT_EQ(0u, context); | 245 EXPECT_EQ(0u, context); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 &dispatchers_vector, | 336 &dispatchers_vector, |
308 results, | 337 results, |
309 nullptr)); | 338 nullptr)); |
310 EXPECT_EQ(2u, count); | 339 EXPECT_EQ(2u, count); |
311 std::sort(dispatchers_vector.begin(), dispatchers_vector.end()); | 340 std::sort(dispatchers_vector.begin(), dispatchers_vector.end()); |
312 EXPECT_EQ(expected_dispatchers, dispatchers_vector); | 341 EXPECT_EQ(expected_dispatchers, dispatchers_vector); |
313 | 342 |
314 // Write to |dispatcher1_|, which should make |dispatcher0_| readable. | 343 // Write to |dispatcher1_|, which should make |dispatcher0_| readable. |
315 char buffer[] = "abcd"; | 344 char buffer[] = "abcd"; |
316 w.Init(); | 345 w.Init(); |
317 ASSERT_EQ(MOJO_RESULT_OK, | 346 WriteMessage(dispatcher1_.get(), buffer, sizeof(buffer)); |
318 dispatcher1_->WriteMessage(buffer, sizeof(buffer), nullptr, 0, | |
319 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
320 { | 347 { |
321 Waiter mp_w; | 348 Waiter mp_w; |
322 mp_w.Init(); | 349 mp_w.Init(); |
323 // Wait for |dispatcher0_| to be readable. | 350 // Wait for |dispatcher0_| to be readable. |
324 if (dispatcher0_->AddAwakable(&mp_w, MOJO_HANDLE_SIGNAL_READABLE, 0, | 351 if (dispatcher0_->AddAwakable(&mp_w, MOJO_HANDLE_SIGNAL_READABLE, 0, |
325 nullptr) == MOJO_RESULT_OK) { | 352 nullptr) == MOJO_RESULT_OK) { |
326 EXPECT_EQ(MOJO_RESULT_OK, mp_w.Wait(MOJO_DEADLINE_INDEFINITE, 0)); | 353 EXPECT_EQ(MOJO_RESULT_OK, mp_w.Wait(MOJO_DEADLINE_INDEFINITE, 0)); |
327 dispatcher0_->RemoveAwakable(&mp_w, nullptr); | 354 dispatcher0_->RemoveAwakable(&mp_w, nullptr); |
328 } | 355 } |
329 } | 356 } |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 EXPECT_EQ(MOJO_RESULT_OK, | 489 EXPECT_EQ(MOJO_RESULT_OK, |
463 GetOneReadyDispatcher(wait_set, &woken_dispatcher, nullptr)); | 490 GetOneReadyDispatcher(wait_set, &woken_dispatcher, nullptr)); |
464 EXPECT_EQ(nested_wait_set, woken_dispatcher); | 491 EXPECT_EQ(nested_wait_set, woken_dispatcher); |
465 | 492 |
466 wait_set->RemoveAwakable(&w, nullptr); | 493 wait_set->RemoveAwakable(&w, nullptr); |
467 } | 494 } |
468 | 495 |
469 } // namespace | 496 } // namespace |
470 } // namespace edk | 497 } // namespace edk |
471 } // namespace mojo | 498 } // namespace mojo |
OLD | NEW |