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

Unified Diff: third_party/mojo/src/mojo/edk/system/wait_set_dispatcher_unittest.cc

Issue 1461213002: WaitSet implementation for old EDK. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mojo-waitset-skeleton
Patch Set: Fix windows build and style issues. Created 5 years 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/mojo/src/mojo/edk/system/wait_set_dispatcher.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/mojo/src/mojo/edk/system/wait_set_dispatcher_unittest.cc
diff --git a/third_party/mojo/src/mojo/edk/system/wait_set_dispatcher_unittest.cc b/third_party/mojo/src/mojo/edk/system/wait_set_dispatcher_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..86f5e3663e3bc7f15e4345876e5602be75d6d7fe
--- /dev/null
+++ b/third_party/mojo/src/mojo/edk/system/wait_set_dispatcher_unittest.cc
@@ -0,0 +1,459 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/mojo/src/mojo/edk/system/wait_set_dispatcher.h"
+
+#include <algorithm>
+
+#include "base/memory/ref_counted.h"
+#include "mojo/public/cpp/system/macros.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/mojo/src/mojo/edk/system/message_pipe.h"
+#include "third_party/mojo/src/mojo/edk/system/message_pipe_dispatcher.h"
+#include "third_party/mojo/src/mojo/edk/system/test_utils.h"
+#include "third_party/mojo/src/mojo/edk/system/waiter.h"
+
+namespace mojo {
+namespace system {
+namespace {
+
+class WaitSetDispatcherTest : public ::testing::Test {
+ public:
+ WaitSetDispatcherTest() {}
+ ~WaitSetDispatcherTest() override {}
+
+ void SetUp() override {
+ dispatcher0_ = MessagePipeDispatcher::Create(
+ MessagePipeDispatcher::kDefaultCreateOptions);
+ dispatcher1_ = MessagePipeDispatcher::Create(
+ MessagePipeDispatcher::kDefaultCreateOptions);
+
+ scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
+ dispatcher0_->Init(mp, 0);
+ dispatcher1_->Init(mp, 1);
+
+ dispatchers_to_close_.push_back(dispatcher0_);
+ dispatchers_to_close_.push_back(dispatcher1_);
+ }
+
+ void TearDown() override {
+ for (auto& d : dispatchers_to_close_)
+ d->Close();
+ }
+
+ MojoResult GetOneReadyDispatcher(
+ const scoped_refptr<WaitSetDispatcher>& wait_set,
+ scoped_refptr<Dispatcher>* ready_dispatcher,
+ uintptr_t* context) {
+ uint32_t count = 1;
+ MojoResult dispatcher_result = MOJO_RESULT_UNKNOWN;
+ DispatcherVector dispatchers;
+ MojoResult result = wait_set->GetReadyDispatchers(
+ MakeUserPointer(&count),
+ &dispatchers,
+ MakeUserPointer(&dispatcher_result),
+ MakeUserPointer(context));
+ if (result == MOJO_RESULT_OK) {
+ CHECK_EQ(1u, dispatchers.size());
+ *ready_dispatcher = dispatchers[0];
+ return dispatcher_result;
+ }
+ return result;
+ }
+
+ void CloseOnShutdown(const scoped_refptr<Dispatcher>& dispatcher) {
+ dispatchers_to_close_.push_back(dispatcher);
+ }
+
+ protected:
+ scoped_refptr<MessagePipeDispatcher> dispatcher0_;
+ scoped_refptr<MessagePipeDispatcher> dispatcher1_;
+
+ DispatcherVector dispatchers_to_close_;
+
+ DISALLOW_COPY_AND_ASSIGN(WaitSetDispatcherTest);
+};
+
+TEST_F(WaitSetDispatcherTest, Basic) {
+ scoped_refptr<WaitSetDispatcher> wait_set = new WaitSetDispatcher();
+ CloseOnShutdown(wait_set);
+ ASSERT_EQ(MOJO_RESULT_OK,
+ wait_set->AddWaitingDispatcher(dispatcher0_,
+ MOJO_HANDLE_SIGNAL_READABLE, 1));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ wait_set->AddWaitingDispatcher(dispatcher1_,
+ MOJO_HANDLE_SIGNAL_WRITABLE, 2));
+
+ Waiter w;
+ uintptr_t context = 0;
+ w.Init();
+ HandleSignalsState hss;
+ // |dispatcher1_| should already be writable.
+ EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
+ wait_set->AddAwakable(&w, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
+
+ scoped_refptr<Dispatcher> woken_dispatcher;
+ EXPECT_EQ(MOJO_RESULT_OK,
+ GetOneReadyDispatcher(wait_set, &woken_dispatcher, &context));
+ EXPECT_EQ(dispatcher1_, woken_dispatcher);
+ EXPECT_EQ(2u, context);
+ // If a ready dispatcher isn't removed, it will continue to be returned.
+ EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
+ wait_set->AddAwakable(&w, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
+ woken_dispatcher = nullptr;
+ context = 0;
+ EXPECT_EQ(MOJO_RESULT_OK,
+ GetOneReadyDispatcher(wait_set, &woken_dispatcher, &context));
+ EXPECT_EQ(dispatcher1_, woken_dispatcher);
+ EXPECT_EQ(2u, context);
+ ASSERT_EQ(MOJO_RESULT_OK, wait_set->RemoveWaitingDispatcher(dispatcher1_));
+
+ // No ready dispatcher.
+ hss = HandleSignalsState();
+ EXPECT_EQ(MOJO_RESULT_OK,
+ wait_set->AddAwakable(&w, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
+ EXPECT_FALSE(hss.satisfies(MOJO_HANDLE_SIGNAL_READABLE));
+ EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, w.Wait(0, nullptr));
+ EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
+ GetOneReadyDispatcher(wait_set, &woken_dispatcher, nullptr));
+
+ // Write to |dispatcher1_|, which should make |dispatcher0_| readable.
+ char buffer[] = "abcd";
+ w.Init();
+ ASSERT_EQ(MOJO_RESULT_OK,
+ dispatcher1_->WriteMessage(UserPointer<const void>(buffer),
+ sizeof(buffer), nullptr,
+ MOJO_WRITE_MESSAGE_FLAG_NONE));
+ EXPECT_EQ(MOJO_RESULT_OK, w.Wait(0, nullptr));
+ woken_dispatcher = nullptr;
+ context = 0;
+ EXPECT_EQ(MOJO_RESULT_OK,
+ GetOneReadyDispatcher(wait_set, &woken_dispatcher, &context));
+ EXPECT_EQ(dispatcher0_, woken_dispatcher);
+ EXPECT_EQ(1u, context);
+
+ // Again, if a ready dispatcher isn't removed, it will continue to be
+ // returned.
+ woken_dispatcher = nullptr;
+ EXPECT_EQ(MOJO_RESULT_OK,
+ GetOneReadyDispatcher(wait_set, &woken_dispatcher, nullptr));
+ EXPECT_EQ(dispatcher0_, woken_dispatcher);
+
+ wait_set->RemoveAwakable(&w, nullptr);
+}
+
+TEST_F(WaitSetDispatcherTest, HandleWithoutRemoving) {
+ scoped_refptr<WaitSetDispatcher> wait_set = new WaitSetDispatcher();
+ CloseOnShutdown(wait_set);
+ ASSERT_EQ(MOJO_RESULT_OK,
+ wait_set->AddWaitingDispatcher(dispatcher0_,
+ MOJO_HANDLE_SIGNAL_READABLE, 1));
+
+ Waiter w;
+ uintptr_t context = 0;
+ w.Init();
+ HandleSignalsState hss;
+ // No ready dispatcher.
+ hss = HandleSignalsState();
+ EXPECT_EQ(MOJO_RESULT_OK,
+ wait_set->AddAwakable(&w, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
+ EXPECT_FALSE(hss.satisfies(MOJO_HANDLE_SIGNAL_READABLE));
+ EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, w.Wait(0, nullptr));
+ scoped_refptr<Dispatcher> woken_dispatcher;
+ EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
+ GetOneReadyDispatcher(wait_set, &woken_dispatcher, nullptr));
+
+ // The tested behaviour below should be repeatable.
+ for (size_t i = 0; i < 3; i++) {
+ // Write to |dispatcher1_|, which should make |dispatcher0_| readable.
+ char buffer[] = "abcd";
+ w.Init();
+ ASSERT_EQ(MOJO_RESULT_OK,
+ dispatcher1_->WriteMessage(UserPointer<const void>(buffer),
+ sizeof(buffer), nullptr,
+ MOJO_WRITE_MESSAGE_FLAG_NONE));
+ EXPECT_EQ(MOJO_RESULT_OK, w.Wait(0, nullptr));
+ woken_dispatcher = nullptr;
+ context = 0;
+ EXPECT_EQ(MOJO_RESULT_OK,
+ GetOneReadyDispatcher(wait_set, &woken_dispatcher, &context));
+ EXPECT_EQ(dispatcher0_, woken_dispatcher);
+ EXPECT_EQ(1u, context);
+
+ // Read from |dispatcher0_| which should change it's state to non-readable.
+ char read_buffer[sizeof(buffer) + 5];
+ uint32_t num_bytes = sizeof(read_buffer);
+ ASSERT_EQ(MOJO_RESULT_OK,
+ dispatcher0_->ReadMessage(UserPointer<void>(read_buffer),
+ MakeUserPointer(&num_bytes),
+ nullptr, nullptr,
+ MOJO_READ_MESSAGE_FLAG_NONE));
+ EXPECT_EQ(sizeof(buffer), num_bytes);
+
+ // No dispatchers are ready.
+ w.Init();
+ woken_dispatcher = nullptr;
+ context = 0;
+ EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
+ GetOneReadyDispatcher(wait_set, &woken_dispatcher, &context));
+ EXPECT_EQ(nullptr, woken_dispatcher);
+ EXPECT_EQ(0u, context);
+ EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, w.Wait(0, nullptr));
+ }
+
+ wait_set->RemoveAwakable(&w, nullptr);
+}
+
+TEST_F(WaitSetDispatcherTest, MultipleReady) {
+ scoped_refptr<WaitSetDispatcher> wait_set = new WaitSetDispatcher();
+ CloseOnShutdown(wait_set);
+
+ scoped_refptr<MessagePipeDispatcher> mp1_dispatcher0 =
+ MessagePipeDispatcher::Create(
+ MessagePipeDispatcher::kDefaultCreateOptions);
+ scoped_refptr<MessagePipeDispatcher> mp1_dispatcher1 =
+ MessagePipeDispatcher::Create(
+ MessagePipeDispatcher::kDefaultCreateOptions);
+ CloseOnShutdown(mp1_dispatcher0);
+ CloseOnShutdown(mp1_dispatcher1);
+ {
+ scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
+ mp1_dispatcher0->Init(mp, 0);
+ mp1_dispatcher1->Init(mp, 1);
+ }
+
+ ASSERT_EQ(MOJO_RESULT_OK,
+ wait_set->AddWaitingDispatcher(dispatcher0_,
+ MOJO_HANDLE_SIGNAL_READABLE, 0));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ wait_set->AddWaitingDispatcher(dispatcher1_,
+ MOJO_HANDLE_SIGNAL_WRITABLE, 0));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ wait_set->AddWaitingDispatcher(mp1_dispatcher0,
+ MOJO_HANDLE_SIGNAL_WRITABLE, 0));
+ ASSERT_EQ(MOJO_RESULT_OK,
+ wait_set->AddWaitingDispatcher(mp1_dispatcher1,
+ MOJO_HANDLE_SIGNAL_WRITABLE, 0));
+
+ Waiter w;
+ w.Init();
+ HandleSignalsState hss;
+ // The three writable dispatchers should be ready.
+ EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
+ wait_set->AddAwakable(&w, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
+
+ scoped_refptr<Dispatcher> woken_dispatcher;
+ EXPECT_EQ(MOJO_RESULT_OK,
+ GetOneReadyDispatcher(wait_set, &woken_dispatcher, nullptr));
+ // Don't know which dispatcher was returned, just that it was one of the
+ // writable ones.
+ EXPECT_TRUE(woken_dispatcher == dispatcher1_ ||
+ woken_dispatcher == mp1_dispatcher0 ||
+ woken_dispatcher == mp1_dispatcher1);
+
+ DispatcherVector dispatchers_vector;
+ uint32_t count = 4;
+ MojoResult results[4];
+ EXPECT_EQ(MOJO_RESULT_OK,
+ wait_set->GetReadyDispatchers(MakeUserPointer(&count),
+ &dispatchers_vector,
+ MakeUserPointer(results),
+ MakeUserPointer<uintptr_t>(nullptr)));
+ EXPECT_EQ(3u, count);
+ std::sort(dispatchers_vector.begin(), dispatchers_vector.end());
+ DispatcherVector expected_dispatchers;
+ expected_dispatchers.push_back(dispatcher1_);
+ expected_dispatchers.push_back(mp1_dispatcher0);
+ expected_dispatchers.push_back(mp1_dispatcher1);
+ std::sort(expected_dispatchers.begin(), expected_dispatchers.end());
+ EXPECT_EQ(expected_dispatchers, dispatchers_vector);
+
+ // If a ready dispatcher isn't removed, it will continue to be returned.
+ EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
+ wait_set->AddAwakable(&w, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
+ count = 4;
+ dispatchers_vector.clear();
+ EXPECT_EQ(MOJO_RESULT_OK,
+ wait_set->GetReadyDispatchers(MakeUserPointer(&count),
+ &dispatchers_vector,
+ MakeUserPointer(results),
+ MakeUserPointer<uintptr_t>(nullptr)));
+ EXPECT_EQ(3u, count);
+ std::sort(dispatchers_vector.begin(), dispatchers_vector.end());
+ EXPECT_EQ(expected_dispatchers, dispatchers_vector);
+
+ // Remove one. It shouldn't be returned any longer.
+ ASSERT_EQ(MOJO_RESULT_OK,
+ wait_set->RemoveWaitingDispatcher(expected_dispatchers.back()));
+ expected_dispatchers.pop_back();
+ EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
+ wait_set->AddAwakable(&w, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
+ count = 4;
+ dispatchers_vector.clear();
+ EXPECT_EQ(MOJO_RESULT_OK,
+ wait_set->GetReadyDispatchers(MakeUserPointer(&count),
+ &dispatchers_vector,
+ MakeUserPointer(results),
+ MakeUserPointer<uintptr_t>(nullptr)));
+ EXPECT_EQ(2u, count);
+ std::sort(dispatchers_vector.begin(), dispatchers_vector.end());
+ EXPECT_EQ(expected_dispatchers, dispatchers_vector);
+
+ // Write to |dispatcher1_|, which should make |dispatcher0_| readable.
+ char buffer[] = "abcd";
+ w.Init();
+ ASSERT_EQ(MOJO_RESULT_OK,
+ dispatcher1_->WriteMessage(UserPointer<const void>(buffer),
+ sizeof(buffer), nullptr,
+ MOJO_WRITE_MESSAGE_FLAG_NONE));
+ expected_dispatchers.push_back(dispatcher0_);
+ std::sort(expected_dispatchers.begin(), expected_dispatchers.end());
+ EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
+ wait_set->AddAwakable(&w, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
+ count = 4;
+ dispatchers_vector.clear();
+ EXPECT_EQ(MOJO_RESULT_OK,
+ wait_set->GetReadyDispatchers(MakeUserPointer(&count),
+ &dispatchers_vector,
+ MakeUserPointer(results),
+ MakeUserPointer<uintptr_t>(nullptr)));
+ EXPECT_EQ(3u, count);
+ std::sort(dispatchers_vector.begin(), dispatchers_vector.end());
+ EXPECT_EQ(expected_dispatchers, dispatchers_vector);
+}
+
+TEST_F(WaitSetDispatcherTest, InvalidParams) {
+ scoped_refptr<WaitSetDispatcher> wait_set = new WaitSetDispatcher();
+
+ // Can't add a wait set to itself.
+ EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+ wait_set->AddWaitingDispatcher(wait_set,
+ MOJO_HANDLE_SIGNAL_READABLE, 0));
+
+ // Can't add twice.
+ EXPECT_EQ(MOJO_RESULT_OK,
+ wait_set->AddWaitingDispatcher(dispatcher0_,
+ MOJO_HANDLE_SIGNAL_READABLE, 0));
+ EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
+ wait_set->AddWaitingDispatcher(dispatcher0_,
+ MOJO_HANDLE_SIGNAL_READABLE, 0));
+
+ // Remove a dispatcher that wasn't added.
+ EXPECT_EQ(MOJO_RESULT_NOT_FOUND,
+ wait_set->RemoveWaitingDispatcher(dispatcher1_));
+
+ // Add to a closed wait set.
+ wait_set->Close();
+ EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+ wait_set->AddWaitingDispatcher(dispatcher0_,
+ MOJO_HANDLE_SIGNAL_READABLE, 0));
+}
+
+TEST_F(WaitSetDispatcherTest, NotSatisfiable) {
+ scoped_refptr<WaitSetDispatcher> wait_set = new WaitSetDispatcher();
+ CloseOnShutdown(wait_set);
+
+ // Wait sets can only satisfy MOJO_HANDLE_SIGNAL_READABLE.
+ Waiter w;
+ w.Init();
+ HandleSignalsState hss;
+ EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
+ wait_set->AddAwakable(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &hss));
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_NONE, hss.satisfied_signals);
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
+
+ hss = HandleSignalsState();
+ EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
+ wait_set->AddAwakable(&w, MOJO_HANDLE_SIGNAL_PEER_CLOSED, 0, &hss));
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_NONE, hss.satisfied_signals);
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
+}
+
+TEST_F(WaitSetDispatcherTest, ClosedDispatchers) {
+ scoped_refptr<WaitSetDispatcher> wait_set = new WaitSetDispatcher();
+ CloseOnShutdown(wait_set);
+
+ Waiter w;
+ w.Init();
+ HandleSignalsState hss;
+ // A dispatcher that was added and then closed will be cancelled.
+ ASSERT_EQ(MOJO_RESULT_OK,
+ wait_set->AddWaitingDispatcher(dispatcher0_,
+ MOJO_HANDLE_SIGNAL_READABLE, 0));
+ EXPECT_EQ(MOJO_RESULT_OK,
+ wait_set->AddAwakable(&w, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
+ dispatcher0_->Close();
+ EXPECT_EQ(MOJO_RESULT_OK, w.Wait(0, nullptr));
+ EXPECT_TRUE(wait_set->GetHandleSignalsState().satisfies(
+ MOJO_HANDLE_SIGNAL_READABLE));
+ scoped_refptr<Dispatcher> woken_dispatcher;
+ EXPECT_EQ(MOJO_RESULT_CANCELLED,
+ GetOneReadyDispatcher(wait_set, &woken_dispatcher, nullptr));
+ EXPECT_EQ(dispatcher0_, woken_dispatcher);
+
+ // Dispatcher will be implicitly removed because it may be impossible to
+ // remove explicitly.
+ woken_dispatcher = nullptr;
+ EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
+ GetOneReadyDispatcher(wait_set, &woken_dispatcher, nullptr));
+ EXPECT_EQ(MOJO_RESULT_NOT_FOUND,
+ wait_set->RemoveWaitingDispatcher(dispatcher0_));
+
+ // A dispatcher that's not satisfiable should give an error.
+ w.Init();
+ EXPECT_EQ(MOJO_RESULT_OK,
+ wait_set->AddWaitingDispatcher(dispatcher1_,
+ MOJO_HANDLE_SIGNAL_READABLE, 0));
+ EXPECT_EQ(MOJO_RESULT_OK, w.Wait(0, nullptr));
+ EXPECT_TRUE(wait_set->GetHandleSignalsState().satisfies(
+ MOJO_HANDLE_SIGNAL_READABLE));
+ EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
+ GetOneReadyDispatcher(wait_set, &woken_dispatcher, nullptr));
+ EXPECT_EQ(dispatcher1_, woken_dispatcher);
+
+ wait_set->RemoveAwakable(&w, nullptr);
+}
+
+TEST_F(WaitSetDispatcherTest, NestedSets) {
+ scoped_refptr<WaitSetDispatcher> wait_set = new WaitSetDispatcher();
+ CloseOnShutdown(wait_set);
+ scoped_refptr<WaitSetDispatcher> nested_wait_set = new WaitSetDispatcher();
+ CloseOnShutdown(nested_wait_set);
+
+ Waiter w;
+ w.Init();
+ EXPECT_EQ(MOJO_RESULT_OK,
+ wait_set->AddWaitingDispatcher(nested_wait_set,
+ MOJO_HANDLE_SIGNAL_READABLE, 0));
+ EXPECT_EQ(MOJO_RESULT_OK,
+ wait_set->AddAwakable(&w, MOJO_HANDLE_SIGNAL_READABLE, 0, nullptr));
+ EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, w.Wait(0, nullptr));
+
+ // Writable signal is immediately satisfied by the message pipe.
+ w.Init();
+ EXPECT_EQ(MOJO_RESULT_OK,
+ nested_wait_set->AddWaitingDispatcher(
+ dispatcher0_, MOJO_HANDLE_SIGNAL_WRITABLE, 0));
+ EXPECT_EQ(MOJO_RESULT_OK, w.Wait(0, nullptr));
+ scoped_refptr<Dispatcher> woken_dispatcher;
+ EXPECT_EQ(MOJO_RESULT_OK,
+ GetOneReadyDispatcher(wait_set, &woken_dispatcher, nullptr));
+ EXPECT_EQ(nested_wait_set, woken_dispatcher);
+
+ wait_set->RemoveAwakable(&w, nullptr);
+}
+
+} // namespace
+} // namespace system
+} // namespace mojo
« no previous file with comments | « third_party/mojo/src/mojo/edk/system/wait_set_dispatcher.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698