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