| Index: mojo/edk/test/mojo_test_base.cc
|
| diff --git a/mojo/edk/test/mojo_test_base.cc b/mojo/edk/test/mojo_test_base.cc
|
| index f1032d7e3f5fe0ef45957dba5c8949cd1cdf5602..d7d3b2a0a75032508a2040c30d0fac21be8d7ec5 100644
|
| --- a/mojo/edk/test/mojo_test_base.cc
|
| +++ b/mojo/edk/test/mojo_test_base.cc
|
| @@ -5,13 +5,16 @@
|
| #include "mojo/edk/test/mojo_test_base.h"
|
|
|
| #include "base/memory/ptr_util.h"
|
| +#include "base/memory/ref_counted.h"
|
| #include "base/message_loop/message_loop.h"
|
| #include "base/run_loop.h"
|
| +#include "base/synchronization/waitable_event.h"
|
| #include "mojo/edk/embedder/embedder.h"
|
| #include "mojo/edk/system/handle_signals_state.h"
|
| #include "mojo/public/c/system/buffer.h"
|
| #include "mojo/public/c/system/data_pipe.h"
|
| #include "mojo/public/c/system/functions.h"
|
| +#include "mojo/public/c/system/watcher.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| #if defined(OS_MACOSX) && !defined(OS_IOS)
|
| @@ -22,6 +25,103 @@ namespace mojo {
|
| namespace edk {
|
| namespace test {
|
|
|
| +namespace {
|
| +
|
| +class Waiter {
|
| + public:
|
| + Waiter() {}
|
| + ~Waiter() {}
|
| +
|
| + MojoResult Wait(MojoHandle handle,
|
| + MojoHandleSignals signals,
|
| + MojoHandleSignalsState* state) {
|
| + MojoHandle watcher;
|
| + MojoCreateWatcher(&Context::OnNotification, &watcher);
|
| +
|
| + context_ = new Context();
|
| +
|
| + // Balanced by OnNotification in the |MOJO_RESULT_CANCELLED| case.
|
| + context_->AddRef();
|
| +
|
| + MojoResult rv = MojoWatch(watcher, handle, signals,
|
| + reinterpret_cast<uintptr_t>(context_.get()));
|
| + DCHECK_EQ(MOJO_RESULT_OK, rv);
|
| +
|
| + uint32_t num_ready_contexts = 1;
|
| + uintptr_t ready_context;
|
| + MojoResult ready_result;
|
| + MojoHandleSignalsState ready_state;
|
| + rv = MojoArmWatcher(watcher, &num_ready_contexts, &ready_context,
|
| + &ready_result, &ready_state);
|
| + if (rv == MOJO_RESULT_FAILED_PRECONDITION) {
|
| + MojoClose(watcher);
|
| + DCHECK_EQ(1u, num_ready_contexts);
|
| + if (state)
|
| + *state = ready_state;
|
| + return ready_result;
|
| + }
|
| +
|
| + // Wait for the first notification.
|
| + context_->event().Wait();
|
| +
|
| + ready_result = context_->wait_result();
|
| + DCHECK_NE(MOJO_RESULT_UNKNOWN, ready_result);
|
| +
|
| + if (state)
|
| + *state = context_->wait_state();
|
| +
|
| + MojoClose(watcher);
|
| +
|
| + return ready_result;
|
| + }
|
| +
|
| + private:
|
| + class Context : public base::RefCountedThreadSafe<Context> {
|
| + public:
|
| + Context()
|
| + : event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
|
| + base::WaitableEvent::InitialState::NOT_SIGNALED) {}
|
| +
|
| + base::WaitableEvent& event() { return event_; }
|
| + MojoResult wait_result() const { return wait_result_; }
|
| + MojoHandleSignalsState wait_state() const { return wait_state_; }
|
| +
|
| + static void OnNotification(uintptr_t context_value,
|
| + MojoResult result,
|
| + MojoHandleSignalsState state,
|
| + MojoWatcherNotificationFlags flags) {
|
| + auto* context = reinterpret_cast<Context*>(context_value);
|
| + context->Notify(result, state);
|
| + if (result == MOJO_RESULT_CANCELLED)
|
| + context->Release();
|
| + }
|
| +
|
| + private:
|
| + friend class base::RefCountedThreadSafe<Context>;
|
| +
|
| + ~Context() {}
|
| +
|
| + void Notify(MojoResult result, MojoHandleSignalsState state) {
|
| + if (wait_result_ == MOJO_RESULT_UNKNOWN) {
|
| + wait_result_ = result;
|
| + wait_state_ = state;
|
| + }
|
| + event_.Signal();
|
| + }
|
| +
|
| + base::WaitableEvent event_;
|
| + MojoResult wait_result_ = MOJO_RESULT_UNKNOWN;
|
| + MojoHandleSignalsState wait_state_ = {0, 0};
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(Context);
|
| + };
|
| +
|
| + scoped_refptr<Context> context_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(Waiter);
|
| +};
|
| +
|
| +} // namespace
|
|
|
| #if defined(OS_MACOSX) && !defined(OS_IOS)
|
| namespace {
|
| @@ -130,9 +230,7 @@ std::string MojoTestBase::ReadMessageWithHandles(
|
| MojoHandle mp,
|
| MojoHandle* handles,
|
| uint32_t expected_num_handles) {
|
| - CHECK_EQ(MojoWait(mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE,
|
| - nullptr),
|
| - MOJO_RESULT_OK);
|
| + CHECK_EQ(WaitForSignals(mp, MOJO_HANDLE_SIGNAL_READABLE), MOJO_RESULT_OK);
|
|
|
| uint32_t message_size = 0;
|
| uint32_t num_handles = 0;
|
| @@ -154,9 +252,7 @@ std::string MojoTestBase::ReadMessageWithHandles(
|
| // static
|
| std::string MojoTestBase::ReadMessageWithOptionalHandle(MojoHandle mp,
|
| MojoHandle* handle) {
|
| - CHECK_EQ(MojoWait(mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE,
|
| - nullptr),
|
| - MOJO_RESULT_OK);
|
| + CHECK_EQ(WaitForSignals(mp, MOJO_HANDLE_SIGNAL_READABLE), MOJO_RESULT_OK);
|
|
|
| uint32_t message_size = 0;
|
| uint32_t num_handles = 0;
|
| @@ -191,9 +287,7 @@ std::string MojoTestBase::ReadMessage(MojoHandle mp) {
|
| void MojoTestBase::ReadMessage(MojoHandle mp,
|
| char* data,
|
| size_t num_bytes) {
|
| - CHECK_EQ(MojoWait(mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE,
|
| - nullptr),
|
| - MOJO_RESULT_OK);
|
| + CHECK_EQ(WaitForSignals(mp, MOJO_HANDLE_SIGNAL_READABLE), MOJO_RESULT_OK);
|
|
|
| uint32_t message_size = 0;
|
| uint32_t num_handles = 0;
|
| @@ -288,8 +382,7 @@ void MojoTestBase::CreateDataPipe(MojoHandle *p0,
|
|
|
| // static
|
| void MojoTestBase::WriteData(MojoHandle producer, const std::string& data) {
|
| - CHECK_EQ(MojoWait(producer, MOJO_HANDLE_SIGNAL_WRITABLE,
|
| - MOJO_DEADLINE_INDEFINITE, nullptr),
|
| + CHECK_EQ(WaitForSignals(producer, MOJO_HANDLE_SIGNAL_WRITABLE),
|
| MOJO_RESULT_OK);
|
| uint32_t num_bytes = static_cast<uint32_t>(data.size());
|
| CHECK_EQ(MojoWriteData(producer, data.data(), &num_bytes,
|
| @@ -300,8 +393,7 @@ void MojoTestBase::WriteData(MojoHandle producer, const std::string& data) {
|
|
|
| // static
|
| std::string MojoTestBase::ReadData(MojoHandle consumer, size_t size) {
|
| - CHECK_EQ(MojoWait(consumer, MOJO_HANDLE_SIGNAL_READABLE,
|
| - MOJO_DEADLINE_INDEFINITE, nullptr),
|
| + CHECK_EQ(WaitForSignals(consumer, MOJO_HANDLE_SIGNAL_READABLE),
|
| MOJO_RESULT_OK);
|
| std::vector<char> buffer(size);
|
| uint32_t num_bytes = static_cast<uint32_t>(size);
|
| @@ -313,6 +405,21 @@ std::string MojoTestBase::ReadData(MojoHandle consumer, size_t size) {
|
| return std::string(buffer.data(), buffer.size());
|
| }
|
|
|
| +// static
|
| +MojoHandleSignalsState MojoTestBase::GetSignalsState(MojoHandle handle) {
|
| + MojoHandleSignalsState signals_state;
|
| + CHECK_EQ(MOJO_RESULT_OK, MojoQueryHandleSignalsState(handle, &signals_state));
|
| + return signals_state;
|
| +}
|
| +
|
| +// static
|
| +MojoResult MojoTestBase::WaitForSignals(MojoHandle handle,
|
| + MojoHandleSignals signals,
|
| + MojoHandleSignalsState* state) {
|
| + Waiter waiter;
|
| + return waiter.Wait(handle, signals, state);
|
| +}
|
| +
|
| } // namespace test
|
| } // namespace edk
|
| } // namespace mojo
|
|
|