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 MojoMessageHandle msg; |
| 83 ASSERT_EQ(MOJO_RESULT_OK, |
| 84 core->AllocMessage(static_cast<uint32_t>(num_bytes), nullptr, 0, |
| 85 MOJO_ALLOC_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 reinterpret_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 std::unique_ptr<MessageForTransit> message; |
| 101 ASSERT_EQ(MOJO_RESULT_OK, |
| 102 dispatcher->ReadMessage(&message, num_bytes, nullptr, 0, |
| 103 MOJO_READ_MESSAGE_FLAG_NONE, false)); |
| 104 memcpy(bytes, message->bytes(), *num_bytes); |
| 105 } |
| 106 |
77 protected: | 107 protected: |
78 scoped_refptr<MessagePipeDispatcher> dispatcher0_; | 108 scoped_refptr<MessagePipeDispatcher> dispatcher0_; |
79 scoped_refptr<MessagePipeDispatcher> dispatcher1_; | 109 scoped_refptr<MessagePipeDispatcher> dispatcher1_; |
80 | 110 |
81 private: | 111 private: |
82 // We keep an active RequestContext for the duration of each test. It's unused | 112 // 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. | 113 // since these tests don't rely on the MojoWatch API. |
84 const RequestContext request_context_; | 114 const RequestContext request_context_; |
85 | 115 |
86 static uint64_t pipe_id_generator_; | 116 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, | 163 EXPECT_EQ(MOJO_RESULT_OK, |
134 wait_set->AddAwakable(&w, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss)); | 164 wait_set->AddAwakable(&w, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss)); |
135 EXPECT_FALSE(hss.satisfies(MOJO_HANDLE_SIGNAL_READABLE)); | 165 EXPECT_FALSE(hss.satisfies(MOJO_HANDLE_SIGNAL_READABLE)); |
136 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, w.Wait(0, nullptr)); | 166 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, w.Wait(0, nullptr)); |
137 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | 167 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, |
138 GetOneReadyDispatcher(wait_set, &woken_dispatcher, nullptr)); | 168 GetOneReadyDispatcher(wait_set, &woken_dispatcher, nullptr)); |
139 | 169 |
140 // Write to |dispatcher1_|, which should make |dispatcher0_| readable. | 170 // Write to |dispatcher1_|, which should make |dispatcher0_| readable. |
141 char buffer[] = "abcd"; | 171 char buffer[] = "abcd"; |
142 w.Init(); | 172 w.Init(); |
143 ASSERT_EQ(MOJO_RESULT_OK, | 173 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)); | 174 EXPECT_EQ(MOJO_RESULT_OK, w.Wait(MOJO_DEADLINE_INDEFINITE, nullptr)); |
147 woken_dispatcher = nullptr; | 175 woken_dispatcher = nullptr; |
148 context = 0; | 176 context = 0; |
149 EXPECT_EQ(MOJO_RESULT_OK, | 177 EXPECT_EQ(MOJO_RESULT_OK, |
150 GetOneReadyDispatcher(wait_set, &woken_dispatcher, &context)); | 178 GetOneReadyDispatcher(wait_set, &woken_dispatcher, &context)); |
151 EXPECT_EQ(dispatcher0_, woken_dispatcher); | 179 EXPECT_EQ(dispatcher0_, woken_dispatcher); |
152 EXPECT_EQ(1u, context); | 180 EXPECT_EQ(1u, context); |
153 | 181 |
154 // Again, if a ready dispatcher isn't removed, it will continue to be | 182 // Again, if a ready dispatcher isn't removed, it will continue to be |
155 // returned. | 183 // returned. |
(...skipping 24 matching lines...) Expand all Loading... |
180 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, w.Wait(0, nullptr)); | 208 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, w.Wait(0, nullptr)); |
181 scoped_refptr<Dispatcher> woken_dispatcher; | 209 scoped_refptr<Dispatcher> woken_dispatcher; |
182 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | 210 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, |
183 GetOneReadyDispatcher(wait_set, &woken_dispatcher, nullptr)); | 211 GetOneReadyDispatcher(wait_set, &woken_dispatcher, nullptr)); |
184 | 212 |
185 // The tested behaviour below should be repeatable. | 213 // The tested behaviour below should be repeatable. |
186 for (size_t i = 0; i < 3; i++) { | 214 for (size_t i = 0; i < 3; i++) { |
187 // Write to |dispatcher1_|, which should make |dispatcher0_| readable. | 215 // Write to |dispatcher1_|, which should make |dispatcher0_| readable. |
188 char buffer[] = "abcd"; | 216 char buffer[] = "abcd"; |
189 w.Init(); | 217 w.Init(); |
190 ASSERT_EQ(MOJO_RESULT_OK, | 218 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)); | 219 EXPECT_EQ(MOJO_RESULT_OK, w.Wait(MOJO_DEADLINE_INDEFINITE, nullptr)); |
194 woken_dispatcher = nullptr; | 220 woken_dispatcher = nullptr; |
195 context = 0; | 221 context = 0; |
196 EXPECT_EQ(MOJO_RESULT_OK, | 222 EXPECT_EQ(MOJO_RESULT_OK, |
197 GetOneReadyDispatcher(wait_set, &woken_dispatcher, &context)); | 223 GetOneReadyDispatcher(wait_set, &woken_dispatcher, &context)); |
198 EXPECT_EQ(dispatcher0_, woken_dispatcher); | 224 EXPECT_EQ(dispatcher0_, woken_dispatcher); |
199 EXPECT_EQ(1u, context); | 225 EXPECT_EQ(1u, context); |
200 | 226 |
201 // Read from |dispatcher0_| which should change it's state to non-readable. | 227 // Read from |dispatcher0_| which should change it's state to non-readable. |
202 char read_buffer[sizeof(buffer) + 5]; | 228 char read_buffer[sizeof(buffer) + 5]; |
203 uint32_t num_bytes = sizeof(read_buffer); | 229 uint32_t num_bytes = sizeof(read_buffer); |
204 ASSERT_EQ(MOJO_RESULT_OK, | 230 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); | 231 EXPECT_EQ(sizeof(buffer), num_bytes); |
208 | 232 |
209 // No dispatchers are ready. | 233 // No dispatchers are ready. |
210 w.Init(); | 234 w.Init(); |
211 woken_dispatcher = nullptr; | 235 woken_dispatcher = nullptr; |
212 context = 0; | 236 context = 0; |
213 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | 237 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, |
214 GetOneReadyDispatcher(wait_set, &woken_dispatcher, &context)); | 238 GetOneReadyDispatcher(wait_set, &woken_dispatcher, &context)); |
215 EXPECT_EQ(nullptr, woken_dispatcher); | 239 EXPECT_EQ(nullptr, woken_dispatcher); |
216 EXPECT_EQ(0u, context); | 240 EXPECT_EQ(0u, context); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 &dispatchers_vector, | 331 &dispatchers_vector, |
308 results, | 332 results, |
309 nullptr)); | 333 nullptr)); |
310 EXPECT_EQ(2u, count); | 334 EXPECT_EQ(2u, count); |
311 std::sort(dispatchers_vector.begin(), dispatchers_vector.end()); | 335 std::sort(dispatchers_vector.begin(), dispatchers_vector.end()); |
312 EXPECT_EQ(expected_dispatchers, dispatchers_vector); | 336 EXPECT_EQ(expected_dispatchers, dispatchers_vector); |
313 | 337 |
314 // Write to |dispatcher1_|, which should make |dispatcher0_| readable. | 338 // Write to |dispatcher1_|, which should make |dispatcher0_| readable. |
315 char buffer[] = "abcd"; | 339 char buffer[] = "abcd"; |
316 w.Init(); | 340 w.Init(); |
317 ASSERT_EQ(MOJO_RESULT_OK, | 341 WriteMessage(dispatcher1_.get(), buffer, sizeof(buffer)); |
318 dispatcher1_->WriteMessage(buffer, sizeof(buffer), nullptr, 0, | |
319 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
320 { | 342 { |
321 Waiter mp_w; | 343 Waiter mp_w; |
322 mp_w.Init(); | 344 mp_w.Init(); |
323 // Wait for |dispatcher0_| to be readable. | 345 // Wait for |dispatcher0_| to be readable. |
324 if (dispatcher0_->AddAwakable(&mp_w, MOJO_HANDLE_SIGNAL_READABLE, 0, | 346 if (dispatcher0_->AddAwakable(&mp_w, MOJO_HANDLE_SIGNAL_READABLE, 0, |
325 nullptr) == MOJO_RESULT_OK) { | 347 nullptr) == MOJO_RESULT_OK) { |
326 EXPECT_EQ(MOJO_RESULT_OK, mp_w.Wait(MOJO_DEADLINE_INDEFINITE, 0)); | 348 EXPECT_EQ(MOJO_RESULT_OK, mp_w.Wait(MOJO_DEADLINE_INDEFINITE, 0)); |
327 dispatcher0_->RemoveAwakable(&mp_w, nullptr); | 349 dispatcher0_->RemoveAwakable(&mp_w, nullptr); |
328 } | 350 } |
329 } | 351 } |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 EXPECT_EQ(MOJO_RESULT_OK, | 484 EXPECT_EQ(MOJO_RESULT_OK, |
463 GetOneReadyDispatcher(wait_set, &woken_dispatcher, nullptr)); | 485 GetOneReadyDispatcher(wait_set, &woken_dispatcher, nullptr)); |
464 EXPECT_EQ(nested_wait_set, woken_dispatcher); | 486 EXPECT_EQ(nested_wait_set, woken_dispatcher); |
465 | 487 |
466 wait_set->RemoveAwakable(&w, nullptr); | 488 wait_set->RemoveAwakable(&w, nullptr); |
467 } | 489 } |
468 | 490 |
469 } // namespace | 491 } // namespace |
470 } // namespace edk | 492 } // namespace edk |
471 } // namespace mojo | 493 } // namespace mojo |
OLD | NEW |