diff options
author | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-14 16:27:51 +0000 |
---|---|---|
committer | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-14 16:27:51 +0000 |
commit | 0d37563e4df3e98c429f3bd71816451becbe06d7 (patch) | |
tree | 8724e2770a1eb259d8ffd267e8dc7a587098e59b /mojo/public/utility | |
parent | 0d55b916994bb03c4b2b5ecac90ad77c1124c453 (diff) | |
download | chromium_src-0d37563e4df3e98c429f3bd71816451becbe06d7.zip chromium_src-0d37563e4df3e98c429f3bd71816451becbe06d7.tar.gz chromium_src-0d37563e4df3e98c429f3bd71816451becbe06d7.tar.bz2 |
Mojo: AsyncWaiter and mojo/public/environment
Summary of changes:
o BindingsSupport is gone:
- mojo/public/bindings/lib depends on mojo/public/environment/,
which is also a static library.
- mojo/public/environment provides a default implementation of
MojoAsyncWaiter (replacing the AsyncWait functionality of
BindingsSupport).
- mojo/public/environment provides TLS support for storing the
current Buffer* (replacing the Set/GetCurrentBuffer functionality
of BindingsSupport).
- mojo/public/environment provides the Environment class, formerly
part of mojo/public/utility/
- The standalone implementation of mojo/public/environment/ depends
on mojo/public/utility/ and assumes clients will be instantiating
RunLoops on their threads.
- The chromium-specific implementation of mojo/public/environment/
depends on mojo/common/ and assumes clients will be instantiating
MessageLoops on their threads.
- The chromium-specific implementation of mojo/public/environment/
is divided into two targets: mojo_environment_chromium and
mojo_environment_chromium_impl. The former is a static library and
the latter is a component. (This way all of the state--TLS keys--
associated with the environment is kept in a DSO when using a
component build.)
o RemotePtr and Connector may optionally be parameterized with a
MojoAsyncWaiter*, allowing users to customize how AsyncWait is
implemented for a particular usage of bindings. This is needed by
the GL library so that it can schedule work on an application
defined run loop.
o RunLoop gains a RunUntilIdle method to support tests. This allows us
to delete SimpleBindingsSupport instead of converting it over to an
implementation of MojoAsyncWaiter.
Review URL: https://codereview.chromium.org/134253004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@244739 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo/public/utility')
-rw-r--r-- | mojo/public/utility/DEPS | 3 | ||||
-rw-r--r-- | mojo/public/utility/bindings_support_impl.cc | 111 | ||||
-rw-r--r-- | mojo/public/utility/bindings_support_impl.h | 44 | ||||
-rw-r--r-- | mojo/public/utility/environment.cc | 30 | ||||
-rw-r--r-- | mojo/public/utility/environment.h | 32 | ||||
-rw-r--r-- | mojo/public/utility/run_loop.cc | 68 | ||||
-rw-r--r-- | mojo/public/utility/run_loop.h | 23 |
7 files changed, 63 insertions, 248 deletions
diff --git a/mojo/public/utility/DEPS b/mojo/public/utility/DEPS new file mode 100644 index 0000000..dd7669a --- /dev/null +++ b/mojo/public/utility/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+mojo/public/system", +] diff --git a/mojo/public/utility/bindings_support_impl.cc b/mojo/public/utility/bindings_support_impl.cc deleted file mode 100644 index b78f782..0000000 --- a/mojo/public/utility/bindings_support_impl.cc +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2013 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/utility/bindings_support_impl.h" - -#include <assert.h> - -#include "mojo/public/bindings/lib/buffer.h" -#include "mojo/public/utility/run_loop.h" -#include "mojo/public/utility/run_loop_handler.h" -#include "mojo/public/utility/thread_local.h" - -namespace mojo { -namespace internal { -namespace { - -ThreadLocalPointer<Buffer>* tls_buffer = NULL; - -// RunLoopHandler implementation used for a request to AsyncWait(). There are -// two ways RunLoopHandlerImpl is deleted: -// . when the handle is ready (or errored). -// . when BindingsSupport::CancelWait() is invoked. -class RunLoopHandlerImpl : public RunLoopHandler { - public: - RunLoopHandlerImpl(const Handle& handle, - BindingsSupport::AsyncWaitCallback* callback) - : handle_(handle), - callback_(callback) {} - 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. - BindingsSupport::AsyncWaitCallback* callback = callback_; - delete this; - - callback->OnHandleReady(result); - } - - const Handle handle_; - BindingsSupport::AsyncWaitCallback* callback_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(RunLoopHandlerImpl); -}; - -} // namespace - -BindingsSupportImpl::BindingsSupportImpl() { -} - -BindingsSupportImpl::~BindingsSupportImpl() { -} - -// static -void BindingsSupportImpl::SetUp() { - assert(!tls_buffer); - tls_buffer = new ThreadLocalPointer<Buffer>; -} - -// static -void BindingsSupportImpl::TearDown() { - assert(tls_buffer); - delete tls_buffer; - tls_buffer = NULL; -} - -Buffer* BindingsSupportImpl::GetCurrentBuffer() { - return tls_buffer->Get(); -} - -Buffer* BindingsSupportImpl::SetCurrentBuffer(Buffer* buf) { - Buffer* old_buf = tls_buffer->Get(); - tls_buffer->Set(buf); - return old_buf; -} - -BindingsSupport::AsyncWaitID BindingsSupportImpl::AsyncWait( - const Handle& handle, - MojoWaitFlags flags, - AsyncWaitCallback* callback) { - 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, callback); - run_loop->AddHandler(run_loop_handler, handle, flags, - MOJO_DEADLINE_INDEFINITE); - return run_loop_handler; -} - -void BindingsSupportImpl::CancelWait(AsyncWaitID async_wait_id) { - delete static_cast<RunLoopHandlerImpl*>(async_wait_id); -} - -} // namespace internal -} // namespace mojo diff --git a/mojo/public/utility/bindings_support_impl.h b/mojo/public/utility/bindings_support_impl.h deleted file mode 100644 index 6216227..0000000 --- a/mojo/public/utility/bindings_support_impl.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2013 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_UTILITY_BINDINGS_SUPPORT_IMPL_H_ -#define MOJO_PUBLIC_UTILITY_BINDINGS_SUPPORT_IMPL_H_ - -#include "mojo/public/bindings/lib/bindings_support.h" -#include "mojo/public/system/macros.h" - -namespace mojo { -namespace internal { - -// BindingsSupport implementation that uses RunLoop. Before using this you must -// have created a RunLoop on the current thread. -// You shouldn't create this directly, instead use Environment. -class BindingsSupportImpl : public BindingsSupport { - public: - BindingsSupportImpl(); - virtual ~BindingsSupportImpl(); - - // Sets up state needed for BindingsSupportImpl. This must be invoked before - // creating a BindingsSupportImpl. - static void SetUp(); - - // Cleans state created by Setup(). - static void TearDown(); - - // BindingsSupport methods: - virtual Buffer* GetCurrentBuffer() MOJO_OVERRIDE; - virtual Buffer* SetCurrentBuffer(Buffer* buf) MOJO_OVERRIDE; - virtual AsyncWaitID AsyncWait(const Handle& handle, - MojoWaitFlags flags, - AsyncWaitCallback* callback) MOJO_OVERRIDE; - virtual void CancelWait(AsyncWaitID async_wait_id) MOJO_OVERRIDE; - - private: - MOJO_DISALLOW_COPY_AND_ASSIGN(BindingsSupportImpl); -}; - -} // namespace internal -} // namespace mojo - -#endif // MOJO_PUBLIC_UTILITY_BINDINGS_SUPPORT_IMPL_H_ diff --git a/mojo/public/utility/environment.cc b/mojo/public/utility/environment.cc deleted file mode 100644 index b492030..0000000 --- a/mojo/public/utility/environment.cc +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2013 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/utility/environment.h" - -#include "mojo/public/utility/bindings_support_impl.h" -#include "mojo/public/utility/run_loop.h" - -namespace mojo { - -Environment::Environment() : bindings_support_(NULL) { - RunLoop::SetUp(); - - internal::BindingsSupportImpl::SetUp(); - bindings_support_ = new internal::BindingsSupportImpl; - BindingsSupport::Set(bindings_support_); -} - -Environment::~Environment() { - // Allow for someone to have replaced BindingsSupport. - if (BindingsSupport::Get() == bindings_support_) - BindingsSupport::Set(NULL); - delete bindings_support_; - internal::BindingsSupportImpl::TearDown(); - - RunLoop::TearDown(); -} - -} // namespace mojo diff --git a/mojo/public/utility/environment.h b/mojo/public/utility/environment.h deleted file mode 100644 index e7ea6a7..0000000 --- a/mojo/public/utility/environment.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2013 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_UTILITY_ENVIRONMENT_H_ -#define MOJO_PUBLIC_UTILITY_ENVIRONMENT_H_ - -#include "mojo/public/system/macros.h" - -namespace mojo { - -namespace internal { -class BindingsSupportImpl; -} // namespace internal - -class RunLoop; - -// Use Environment to cofigure state. -class Environment { - public: - Environment(); - ~Environment(); - - private: - internal::BindingsSupportImpl* bindings_support_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(Environment); -}; - -} // namespace mojo - -#endif // MOJO_PUBLIC_UTILITY_ENVIRONMENT_H_ diff --git a/mojo/public/utility/run_loop.cc b/mojo/public/utility/run_loop.cc index 56f7c42..bec828d 100644 --- a/mojo/public/utility/run_loop.cc +++ b/mojo/public/utility/run_loop.cc @@ -103,7 +103,21 @@ void RunLoop::Run() { RunState run_state; run_state_ = &run_state; while (!run_state.should_quit) - Wait(); + Wait(false); + run_state_ = old_state; +} + +void RunLoop::RunUntilIdle() { + assert(current() == this); + // We don't currently support nesting. + assert(!run_state_); + RunState* old_state = run_state_; + RunState run_state; + run_state_ = &run_state; + while (!run_state.should_quit) { + if (!Wait(true)) + break; + } run_state_ = old_state; } @@ -113,11 +127,11 @@ void RunLoop::Quit() { run_state_->should_quit = true; } -void RunLoop::Wait() { - const WaitState wait_state = GetWaitState(); +bool RunLoop::Wait(bool non_blocking) { + const WaitState wait_state = GetWaitState(non_blocking); if (wait_state.handles.empty()) { Quit(); - return; + return false; } const MojoResult result = @@ -128,23 +142,24 @@ void RunLoop::Wait() { handler_data_.end()); handler_data_[wait_state.handles[index]].handler->OnHandleReady( wait_state.handles[index]); - } else { - switch (result) { - case MOJO_RESULT_INVALID_ARGUMENT: - case MOJO_RESULT_FAILED_PRECONDITION: - RemoveFirstInvalidHandle(wait_state); - break; - case MOJO_RESULT_DEADLINE_EXCEEDED: - break; - default: - assert(false); - } + return true; + } + + switch (result) { + case MOJO_RESULT_INVALID_ARGUMENT: + case MOJO_RESULT_FAILED_PRECONDITION: + return RemoveFirstInvalidHandle(wait_state); + case MOJO_RESULT_DEADLINE_EXCEEDED: + return NotifyDeadlineExceeded(); } - NotifyDeadlineExceeded(); + assert(false); + return false; } -void RunLoop::NotifyDeadlineExceeded() { +bool RunLoop::NotifyDeadlineExceeded() { + bool notified = false; + // Make a copy in case someone tries to add/remove new handlers as part of // notifying. const HandleToHandlerData cloned_handlers(handler_data_); @@ -159,11 +174,14 @@ void RunLoop::NotifyDeadlineExceeded() { handler_data_[i->first].id == i->second.id) { handler_data_.erase(i->first); i->second.handler->OnHandleError(i->first, MOJO_RESULT_DEADLINE_EXCEEDED); + notified = true; } } + + return notified; } -void RunLoop::RemoveFirstInvalidHandle(const WaitState& wait_state) { +bool RunLoop::RemoveFirstInvalidHandle(const WaitState& wait_state) { for (size_t i = 0; i < wait_state.handles.size(); ++i) { const MojoResult result = mojo::Wait(wait_state.handles[i], wait_state.wait_flags[i], @@ -177,26 +195,28 @@ void RunLoop::RemoveFirstInvalidHandle(const WaitState& wait_state) { handler_data_[wait_state.handles[i]].handler; handler_data_.erase(wait_state.handles[i]); handler->OnHandleError(wait_state.handles[i], result); - return; - } else { - assert(MOJO_RESULT_DEADLINE_EXCEEDED == result); + return true; } + assert(MOJO_RESULT_DEADLINE_EXCEEDED == result); } + return false; } -RunLoop::WaitState RunLoop::GetWaitState() const { +RunLoop::WaitState RunLoop::GetWaitState(bool non_blocking) const { WaitState wait_state; MojoTimeTicks min_time = kInvalidTimeTicks; for (HandleToHandlerData::const_iterator i = handler_data_.begin(); i != handler_data_.end(); ++i) { wait_state.handles.push_back(i->first); wait_state.wait_flags.push_back(i->second.wait_flags); - if (i->second.deadline != kInvalidTimeTicks && + if (!non_blocking && i->second.deadline != kInvalidTimeTicks && (min_time == kInvalidTimeTicks || i->second.deadline < min_time)) { min_time = i->second.deadline; } } - if (min_time != kInvalidTimeTicks) { + if (non_blocking) { + wait_state.deadline = static_cast<MojoDeadline>(0); + } else if (min_time != kInvalidTimeTicks) { const MojoTimeTicks now = GetTimeTicksNow(); if (min_time < now) wait_state.deadline = static_cast<MojoDeadline>(0); diff --git a/mojo/public/utility/run_loop.h b/mojo/public/utility/run_loop.h index 49c8c2d..be39edb 100644 --- a/mojo/public/utility/run_loop.h +++ b/mojo/public/utility/run_loop.h @@ -41,6 +41,12 @@ class RunLoop { // Runs the loop servicing handles as they are ready. This returns when Quit() // is invoked, or there no more handles. void Run(); + + // Runs the loop servicing any handles that are ready. Does not wait for + // handles to become ready before returning. Returns early if Quit() is + // invoked. + void RunUntilIdle(); + void Quit(); private: @@ -65,18 +71,21 @@ class RunLoop { typedef std::map<Handle, HandlerData> HandleToHandlerData; // Waits for a handle to be ready. Returns after servicing at least one - // handle (or there are no more handles). - void Wait(); + // handle (or there are no more handles) unless |non_blocking| is true, + // in which case it will also return if servicing at least one handle + // would require blocking. Returns true if a RunLoopHandler was notified. + bool Wait(bool non_blocking); - // Notifies any handlers whose deadline has expired. - void NotifyDeadlineExceeded(); + // Notifies any handlers whose deadline has expired. Returns true if a + // RunLoopHandler was notified. + bool NotifyDeadlineExceeded(); // Removes the first invalid handle. This is called if MojoWaitMany() finds an - // invalid handle. - void RemoveFirstInvalidHandle(const WaitState& wait_state); + // invalid handle. Returns true if a RunLoopHandler was notified. + bool RemoveFirstInvalidHandle(const WaitState& wait_state); // Returns the state needed to pass to WaitMany(). - WaitState GetWaitState() const; + WaitState GetWaitState(bool non_blocking) const; HandleToHandlerData handler_data_; |