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