diff options
Diffstat (limited to 'mojo/public/cpp/environment')
-rw-r--r-- | mojo/public/cpp/environment/buffer_tls.h | 20 | ||||
-rw-r--r-- | mojo/public/cpp/environment/default_async_waiter.h | 17 | ||||
-rw-r--r-- | mojo/public/cpp/environment/environment.h | 24 | ||||
-rw-r--r-- | mojo/public/cpp/environment/lib/DEPS | 4 | ||||
-rw-r--r-- | mojo/public/cpp/environment/lib/buffer_tls.cc | 37 | ||||
-rw-r--r-- | mojo/public/cpp/environment/lib/buffer_tls_setup.h | 17 | ||||
-rw-r--r-- | mojo/public/cpp/environment/lib/default_async_waiter.cc | 93 | ||||
-rw-r--r-- | mojo/public/cpp/environment/lib/environment.cc | 22 | ||||
-rw-r--r-- | mojo/public/cpp/environment/tests/DEPS | 6 | ||||
-rw-r--r-- | mojo/public/cpp/environment/tests/async_waiter_unittest.cc | 118 |
10 files changed, 358 insertions, 0 deletions
diff --git a/mojo/public/cpp/environment/buffer_tls.h b/mojo/public/cpp/environment/buffer_tls.h new file mode 100644 index 0000000..42cf826 --- /dev/null +++ b/mojo/public/cpp/environment/buffer_tls.h @@ -0,0 +1,20 @@ +// Copyright 2014 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. + +#ifndef MOJO_PUBLIC_CPP_ENVIRONMENT_BUFFER_TLS_H_ +#define MOJO_PUBLIC_CPP_ENVIRONMENT_BUFFER_TLS_H_ + +namespace mojo { +class Buffer; + +namespace internal { + +// Get/Set the |Buffer*| associated with current thread. +Buffer* GetCurrentBuffer(); +Buffer* SetCurrentBuffer(Buffer* buffer); + +} // namespace internal +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_ENVIRONMENT_BUFFER_TLS_H_ diff --git a/mojo/public/cpp/environment/default_async_waiter.h b/mojo/public/cpp/environment/default_async_waiter.h new file mode 100644 index 0000000..d7f48bf --- /dev/null +++ b/mojo/public/cpp/environment/default_async_waiter.h @@ -0,0 +1,17 @@ +// Copyright 2014 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. + +#ifndef MOJO_PUBLIC_CPP_ENVIRONMENT_DEFAULT_ASYNC_WAITER_H_ +#define MOJO_PUBLIC_CPP_ENVIRONMENT_DEFAULT_ASYNC_WAITER_H_ + +#include "mojo/public/c/system/async_waiter.h" + +namespace mojo { + +// Returns a default implementation of MojoAsyncWaiter. +MojoAsyncWaiter* GetDefaultAsyncWaiter(); + +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_ENVIRONMENT_DEFAULT_ASYNC_WAITER_H_ diff --git a/mojo/public/cpp/environment/environment.h b/mojo/public/cpp/environment/environment.h new file mode 100644 index 0000000..f75e2f7 --- /dev/null +++ b/mojo/public/cpp/environment/environment.h @@ -0,0 +1,24 @@ +// Copyright 2014 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. + +#ifndef MOJO_PUBLIC_CPP_ENVIRONMENT_ENVIRONMENT_H_ +#define MOJO_PUBLIC_CPP_ENVIRONMENT_ENVIRONMENT_H_ + +#include "mojo/public/cpp/system/macros.h" + +namespace mojo { + +// This class must be instantiated before using any Mojo APIs. +class Environment { + public: + Environment(); + ~Environment(); + + private: + MOJO_DISALLOW_COPY_AND_ASSIGN(Environment); +}; + +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_ENVIRONMENT_ENVIRONMENT_H_ diff --git a/mojo/public/cpp/environment/lib/DEPS b/mojo/public/cpp/environment/lib/DEPS new file mode 100644 index 0000000..1889e1f --- /dev/null +++ b/mojo/public/cpp/environment/lib/DEPS @@ -0,0 +1,4 @@ +include_rules = [ + "+mojo/public/cpp/environment", + "+mojo/public/cpp/utility", +] diff --git a/mojo/public/cpp/environment/lib/buffer_tls.cc b/mojo/public/cpp/environment/lib/buffer_tls.cc new file mode 100644 index 0000000..d54faba --- /dev/null +++ b/mojo/public/cpp/environment/lib/buffer_tls.cc @@ -0,0 +1,37 @@ +// Copyright 2014 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 "mojo/public/cpp/environment/buffer_tls.h" + +#include <assert.h> + +#include "mojo/public/cpp/environment/lib/buffer_tls_setup.h" +#include "mojo/public/cpp/utility/lib/thread_local.h" + +namespace mojo { +namespace internal { + +static ThreadLocalPointer<Buffer> current_buffer; + +void SetUpCurrentBuffer() { + current_buffer.Allocate(); +} + +void TearDownCurrentBuffer() { + assert(!current_buffer.Get()); + current_buffer.Free(); +} + +Buffer* GetCurrentBuffer() { + return current_buffer.Get(); +} + +Buffer* SetCurrentBuffer(Buffer* buf) { + Buffer* old_buf = current_buffer.Get(); + current_buffer.Set(buf); + return old_buf; +} + +} // namespace internal +} // namespace mojo diff --git a/mojo/public/cpp/environment/lib/buffer_tls_setup.h b/mojo/public/cpp/environment/lib/buffer_tls_setup.h new file mode 100644 index 0000000..f0ca0b1 --- /dev/null +++ b/mojo/public/cpp/environment/lib/buffer_tls_setup.h @@ -0,0 +1,17 @@ +// Copyright 2014 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. + +#ifndef MOJO_PUBLIC_CPP_ENVIRONMENT_STANDALONE_BUFFER_TLS_SETUP_H_ +#define MOJO_PUBLIC_CPP_ENVIRONMENT_STANDALONE_BUFFER_TLS_SETUP_H_ + +namespace mojo { +namespace internal { + +void SetUpCurrentBuffer(); +void TearDownCurrentBuffer(); + +} // namespace internal +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_ENVIRONMENT_STANDALONE_BUFFER_TLS_SETUP_H_ diff --git a/mojo/public/cpp/environment/lib/default_async_waiter.cc b/mojo/public/cpp/environment/lib/default_async_waiter.cc new file mode 100644 index 0000000..73e41de --- /dev/null +++ b/mojo/public/cpp/environment/lib/default_async_waiter.cc @@ -0,0 +1,93 @@ +// Copyright 2014 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 "mojo/public/cpp/environment/default_async_waiter.h" + +#include <assert.h> + +#include "mojo/public/cpp/utility/run_loop.h" +#include "mojo/public/cpp/utility/run_loop_handler.h" + +namespace mojo { +namespace { + +// RunLoopHandler implementation used for a request to AsyncWait(). There are +// two ways RunLoopHandlerImpl is deleted: +// . when the handle is ready (or errored). +// . when CancelWait() is invoked. +class RunLoopHandlerImpl : public RunLoopHandler { + public: + RunLoopHandlerImpl(const Handle& handle, + MojoAsyncWaitCallback callback, + void* closure) + : handle_(handle), + callback_(callback), + closure_(closure) { + } + + virtual ~RunLoopHandlerImpl() { + RunLoop::current()->RemoveHandler(handle_); + } + + // RunLoopHandler: + virtual void OnHandleReady(const Handle& handle) MOJO_OVERRIDE { + NotifyCallback(MOJO_RESULT_OK); + } + + virtual void OnHandleError(const Handle& handle, + MojoResult result) MOJO_OVERRIDE { + NotifyCallback(result); + } + + private: + void NotifyCallback(MojoResult result) { + // Delete this to unregister the handle. That way if the callback + // reregisters everything is ok. + MojoAsyncWaitCallback callback = callback_; + void* closure = closure_; + delete this; + + callback(closure, result); + } + + const Handle handle_; + MojoAsyncWaitCallback callback_; + void* closure_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(RunLoopHandlerImpl); +}; + +MojoAsyncWaitID AsyncWait(MojoAsyncWaiter* waiter, + MojoHandle handle, + MojoWaitFlags flags, + MojoDeadline deadline, + MojoAsyncWaitCallback callback, + void* closure) { + RunLoop* run_loop = RunLoop::current(); + assert(run_loop); + + // |run_loop_handler| is destroyed either when the handle is ready or if + // CancelWait is invoked. + RunLoopHandlerImpl* run_loop_handler = + new RunLoopHandlerImpl(Handle(handle), callback, closure); + run_loop->AddHandler(run_loop_handler, Handle(handle), flags, deadline); + return reinterpret_cast<MojoAsyncWaitID>(run_loop_handler); +} + +void CancelWait(MojoAsyncWaiter* waiter, MojoAsyncWaitID wait_id) { + delete reinterpret_cast<RunLoopHandlerImpl*>(wait_id); +} + +MojoAsyncWaiter s_default_async_waiter = { + AsyncWait, + CancelWait +}; + +} // namespace + +MojoAsyncWaiter* GetDefaultAsyncWaiter() { + return &s_default_async_waiter; +} + +} // namespace mojo diff --git a/mojo/public/cpp/environment/lib/environment.cc b/mojo/public/cpp/environment/lib/environment.cc new file mode 100644 index 0000000..b3148af --- /dev/null +++ b/mojo/public/cpp/environment/lib/environment.cc @@ -0,0 +1,22 @@ +// Copyright 2014 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 "mojo/public/cpp/environment/environment.h" + +#include "mojo/public/cpp/environment/lib/buffer_tls_setup.h" +#include "mojo/public/cpp/utility/run_loop.h" + +namespace mojo { + +Environment::Environment() { + internal::SetUpCurrentBuffer(); + RunLoop::SetUp(); +} + +Environment::~Environment() { + RunLoop::TearDown(); + internal::TearDownCurrentBuffer(); +} + +} // namespace mojo diff --git a/mojo/public/cpp/environment/tests/DEPS b/mojo/public/cpp/environment/tests/DEPS new file mode 100644 index 0000000..9266146 --- /dev/null +++ b/mojo/public/cpp/environment/tests/DEPS @@ -0,0 +1,6 @@ +include_rules = [ + "+testing", + "+mojo/public/cpp/utility", + # TODO(vtl): Temporary until these are moved to mojo/public/cpp: + "+mojo/public/tests", +] diff --git a/mojo/public/cpp/environment/tests/async_waiter_unittest.cc b/mojo/public/cpp/environment/tests/async_waiter_unittest.cc new file mode 100644 index 0000000..444fdef --- /dev/null +++ b/mojo/public/cpp/environment/tests/async_waiter_unittest.cc @@ -0,0 +1,118 @@ +// Copyright 2014 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 <string> + +#include "mojo/public/cpp/environment/default_async_waiter.h" +#include "mojo/public/cpp/environment/environment.h" +#include "mojo/public/cpp/system/core.h" +#include "mojo/public/cpp/system/macros.h" +#include "mojo/public/cpp/utility/run_loop.h" +#include "mojo/public/tests/test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace mojo { +namespace { + +class TestAsyncWaitCallback { + public: + TestAsyncWaitCallback() : result_count_(0), last_result_(MOJO_RESULT_OK) { + } + virtual ~TestAsyncWaitCallback() {} + + int result_count() const { return result_count_; } + + MojoResult last_result() const { return last_result_; } + + // MojoAsyncWaitCallback: + static void OnHandleReady(void* closure, MojoResult result) { + TestAsyncWaitCallback* self = static_cast<TestAsyncWaitCallback*>(closure); + self->result_count_++; + self->last_result_ = result; + } + + private: + int result_count_; + MojoResult last_result_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(TestAsyncWaitCallback); +}; + +MojoAsyncWaitID CallAsyncWait(const Handle& handle, + MojoWaitFlags flags, + TestAsyncWaitCallback* callback) { + MojoAsyncWaiter* waiter = GetDefaultAsyncWaiter(); + return waiter->AsyncWait(waiter, + handle.value(), + flags, + MOJO_DEADLINE_INDEFINITE, + &TestAsyncWaitCallback::OnHandleReady, + callback); +} + +void CallCancelWait(MojoAsyncWaitID wait_id) { + MojoAsyncWaiter* waiter = GetDefaultAsyncWaiter(); + waiter->CancelWait(waiter, wait_id); +} + +class AsyncWaiterTest : public testing::Test { + public: + AsyncWaiterTest() {} + + private: + Environment environment_; + RunLoop run_loop_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(AsyncWaiterTest); +}; + +// Verifies AsyncWaitCallback is notified when pipe is ready. +TEST_F(AsyncWaiterTest, CallbackNotified) { + TestAsyncWaitCallback callback; + MessagePipe test_pipe; + EXPECT_TRUE(test::WriteTextMessage(test_pipe.handle1.get(), std::string())); + + CallAsyncWait(test_pipe.handle0.get(), + MOJO_WAIT_FLAG_READABLE, + &callback); + RunLoop::current()->Run(); + EXPECT_EQ(1, callback.result_count()); + EXPECT_EQ(MOJO_RESULT_OK, callback.last_result()); +} + +// Verifies 2 AsyncWaitCallbacks are notified when there pipes are ready. +TEST_F(AsyncWaiterTest, TwoCallbacksNotified) { + TestAsyncWaitCallback callback1; + TestAsyncWaitCallback callback2; + MessagePipe test_pipe1; + MessagePipe test_pipe2; + EXPECT_TRUE(test::WriteTextMessage(test_pipe1.handle1.get(), std::string())); + EXPECT_TRUE(test::WriteTextMessage(test_pipe2.handle1.get(), std::string())); + + CallAsyncWait(test_pipe1.handle0.get(), MOJO_WAIT_FLAG_READABLE, &callback1); + CallAsyncWait(test_pipe2.handle0.get(), MOJO_WAIT_FLAG_READABLE, &callback2); + + RunLoop::current()->Run(); + EXPECT_EQ(1, callback1.result_count()); + EXPECT_EQ(MOJO_RESULT_OK, callback1.last_result()); + EXPECT_EQ(1, callback2.result_count()); + EXPECT_EQ(MOJO_RESULT_OK, callback2.last_result()); +} + +// Verifies cancel works. +TEST_F(AsyncWaiterTest, CancelCallback) { + TestAsyncWaitCallback callback; + MessagePipe test_pipe; + EXPECT_TRUE(test::WriteTextMessage(test_pipe.handle1.get(), std::string())); + + CallCancelWait( + CallAsyncWait(test_pipe.handle0.get(), + MOJO_WAIT_FLAG_READABLE, + &callback)); + RunLoop::current()->Run(); + EXPECT_EQ(0, callback.result_count()); +} + +} // namespace +} // namespace mojo |