summaryrefslogtreecommitdiffstats
path: root/mojo/common
diff options
context:
space:
mode:
authorsky <sky@chromium.org>2015-08-06 18:06:18 -0700
committerCommit bot <commit-bot@chromium.org>2015-08-07 01:07:34 +0000
commitadd030b55dee834423004bde2a0d92afd8a7be7e (patch)
treed7e3af2db33ba8e700d15a80f40a003336ba9523 /mojo/common
parent1efe8793da85ee6e25185175047c077adfe8e55c (diff)
downloadchromium_src-add030b55dee834423004bde2a0d92afd8a7be7e.zip
chromium_src-add030b55dee834423004bde2a0d92afd8a7be7e.tar.gz
chromium_src-add030b55dee834423004bde2a0d92afd8a7be7e.tar.bz2
Straightens outs DEPS in mojo/common
Prior to this change //mojo/environment depended upon //mojo/common. //mojo/common's deps are wrong and it needs to be depend upon various things in //third_party/mojo/src/mojo... When these DEPS are added link errors result because Environment and and a couple of other things need to be defined. These are defined in //mojo/environment. But //mojo/environment can't be a dep of //mojo/common, else we get a cycle. To straighten this out I've moved the files //mojo/environment needs from //mojo/common to //mojo/message_pump. //mojo/environment no longer depends upon //mojo/common, only //mojo/message_pump. //mojo/common can then depend upon //mojo/environment and we no longer have the cycle. Yay! BUG=none TEST=none Committed: https://crrev.com/a11b4d76a27816fe025af647825becac5f633c34 Cr-Commit-Position: refs/heads/master@{#341979} Review URL: https://codereview.chromium.org/1262173005 Cr-Commit-Position: refs/heads/master@{#342252}
Diffstat (limited to 'mojo/common')
-rw-r--r--mojo/common/BUILD.gn18
-rw-r--r--mojo/common/handle_watcher.cc475
-rw-r--r--mojo/common/handle_watcher.h64
-rw-r--r--mojo/common/handle_watcher_unittest.cc483
-rw-r--r--mojo/common/message_pump_mojo.cc295
-rw-r--r--mojo/common/message_pump_mojo.h136
-rw-r--r--mojo/common/message_pump_mojo_handler.h29
-rw-r--r--mojo/common/message_pump_mojo_unittest.cc124
-rw-r--r--mojo/common/time_helper.cc33
-rw-r--r--mojo/common/time_helper.h34
10 files changed, 9 insertions, 1682 deletions
diff --git a/mojo/common/BUILD.gn b/mojo/common/BUILD.gn
index 99f0ba5..6dfed2f 100644
--- a/mojo/common/BUILD.gn
+++ b/mojo/common/BUILD.gn
@@ -21,13 +21,6 @@ component("common_base") {
"data_pipe_file_utils.cc",
"data_pipe_utils.cc",
"data_pipe_utils.h",
- "handle_watcher.cc",
- "handle_watcher.h",
- "message_pump_mojo.cc",
- "message_pump_mojo.h",
- "message_pump_mojo_handler.h",
- "time_helper.cc",
- "time_helper.h",
"user_agent.cc",
"user_agent.h",
"weak_binding_set.h",
@@ -39,7 +32,11 @@ component("common_base") {
deps = [
"//base",
"//base/third_party/dynamic_annotations",
+ "//mojo/environment:chromium",
"//third_party/mojo/src/mojo/public/c/system:for_component",
+ "//third_party/mojo/src/mojo/public/cpp/bindings",
+ "//third_party/mojo/src/mojo/public/cpp/environment",
+ "//third_party/mojo/src/mojo/public/cpp/system",
]
}
@@ -78,6 +75,7 @@ test("mojo_common_unittests") {
"//base:message_loop_tests",
"//base/test:test_support",
"//mojo/environment:chromium",
+ "//mojo/message_pump",
"//testing/gtest",
"//third_party/mojo/src/mojo/edk/test:run_all_unittests",
"//third_party/mojo/src/mojo/edk/test:test_support",
@@ -87,9 +85,11 @@ test("mojo_common_unittests") {
]
sources = [
+ # The message_pump tests are so small and some what related to this code
+ # that we put them here.
+ "../message_pump/handle_watcher_unittest.cc",
+ "../message_pump/message_pump_mojo_unittest.cc",
"common_type_converters_unittest.cc",
- "handle_watcher_unittest.cc",
- "message_pump_mojo_unittest.cc",
]
}
diff --git a/mojo/common/handle_watcher.cc b/mojo/common/handle_watcher.cc
deleted file mode 100644
index 6bff0cd..0000000
--- a/mojo/common/handle_watcher.cc
+++ /dev/null
@@ -1,475 +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/common/handle_watcher.h"
-
-#include <map>
-
-#include "base/atomic_sequence_num.h"
-#include "base/bind.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/singleton.h"
-#include "base/memory/weak_ptr.h"
-#include "base/message_loop/message_loop.h"
-#include "base/single_thread_task_runner.h"
-#include "base/synchronization/lock.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/thread_task_runner_handle.h"
-#include "base/threading/thread.h"
-#include "base/threading/thread_restrictions.h"
-#include "base/time/time.h"
-#include "mojo/common/message_pump_mojo.h"
-#include "mojo/common/message_pump_mojo_handler.h"
-#include "mojo/common/time_helper.h"
-
-namespace mojo {
-namespace common {
-
-typedef int WatcherID;
-
-namespace {
-
-const char kWatcherThreadName[] = "handle-watcher-thread";
-
-base::TimeTicks MojoDeadlineToTimeTicks(MojoDeadline deadline) {
- return deadline == MOJO_DEADLINE_INDEFINITE ? base::TimeTicks() :
- internal::NowTicks() + base::TimeDelta::FromMicroseconds(deadline);
-}
-
-// Tracks the data for a single call to Start().
-struct WatchData {
- WatchData()
- : id(0), handle_signals(MOJO_HANDLE_SIGNAL_NONE), task_runner(NULL) {}
-
- WatcherID id;
- Handle handle;
- MojoHandleSignals handle_signals;
- base::TimeTicks deadline;
- base::Callback<void(MojoResult)> callback;
- scoped_refptr<base::SingleThreadTaskRunner> task_runner;
-};
-
-// WatcherBackend --------------------------------------------------------------
-
-// WatcherBackend is responsible for managing the requests and interacting with
-// MessagePumpMojo. All access (outside of creation/destruction) is done on the
-// thread WatcherThreadManager creates.
-class WatcherBackend : public MessagePumpMojoHandler {
- public:
- WatcherBackend();
- ~WatcherBackend() override;
-
- void StartWatching(const WatchData& data);
-
- // Cancels a previously scheduled request to start a watch.
- void StopWatching(WatcherID watcher_id);
-
- private:
- typedef std::map<Handle, WatchData> HandleToWatchDataMap;
-
- // Invoked when a handle needs to be removed and notified.
- void RemoveAndNotify(const Handle& handle, MojoResult result);
-
- // Searches through |handle_to_data_| for |watcher_id|. Returns true if found
- // and sets |handle| to the Handle. Returns false if not a known id.
- bool GetMojoHandleByWatcherID(WatcherID watcher_id, Handle* handle) const;
-
- // MessagePumpMojoHandler overrides:
- void OnHandleReady(const Handle& handle) override;
- void OnHandleError(const Handle& handle, MojoResult result) override;
-
- // Maps from assigned id to WatchData.
- HandleToWatchDataMap handle_to_data_;
-
- DISALLOW_COPY_AND_ASSIGN(WatcherBackend);
-};
-
-WatcherBackend::WatcherBackend() {
-}
-
-WatcherBackend::~WatcherBackend() {
-}
-
-void WatcherBackend::StartWatching(const WatchData& data) {
- RemoveAndNotify(data.handle, MOJO_RESULT_CANCELLED);
-
- DCHECK_EQ(0u, handle_to_data_.count(data.handle));
-
- handle_to_data_[data.handle] = data;
- MessagePumpMojo::current()->AddHandler(this, data.handle,
- data.handle_signals,
- data.deadline);
-}
-
-void WatcherBackend::StopWatching(WatcherID watcher_id) {
- // Because of the thread hop it is entirely possible to get here and not
- // have a valid handle registered for |watcher_id|.
- Handle handle;
- if (GetMojoHandleByWatcherID(watcher_id, &handle)) {
- handle_to_data_.erase(handle);
- MessagePumpMojo::current()->RemoveHandler(handle);
- }
-}
-
-void WatcherBackend::RemoveAndNotify(const Handle& handle,
- MojoResult result) {
- if (handle_to_data_.count(handle) == 0)
- return;
-
- const WatchData data(handle_to_data_[handle]);
- handle_to_data_.erase(handle);
- MessagePumpMojo::current()->RemoveHandler(handle);
-
- data.task_runner->PostTask(FROM_HERE, base::Bind(data.callback, result));
-}
-
-bool WatcherBackend::GetMojoHandleByWatcherID(WatcherID watcher_id,
- Handle* handle) const {
- for (HandleToWatchDataMap::const_iterator i = handle_to_data_.begin();
- i != handle_to_data_.end(); ++i) {
- if (i->second.id == watcher_id) {
- *handle = i->second.handle;
- return true;
- }
- }
- return false;
-}
-
-void WatcherBackend::OnHandleReady(const Handle& handle) {
- RemoveAndNotify(handle, MOJO_RESULT_OK);
-}
-
-void WatcherBackend::OnHandleError(const Handle& handle, MojoResult result) {
- RemoveAndNotify(handle, result);
-}
-
-// WatcherThreadManager --------------------------------------------------------
-
-// WatcherThreadManager manages the background thread that listens for handles
-// to be ready. All requests are handled by WatcherBackend.
-} // namespace
-
-class WatcherThreadManager {
- public:
- ~WatcherThreadManager();
-
- // Returns the shared instance.
- static WatcherThreadManager* GetInstance();
-
- // Starts watching the requested handle. Returns a unique ID that is used to
- // stop watching the handle. When the handle is ready |callback| is notified
- // on the thread StartWatching() was invoked on.
- // This may be invoked on any thread.
- WatcherID StartWatching(const Handle& handle,
- MojoHandleSignals handle_signals,
- base::TimeTicks deadline,
- const base::Callback<void(MojoResult)>& callback);
-
- // Stops watching a handle.
- // This may be invoked on any thread.
- void StopWatching(WatcherID watcher_id);
-
- private:
- enum RequestType {
- REQUEST_START,
- REQUEST_STOP,
- };
-
- // See description of |requests_| for details.
- struct RequestData {
- RequestData() : type(REQUEST_START), stop_id(0), stop_event(NULL) {}
-
- RequestType type;
- WatchData start_data;
- WatcherID stop_id;
- base::WaitableEvent* stop_event;
- };
-
- typedef std::vector<RequestData> Requests;
-
- friend struct DefaultSingletonTraits<WatcherThreadManager>;
-
- WatcherThreadManager();
-
- // Schedules a request on the background thread. See |requests_| for details.
- void AddRequest(const RequestData& data);
-
- // Processes requests added to |requests_|. This is invoked on the backend
- // thread.
- void ProcessRequestsOnBackendThread();
-
- base::Thread thread_;
-
- base::AtomicSequenceNumber watcher_id_generator_;
-
- WatcherBackend backend_;
-
- // Protects |requests_|.
- base::Lock lock_;
-
- // Start/Stop result in adding a RequestData to |requests_| (protected by
- // |lock_|). When the background thread wakes up it processes the requests.
- Requests requests_;
-
- DISALLOW_COPY_AND_ASSIGN(WatcherThreadManager);
-};
-
-WatcherThreadManager::~WatcherThreadManager() {
- thread_.Stop();
-}
-
-WatcherThreadManager* WatcherThreadManager::GetInstance() {
- return Singleton<WatcherThreadManager>::get();
-}
-
-WatcherID WatcherThreadManager::StartWatching(
- const Handle& handle,
- MojoHandleSignals handle_signals,
- base::TimeTicks deadline,
- const base::Callback<void(MojoResult)>& callback) {
- RequestData request_data;
- request_data.type = REQUEST_START;
- request_data.start_data.id = watcher_id_generator_.GetNext();
- request_data.start_data.handle = handle;
- request_data.start_data.callback = callback;
- request_data.start_data.handle_signals = handle_signals;
- request_data.start_data.deadline = deadline;
- request_data.start_data.task_runner = base::ThreadTaskRunnerHandle::Get();
- AddRequest(request_data);
- return request_data.start_data.id;
-}
-
-void WatcherThreadManager::StopWatching(WatcherID watcher_id) {
- // Handle the case of StartWatching() followed by StopWatching() before
- // |thread_| woke up.
- {
- base::AutoLock auto_lock(lock_);
- for (Requests::iterator i = requests_.begin(); i != requests_.end(); ++i) {
- if (i->type == REQUEST_START && i->start_data.id == watcher_id) {
- // Watcher ids are not reused, so if we find it we can stop.
- requests_.erase(i);
- return;
- }
- }
- }
-
- base::ThreadRestrictions::ScopedAllowWait allow_wait;
- base::WaitableEvent event(true, false);
- RequestData request_data;
- request_data.type = REQUEST_STOP;
- request_data.stop_id = watcher_id;
- request_data.stop_event = &event;
- AddRequest(request_data);
-
- // We need to block until the handle is actually removed.
- event.Wait();
-}
-
-void WatcherThreadManager::AddRequest(const RequestData& data) {
- {
- base::AutoLock auto_lock(lock_);
- const bool was_empty = requests_.empty();
- requests_.push_back(data);
- if (!was_empty)
- return;
- }
- // We own |thread_|, so it's safe to use Unretained() here.
- thread_.task_runner()->PostTask(
- FROM_HERE,
- base::Bind(&WatcherThreadManager::ProcessRequestsOnBackendThread,
- base::Unretained(this)));
-}
-
-void WatcherThreadManager::ProcessRequestsOnBackendThread() {
- DCHECK_EQ(thread_.message_loop(), base::MessageLoop::current());
-
- Requests requests;
- {
- base::AutoLock auto_lock(lock_);
- requests_.swap(requests);
- }
- for (size_t i = 0; i < requests.size(); ++i) {
- if (requests[i].type == REQUEST_START) {
- backend_.StartWatching(requests[i].start_data);
- } else {
- backend_.StopWatching(requests[i].stop_id);
- requests[i].stop_event->Signal();
- }
- }
-}
-
-WatcherThreadManager::WatcherThreadManager()
- : thread_(kWatcherThreadName) {
- base::Thread::Options thread_options;
- thread_options.message_pump_factory = base::Bind(&MessagePumpMojo::Create);
- thread_.StartWithOptions(thread_options);
-}
-
-// HandleWatcher::StateBase and subclasses -------------------------------------
-
-// The base class of HandleWatcher's state. Owns the user's callback and
-// monitors the current thread's MessageLoop to know when to force the callback
-// to run (with an error) even though the pipe hasn't been signaled yet.
-class HandleWatcher::StateBase : public base::MessageLoop::DestructionObserver {
- public:
- StateBase(HandleWatcher* watcher,
- const base::Callback<void(MojoResult)>& callback)
- : watcher_(watcher),
- callback_(callback),
- got_ready_(false) {
- base::MessageLoop::current()->AddDestructionObserver(this);
- }
-
- ~StateBase() override {
- base::MessageLoop::current()->RemoveDestructionObserver(this);
- }
-
- protected:
- void NotifyHandleReady(MojoResult result) {
- got_ready_ = true;
- NotifyAndDestroy(result);
- }
-
- bool got_ready() const { return got_ready_; }
-
- private:
- void WillDestroyCurrentMessageLoop() override {
- // The current thread is exiting. Simulate a watch error.
- NotifyAndDestroy(MOJO_RESULT_ABORTED);
- }
-
- void NotifyAndDestroy(MojoResult result) {
- base::Callback<void(MojoResult)> callback = callback_;
- watcher_->Stop(); // Destroys |this|.
-
- callback.Run(result);
- }
-
- HandleWatcher* watcher_;
- base::Callback<void(MojoResult)> callback_;
-
- // Have we been notified that the handle is ready?
- bool got_ready_;
-
- DISALLOW_COPY_AND_ASSIGN(StateBase);
-};
-
-// If the thread on which HandleWatcher is used runs MessagePumpMojo,
-// SameThreadWatchingState is used to directly watch the handle on the same
-// thread.
-class HandleWatcher::SameThreadWatchingState : public StateBase,
- public MessagePumpMojoHandler {
- public:
- SameThreadWatchingState(HandleWatcher* watcher,
- const Handle& handle,
- MojoHandleSignals handle_signals,
- MojoDeadline deadline,
- const base::Callback<void(MojoResult)>& callback)
- : StateBase(watcher, callback),
- handle_(handle) {
- DCHECK(MessagePumpMojo::IsCurrent());
-
- MessagePumpMojo::current()->AddHandler(
- this, handle, handle_signals, MojoDeadlineToTimeTicks(deadline));
- }
-
- ~SameThreadWatchingState() override {
- if (!got_ready())
- MessagePumpMojo::current()->RemoveHandler(handle_);
- }
-
- private:
- // MessagePumpMojoHandler overrides:
- void OnHandleReady(const Handle& handle) override {
- StopWatchingAndNotifyReady(handle, MOJO_RESULT_OK);
- }
-
- void OnHandleError(const Handle& handle, MojoResult result) override {
- StopWatchingAndNotifyReady(handle, result);
- }
-
- void StopWatchingAndNotifyReady(const Handle& handle, MojoResult result) {
- DCHECK_EQ(handle.value(), handle_.value());
- MessagePumpMojo::current()->RemoveHandler(handle_);
- NotifyHandleReady(result);
- }
-
- Handle handle_;
-
- DISALLOW_COPY_AND_ASSIGN(SameThreadWatchingState);
-};
-
-// If the thread on which HandleWatcher is used runs a message pump different
-// from MessagePumpMojo, SecondaryThreadWatchingState is used to watch the
-// handle on the handle watcher thread.
-class HandleWatcher::SecondaryThreadWatchingState : public StateBase {
- public:
- SecondaryThreadWatchingState(HandleWatcher* watcher,
- const Handle& handle,
- MojoHandleSignals handle_signals,
- MojoDeadline deadline,
- const base::Callback<void(MojoResult)>& callback)
- : StateBase(watcher, callback),
- weak_factory_(this) {
- watcher_id_ = WatcherThreadManager::GetInstance()->StartWatching(
- handle,
- handle_signals,
- MojoDeadlineToTimeTicks(deadline),
- base::Bind(&SecondaryThreadWatchingState::NotifyHandleReady,
- weak_factory_.GetWeakPtr()));
- }
-
- ~SecondaryThreadWatchingState() override {
- // If we've been notified the handle is ready (|got_ready()| is true) then
- // the watch has been implicitly removed by
- // WatcherThreadManager/MessagePumpMojo and we don't have to call
- // StopWatching(). To do so would needlessly entail posting a task and
- // blocking until the background thread services it.
- if (!got_ready())
- WatcherThreadManager::GetInstance()->StopWatching(watcher_id_);
- }
-
- private:
- WatcherID watcher_id_;
-
- // Used to weakly bind |this| to the WatcherThreadManager.
- base::WeakPtrFactory<SecondaryThreadWatchingState> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(SecondaryThreadWatchingState);
-};
-
-// HandleWatcher ---------------------------------------------------------------
-
-HandleWatcher::HandleWatcher() {
-}
-
-HandleWatcher::~HandleWatcher() {
-}
-
-void HandleWatcher::Start(const Handle& handle,
- MojoHandleSignals handle_signals,
- MojoDeadline deadline,
- const base::Callback<void(MojoResult)>& callback) {
- DCHECK(handle.is_valid());
- DCHECK_NE(MOJO_HANDLE_SIGNAL_NONE, handle_signals);
-
- // Need to clear the state before creating a new one.
- state_.reset();
- if (MessagePumpMojo::IsCurrent()) {
- state_.reset(new SameThreadWatchingState(
- this, handle, handle_signals, deadline, callback));
- } else {
- state_.reset(new SecondaryThreadWatchingState(
- this, handle, handle_signals, deadline, callback));
- }
-}
-
-void HandleWatcher::Stop() {
- state_.reset();
-}
-
-} // namespace common
-} // namespace mojo
diff --git a/mojo/common/handle_watcher.h b/mojo/common/handle_watcher.h
deleted file mode 100644
index 9056ec4..0000000
--- a/mojo/common/handle_watcher.h
+++ /dev/null
@@ -1,64 +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_COMMON_HANDLE_WATCHER_H_
-#define MOJO_COMMON_HANDLE_WATCHER_H_
-
-#include "base/basictypes.h"
-#include "base/callback_forward.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/run_loop.h"
-#include "mojo/common/mojo_common_export.h"
-#include "third_party/mojo/src/mojo/public/cpp/system/core.h"
-
-namespace base {
-class Thread;
-}
-
-namespace mojo {
-namespace common {
-namespace test {
-class HandleWatcherTest;
-}
-
-// HandleWatcher is used to asynchronously wait on a handle and notify a Closure
-// when the handle is ready, or the deadline has expired.
-class MOJO_COMMON_EXPORT HandleWatcher {
- public:
- HandleWatcher();
-
- // The destructor implicitly stops listening. See Stop() for details.
- ~HandleWatcher();
-
- // Starts listening for |handle|. This implicitly invokes Stop(). In other
- // words, Start() performs one asynchronous watch at a time. It is ok to call
- // Start() multiple times, but it cancels any existing watches. |callback| is
- // notified when the handle is ready, invalid or deadline has passed and is
- // notified on the thread Start() was invoked on. If the current thread exits
- // before the handle is ready, then |callback| is invoked with a result of
- // MOJO_RESULT_ABORTED.
- void Start(const Handle& handle,
- MojoHandleSignals handle_signals,
- MojoDeadline deadline,
- const base::Callback<void(MojoResult)>& callback);
-
- // Stops listening. Does nothing if not in the process of listening. Blocks
- // until no longer listening on the handle.
- void Stop();
-
- private:
- class StateBase;
- class SameThreadWatchingState;
- class SecondaryThreadWatchingState;
-
- // If non-NULL Start() has been invoked.
- scoped_ptr<StateBase> state_;
-
- DISALLOW_COPY_AND_ASSIGN(HandleWatcher);
-};
-
-} // namespace common
-} // namespace mojo
-
-#endif // MOJO_COMMON_HANDLE_WATCHER_H_
diff --git a/mojo/common/handle_watcher_unittest.cc b/mojo/common/handle_watcher_unittest.cc
deleted file mode 100644
index 41d5ffb..0000000
--- a/mojo/common/handle_watcher_unittest.cc
+++ /dev/null
@@ -1,483 +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/common/handle_watcher.h"
-
-#include <string>
-
-#include "base/at_exit.h"
-#include "base/auto_reset.h"
-#include "base/bind.h"
-#include "base/memory/scoped_vector.h"
-#include "base/run_loop.h"
-#include "base/test/simple_test_tick_clock.h"
-#include "base/threading/thread.h"
-#include "mojo/common/message_pump_mojo.h"
-#include "mojo/common/time_helper.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/mojo/src/mojo/public/cpp/system/core.h"
-#include "third_party/mojo/src/mojo/public/cpp/test_support/test_utils.h"
-
-namespace mojo {
-namespace common {
-namespace test {
-
-enum MessageLoopConfig {
- MESSAGE_LOOP_CONFIG_DEFAULT = 0,
- MESSAGE_LOOP_CONFIG_MOJO = 1
-};
-
-void ObserveCallback(bool* was_signaled,
- MojoResult* result_observed,
- MojoResult result) {
- *was_signaled = true;
- *result_observed = result;
-}
-
-void RunUntilIdle() {
- base::RunLoop run_loop;
- run_loop.RunUntilIdle();
-}
-
-void DeleteWatcherAndForwardResult(
- HandleWatcher* watcher,
- base::Callback<void(MojoResult)> next_callback,
- MojoResult result) {
- delete watcher;
- next_callback.Run(result);
-}
-
-scoped_ptr<base::MessageLoop> CreateMessageLoop(MessageLoopConfig config) {
- scoped_ptr<base::MessageLoop> loop;
- if (config == MESSAGE_LOOP_CONFIG_DEFAULT)
- loop.reset(new base::MessageLoop());
- else
- loop.reset(new base::MessageLoop(MessagePumpMojo::Create()));
- return loop.Pass();
-}
-
-// Helper class to manage the callback and running the message loop waiting for
-// message to be received. Typical usage is something like:
-// Schedule callback returned from GetCallback().
-// RunUntilGotCallback();
-// EXPECT_TRUE(got_callback());
-// clear_callback();
-class CallbackHelper {
- public:
- CallbackHelper()
- : got_callback_(false),
- run_loop_(NULL),
- weak_factory_(this) {}
- ~CallbackHelper() {}
-
- // See description above |got_callback_|.
- bool got_callback() const { return got_callback_; }
- void clear_callback() { got_callback_ = false; }
-
- // Runs the current MessageLoop until the callback returned from GetCallback()
- // is notified.
- void RunUntilGotCallback() {
- ASSERT_TRUE(run_loop_ == NULL);
- base::RunLoop run_loop;
- base::AutoReset<base::RunLoop*> reseter(&run_loop_, &run_loop);
- run_loop.Run();
- }
-
- base::Callback<void(MojoResult)> GetCallback() {
- return base::Bind(&CallbackHelper::OnCallback, weak_factory_.GetWeakPtr());
- }
-
- void Start(HandleWatcher* watcher, const MessagePipeHandle& handle) {
- StartWithCallback(watcher, handle, GetCallback());
- }
-
- void StartWithCallback(HandleWatcher* watcher,
- const MessagePipeHandle& handle,
- const base::Callback<void(MojoResult)>& callback) {
- watcher->Start(handle, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, callback);
- }
-
- private:
- void OnCallback(MojoResult result) {
- got_callback_ = true;
- if (run_loop_)
- run_loop_->Quit();
- }
-
- // Set to true when the callback is called.
- bool got_callback_;
-
- // If non-NULL we're in RunUntilGotCallback().
- base::RunLoop* run_loop_;
-
- base::WeakPtrFactory<CallbackHelper> weak_factory_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
-};
-
-class HandleWatcherTest : public testing::TestWithParam<MessageLoopConfig> {
- public:
- HandleWatcherTest() : message_loop_(CreateMessageLoop(GetParam())) {}
- virtual ~HandleWatcherTest() {
- test::SetTickClockForTest(NULL);
- }
-
- protected:
- void TearDownMessageLoop() {
- message_loop_.reset();
- }
-
- void InstallTickClock() {
- test::SetTickClockForTest(&tick_clock_);
- }
-
- base::SimpleTestTickClock tick_clock_;
-
- private:
- base::ShadowingAtExitManager at_exit_;
- scoped_ptr<base::MessageLoop> message_loop_;
-
- DISALLOW_COPY_AND_ASSIGN(HandleWatcherTest);
-};
-
-INSTANTIATE_TEST_CASE_P(
- MultipleMessageLoopConfigs, HandleWatcherTest,
- testing::Values(MESSAGE_LOOP_CONFIG_DEFAULT, MESSAGE_LOOP_CONFIG_MOJO));
-
-// Trivial test case with a single handle to watch.
-TEST_P(HandleWatcherTest, SingleHandler) {
- MessagePipe test_pipe;
- ASSERT_TRUE(test_pipe.handle0.is_valid());
- CallbackHelper callback_helper;
- HandleWatcher watcher;
- callback_helper.Start(&watcher, test_pipe.handle0.get());
- RunUntilIdle();
- EXPECT_FALSE(callback_helper.got_callback());
- EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle1.get(),
- std::string()));
- callback_helper.RunUntilGotCallback();
- EXPECT_TRUE(callback_helper.got_callback());
-}
-
-// Creates three handles and notfies them in reverse order ensuring each one is
-// notified appropriately.
-TEST_P(HandleWatcherTest, ThreeHandles) {
- MessagePipe test_pipe1;
- MessagePipe test_pipe2;
- MessagePipe test_pipe3;
- CallbackHelper callback_helper1;
- CallbackHelper callback_helper2;
- CallbackHelper callback_helper3;
- ASSERT_TRUE(test_pipe1.handle0.is_valid());
- ASSERT_TRUE(test_pipe2.handle0.is_valid());
- ASSERT_TRUE(test_pipe3.handle0.is_valid());
-
- HandleWatcher watcher1;
- callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
- RunUntilIdle();
- EXPECT_FALSE(callback_helper1.got_callback());
- EXPECT_FALSE(callback_helper2.got_callback());
- EXPECT_FALSE(callback_helper3.got_callback());
-
- HandleWatcher watcher2;
- callback_helper2.Start(&watcher2, test_pipe2.handle0.get());
- RunUntilIdle();
- EXPECT_FALSE(callback_helper1.got_callback());
- EXPECT_FALSE(callback_helper2.got_callback());
- EXPECT_FALSE(callback_helper3.got_callback());
-
- HandleWatcher watcher3;
- callback_helper3.Start(&watcher3, test_pipe3.handle0.get());
- RunUntilIdle();
- EXPECT_FALSE(callback_helper1.got_callback());
- EXPECT_FALSE(callback_helper2.got_callback());
- EXPECT_FALSE(callback_helper3.got_callback());
-
- // Write to 3 and make sure it's notified.
- EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe3.handle1.get(),
- std::string()));
- callback_helper3.RunUntilGotCallback();
- EXPECT_FALSE(callback_helper1.got_callback());
- EXPECT_FALSE(callback_helper2.got_callback());
- EXPECT_TRUE(callback_helper3.got_callback());
- callback_helper3.clear_callback();
-
- // Write to 1 and 3. Only 1 should be notified since 3 was is no longer
- // running.
- EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
- std::string()));
- EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe3.handle1.get(),
- std::string()));
- callback_helper1.RunUntilGotCallback();
- EXPECT_TRUE(callback_helper1.got_callback());
- EXPECT_FALSE(callback_helper2.got_callback());
- EXPECT_FALSE(callback_helper3.got_callback());
- callback_helper1.clear_callback();
-
- // Write to 1 and 2. Only 2 should be notified (since 1 was already notified).
- EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
- std::string()));
- EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe2.handle1.get(),
- std::string()));
- callback_helper2.RunUntilGotCallback();
- EXPECT_FALSE(callback_helper1.got_callback());
- EXPECT_TRUE(callback_helper2.got_callback());
- EXPECT_FALSE(callback_helper3.got_callback());
-}
-
-// Verifies Start() invoked a second time works.
-TEST_P(HandleWatcherTest, Restart) {
- MessagePipe test_pipe1;
- MessagePipe test_pipe2;
- CallbackHelper callback_helper1;
- CallbackHelper callback_helper2;
- ASSERT_TRUE(test_pipe1.handle0.is_valid());
- ASSERT_TRUE(test_pipe2.handle0.is_valid());
-
- HandleWatcher watcher1;
- callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
- RunUntilIdle();
- EXPECT_FALSE(callback_helper1.got_callback());
- EXPECT_FALSE(callback_helper2.got_callback());
-
- HandleWatcher watcher2;
- callback_helper2.Start(&watcher2, test_pipe2.handle0.get());
- RunUntilIdle();
- EXPECT_FALSE(callback_helper1.got_callback());
- EXPECT_FALSE(callback_helper2.got_callback());
-
- // Write to 1 and make sure it's notified.
- EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
- std::string()));
- callback_helper1.RunUntilGotCallback();
- EXPECT_TRUE(callback_helper1.got_callback());
- EXPECT_FALSE(callback_helper2.got_callback());
- callback_helper1.clear_callback();
- EXPECT_TRUE(mojo::test::DiscardMessage(test_pipe1.handle0.get()));
-
- // Write to 2 and make sure it's notified.
- EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe2.handle1.get(),
- std::string()));
- callback_helper2.RunUntilGotCallback();
- EXPECT_FALSE(callback_helper1.got_callback());
- EXPECT_TRUE(callback_helper2.got_callback());
- callback_helper2.clear_callback();
-
- // Listen on 1 again.
- callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
- RunUntilIdle();
- EXPECT_FALSE(callback_helper1.got_callback());
- EXPECT_FALSE(callback_helper2.got_callback());
-
- // Write to 1 and make sure it's notified.
- EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe1.handle1.get(),
- std::string()));
- callback_helper1.RunUntilGotCallback();
- EXPECT_TRUE(callback_helper1.got_callback());
- EXPECT_FALSE(callback_helper2.got_callback());
-}
-
-// Verifies Start() invoked a second time on the same handle works.
-TEST_P(HandleWatcherTest, RestartOnSameHandle) {
- MessagePipe test_pipe;
- CallbackHelper callback_helper;
- ASSERT_TRUE(test_pipe.handle0.is_valid());
-
- HandleWatcher watcher;
- callback_helper.Start(&watcher, test_pipe.handle0.get());
- RunUntilIdle();
- EXPECT_FALSE(callback_helper.got_callback());
-
- callback_helper.Start(&watcher, test_pipe.handle0.get());
- RunUntilIdle();
- EXPECT_FALSE(callback_helper.got_callback());
-}
-
-// Verifies deadline is honored.
-TEST_P(HandleWatcherTest, Deadline) {
- InstallTickClock();
-
- MessagePipe test_pipe1;
- MessagePipe test_pipe2;
- MessagePipe test_pipe3;
- CallbackHelper callback_helper1;
- CallbackHelper callback_helper2;
- CallbackHelper callback_helper3;
- ASSERT_TRUE(test_pipe1.handle0.is_valid());
- ASSERT_TRUE(test_pipe2.handle0.is_valid());
- ASSERT_TRUE(test_pipe3.handle0.is_valid());
-
- // Add a watcher with an infinite timeout.
- HandleWatcher watcher1;
- callback_helper1.Start(&watcher1, test_pipe1.handle0.get());
- RunUntilIdle();
- EXPECT_FALSE(callback_helper1.got_callback());
- EXPECT_FALSE(callback_helper2.got_callback());
- EXPECT_FALSE(callback_helper3.got_callback());
-
- // Add another watcher wth a timeout of 500 microseconds.
- HandleWatcher watcher2;
- watcher2.Start(test_pipe2.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE, 500,
- callback_helper2.GetCallback());
- RunUntilIdle();
- EXPECT_FALSE(callback_helper1.got_callback());
- EXPECT_FALSE(callback_helper2.got_callback());
- EXPECT_FALSE(callback_helper3.got_callback());
-
- // Advance the clock passed the deadline. We also have to start another
- // watcher to wake up the background thread.
- tick_clock_.Advance(base::TimeDelta::FromMicroseconds(501));
-
- HandleWatcher watcher3;
- callback_helper3.Start(&watcher3, test_pipe3.handle0.get());
-
- callback_helper2.RunUntilGotCallback();
- EXPECT_FALSE(callback_helper1.got_callback());
- EXPECT_TRUE(callback_helper2.got_callback());
- EXPECT_FALSE(callback_helper3.got_callback());
-}
-
-TEST_P(HandleWatcherTest, DeleteInCallback) {
- MessagePipe test_pipe;
- CallbackHelper callback_helper;
-
- HandleWatcher* watcher = new HandleWatcher();
- callback_helper.StartWithCallback(watcher, test_pipe.handle1.get(),
- base::Bind(&DeleteWatcherAndForwardResult,
- watcher,
- callback_helper.GetCallback()));
- EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle0.get(),
- std::string()));
- callback_helper.RunUntilGotCallback();
- EXPECT_TRUE(callback_helper.got_callback());
-}
-
-TEST_P(HandleWatcherTest, AbortedOnMessageLoopDestruction) {
- bool was_signaled = false;
- MojoResult result = MOJO_RESULT_OK;
-
- MessagePipe pipe;
- HandleWatcher watcher;
- watcher.Start(pipe.handle0.get(),
- MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE,
- base::Bind(&ObserveCallback, &was_signaled, &result));
-
- // Now, let the MessageLoop get torn down. We expect our callback to run.
- TearDownMessageLoop();
-
- EXPECT_TRUE(was_signaled);
- EXPECT_EQ(MOJO_RESULT_ABORTED, result);
-}
-
-void NeverReached(MojoResult result) {
- FAIL() << "Callback should never be invoked " << result;
-}
-
-// Called on the main thread when a thread is done. Decrements |active_count|
-// and if |active_count| is zero quits |run_loop|.
-void StressThreadDone(base::RunLoop* run_loop, int* active_count) {
- (*active_count)--;
- EXPECT_GE(*active_count, 0);
- if (*active_count == 0)
- run_loop->Quit();
-}
-
-// See description of StressTest. This is called on the background thread.
-// |count| is the number of HandleWatchers to create. |active_count| is the
-// number of outstanding threads, |task_runner| the task runner for the main
-// thread and |run_loop| the run loop that should be quit when there are no more
-// threads running. When done StressThreadDone() is invoked on the main thread.
-// |active_count| and |run_loop| should only be used on the main thread.
-void RunStressTest(int count,
- scoped_refptr<base::TaskRunner> task_runner,
- base::RunLoop* run_loop,
- int* active_count) {
- struct TestData {
- MessagePipe pipe;
- HandleWatcher watcher;
- };
- ScopedVector<TestData> data_vector;
- for (int i = 0; i < count; ++i) {
- if (i % 20 == 0) {
- // Every so often we wait. This results in some level of thread balancing
- // as well as making sure HandleWatcher has time to actually start some
- // watches.
- MessagePipe test_pipe;
- ASSERT_TRUE(test_pipe.handle0.is_valid());
- CallbackHelper callback_helper;
- HandleWatcher watcher;
- callback_helper.Start(&watcher, test_pipe.handle0.get());
- RunUntilIdle();
- EXPECT_FALSE(callback_helper.got_callback());
- EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle1.get(),
- std::string()));
- base::MessageLoop::ScopedNestableTaskAllower scoper(
- base::MessageLoop::current());
- callback_helper.RunUntilGotCallback();
- EXPECT_TRUE(callback_helper.got_callback());
- } else {
- scoped_ptr<TestData> test_data(new TestData);
- ASSERT_TRUE(test_data->pipe.handle0.is_valid());
- test_data->watcher.Start(test_data->pipe.handle0.get(),
- MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE,
- base::Bind(&NeverReached));
- data_vector.push_back(test_data.release());
- }
- if (i % 15 == 0)
- data_vector.clear();
- }
- task_runner->PostTask(FROM_HERE,
- base::Bind(&StressThreadDone, run_loop,
- active_count));
-}
-
-// This test is meant to stress HandleWatcher. It uses from various threads
-// repeatedly starting and stopping watches. It spins up kThreadCount
-// threads. Each thread creates kWatchCount watches. Every so often each thread
-// writes to a pipe and waits for the response.
-TEST(HandleWatcherCleanEnvironmentTest, StressTest) {
-#if defined(NDEBUG)
- const int kThreadCount = 15;
- const int kWatchCount = 400;
-#else
- const int kThreadCount = 10;
- const int kWatchCount = 250;
-#endif
-
- base::ShadowingAtExitManager at_exit;
- base::MessageLoop message_loop;
- base::RunLoop run_loop;
- ScopedVector<base::Thread> threads;
- int threads_active_counter = kThreadCount;
- // Starts the threads first and then post the task in hopes of having more
- // threads running at once.
- for (int i = 0; i < kThreadCount; ++i) {
- scoped_ptr<base::Thread> thread(new base::Thread("test thread"));
- if (i % 2) {
- base::Thread::Options thread_options;
- thread_options.message_pump_factory =
- base::Bind(&MessagePumpMojo::Create);
- thread->StartWithOptions(thread_options);
- } else {
- thread->Start();
- }
- threads.push_back(thread.release());
- }
- for (int i = 0; i < kThreadCount; ++i) {
- threads[i]->task_runner()->PostTask(
- FROM_HERE, base::Bind(&RunStressTest, kWatchCount,
- message_loop.task_runner(),
- &run_loop, &threads_active_counter));
- }
- run_loop.Run();
- ASSERT_EQ(0, threads_active_counter);
-}
-
-} // namespace test
-} // namespace common
-} // namespace mojo
diff --git a/mojo/common/message_pump_mojo.cc b/mojo/common/message_pump_mojo.cc
deleted file mode 100644
index afbf8f9..0000000
--- a/mojo/common/message_pump_mojo.cc
+++ /dev/null
@@ -1,295 +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/common/message_pump_mojo.h"
-
-#include <algorithm>
-#include <vector>
-
-#include "base/debug/alias.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/threading/thread_local.h"
-#include "base/time/time.h"
-#include "mojo/common/message_pump_mojo_handler.h"
-#include "mojo/common/time_helper.h"
-
-namespace mojo {
-namespace common {
-namespace {
-
-base::LazyInstance<base::ThreadLocalPointer<MessagePumpMojo> >::Leaky
- g_tls_current_pump = LAZY_INSTANCE_INITIALIZER;
-
-MojoDeadline TimeTicksToMojoDeadline(base::TimeTicks time_ticks,
- base::TimeTicks now) {
- // The is_null() check matches that of HandleWatcher as well as how
- // |delayed_work_time| is used.
- if (time_ticks.is_null())
- return MOJO_DEADLINE_INDEFINITE;
- const int64_t delta = (time_ticks - now).InMicroseconds();
- return delta < 0 ? static_cast<MojoDeadline>(0) :
- static_cast<MojoDeadline>(delta);
-}
-
-} // namespace
-
-// State needed for one iteration of WaitMany. The first handle and flags
-// corresponds to that of the control pipe.
-struct MessagePumpMojo::WaitState {
- std::vector<Handle> handles;
- std::vector<MojoHandleSignals> wait_signals;
-};
-
-struct MessagePumpMojo::RunState {
- RunState() : should_quit(false) {
- CreateMessagePipe(NULL, &read_handle, &write_handle);
- }
-
- base::TimeTicks delayed_work_time;
-
- // Used to wake up WaitForWork().
- ScopedMessagePipeHandle read_handle;
- ScopedMessagePipeHandle write_handle;
-
- bool should_quit;
-};
-
-MessagePumpMojo::MessagePumpMojo() : run_state_(NULL), next_handler_id_(0) {
- DCHECK(!current())
- << "There is already a MessagePumpMojo instance on this thread.";
- g_tls_current_pump.Pointer()->Set(this);
-}
-
-MessagePumpMojo::~MessagePumpMojo() {
- DCHECK_EQ(this, current());
- g_tls_current_pump.Pointer()->Set(NULL);
-}
-
-// static
-scoped_ptr<base::MessagePump> MessagePumpMojo::Create() {
- return scoped_ptr<MessagePump>(new MessagePumpMojo());
-}
-
-// static
-MessagePumpMojo* MessagePumpMojo::current() {
- return g_tls_current_pump.Pointer()->Get();
-}
-
-void MessagePumpMojo::AddHandler(MessagePumpMojoHandler* handler,
- const Handle& handle,
- MojoHandleSignals wait_signals,
- base::TimeTicks deadline) {
- CHECK(handler);
- DCHECK(handle.is_valid());
- // Assume it's an error if someone tries to reregister an existing handle.
- CHECK_EQ(0u, handlers_.count(handle));
- Handler handler_data;
- handler_data.handler = handler;
- handler_data.wait_signals = wait_signals;
- handler_data.deadline = deadline;
- handler_data.id = next_handler_id_++;
- handlers_[handle] = handler_data;
-}
-
-void MessagePumpMojo::RemoveHandler(const Handle& handle) {
- handlers_.erase(handle);
-}
-
-void MessagePumpMojo::AddObserver(Observer* observer) {
- observers_.AddObserver(observer);
-}
-
-void MessagePumpMojo::RemoveObserver(Observer* observer) {
- observers_.RemoveObserver(observer);
-}
-
-void MessagePumpMojo::Run(Delegate* delegate) {
- RunState run_state;
- // TODO: better deal with error handling.
- CHECK(run_state.read_handle.is_valid());
- CHECK(run_state.write_handle.is_valid());
- RunState* old_state = NULL;
- {
- base::AutoLock auto_lock(run_state_lock_);
- old_state = run_state_;
- run_state_ = &run_state;
- }
- DoRunLoop(&run_state, delegate);
- {
- base::AutoLock auto_lock(run_state_lock_);
- run_state_ = old_state;
- }
-}
-
-void MessagePumpMojo::Quit() {
- base::AutoLock auto_lock(run_state_lock_);
- if (run_state_)
- run_state_->should_quit = true;
-}
-
-void MessagePumpMojo::ScheduleWork() {
- base::AutoLock auto_lock(run_state_lock_);
- if (run_state_)
- SignalControlPipe(*run_state_);
-}
-
-void MessagePumpMojo::ScheduleDelayedWork(
- const base::TimeTicks& delayed_work_time) {
- base::AutoLock auto_lock(run_state_lock_);
- if (!run_state_)
- return;
- run_state_->delayed_work_time = delayed_work_time;
-}
-
-void MessagePumpMojo::DoRunLoop(RunState* run_state, Delegate* delegate) {
- bool more_work_is_plausible = true;
- for (;;) {
- const bool block = !more_work_is_plausible;
- more_work_is_plausible = DoInternalWork(*run_state, block);
-
- if (run_state->should_quit)
- break;
-
- more_work_is_plausible |= delegate->DoWork();
- if (run_state->should_quit)
- break;
-
- more_work_is_plausible |= delegate->DoDelayedWork(
- &run_state->delayed_work_time);
- if (run_state->should_quit)
- break;
-
- if (more_work_is_plausible)
- continue;
-
- more_work_is_plausible = delegate->DoIdleWork();
- if (run_state->should_quit)
- break;
- }
-}
-
-bool MessagePumpMojo::DoInternalWork(const RunState& run_state, bool block) {
- const MojoDeadline deadline = block ? GetDeadlineForWait(run_state) : 0;
- const WaitState wait_state = GetWaitState(run_state);
-
- const WaitManyResult wait_many_result =
- WaitMany(wait_state.handles, wait_state.wait_signals, deadline, nullptr);
- const MojoResult result = wait_many_result.result;
- bool did_work = true;
- if (result == MOJO_RESULT_OK) {
- if (wait_many_result.index == 0) {
- // Control pipe was written to.
- ReadMessageRaw(run_state.read_handle.get(), NULL, NULL, NULL, NULL,
- MOJO_READ_MESSAGE_FLAG_MAY_DISCARD);
- } else {
- DCHECK(handlers_.find(wait_state.handles[wait_many_result.index]) !=
- handlers_.end());
- WillSignalHandler();
- handlers_[wait_state.handles[wait_many_result.index]]
- .handler->OnHandleReady(wait_state.handles[wait_many_result.index]);
- DidSignalHandler();
- }
- } else {
- switch (result) {
- case MOJO_RESULT_CANCELLED:
- case MOJO_RESULT_FAILED_PRECONDITION:
- RemoveInvalidHandle(wait_state, result, wait_many_result.index);
- break;
- case MOJO_RESULT_DEADLINE_EXCEEDED:
- did_work = false;
- break;
- default:
- base::debug::Alias(&result);
- // Unexpected result is likely fatal, crash so we can determine cause.
- CHECK(false);
- }
- }
-
- // Notify and remove any handlers whose time has expired. Make a copy in case
- // someone tries to add/remove new handlers from notification.
- const HandleToHandler cloned_handlers(handlers_);
- const base::TimeTicks now(internal::NowTicks());
- for (HandleToHandler::const_iterator i = cloned_handlers.begin();
- i != cloned_handlers.end(); ++i) {
- // Since we're iterating over a clone of the handlers, verify the handler is
- // still valid before notifying.
- if (!i->second.deadline.is_null() && i->second.deadline < now &&
- handlers_.find(i->first) != handlers_.end() &&
- handlers_[i->first].id == i->second.id) {
- WillSignalHandler();
- i->second.handler->OnHandleError(i->first, MOJO_RESULT_DEADLINE_EXCEEDED);
- DidSignalHandler();
- handlers_.erase(i->first);
- did_work = true;
- }
- }
- return did_work;
-}
-
-void MessagePumpMojo::RemoveInvalidHandle(const WaitState& wait_state,
- MojoResult result,
- uint32_t index) {
- // TODO(sky): deal with control pipe going bad.
- CHECK(result == MOJO_RESULT_FAILED_PRECONDITION ||
- result == MOJO_RESULT_CANCELLED);
- CHECK_NE(index, 0u); // Indicates the control pipe went bad.
-
- // Remove the handle first, this way if OnHandleError() tries to remove the
- // handle our iterator isn't invalidated.
- CHECK(handlers_.find(wait_state.handles[index]) != handlers_.end());
- MessagePumpMojoHandler* handler =
- handlers_[wait_state.handles[index]].handler;
- handlers_.erase(wait_state.handles[index]);
- WillSignalHandler();
- handler->OnHandleError(wait_state.handles[index], result);
- DidSignalHandler();
-}
-
-void MessagePumpMojo::SignalControlPipe(const RunState& run_state) {
- const MojoResult result =
- WriteMessageRaw(run_state.write_handle.get(), NULL, 0, NULL, 0,
- MOJO_WRITE_MESSAGE_FLAG_NONE);
- // If we can't write we likely won't wake up the thread and there is a strong
- // chance we'll deadlock.
- CHECK_EQ(MOJO_RESULT_OK, result);
-}
-
-MessagePumpMojo::WaitState MessagePumpMojo::GetWaitState(
- const RunState& run_state) const {
- WaitState wait_state;
- wait_state.handles.push_back(run_state.read_handle.get());
- wait_state.wait_signals.push_back(MOJO_HANDLE_SIGNAL_READABLE);
-
- for (HandleToHandler::const_iterator i = handlers_.begin();
- i != handlers_.end(); ++i) {
- wait_state.handles.push_back(i->first);
- wait_state.wait_signals.push_back(i->second.wait_signals);
- }
- return wait_state;
-}
-
-MojoDeadline MessagePumpMojo::GetDeadlineForWait(
- const RunState& run_state) const {
- const base::TimeTicks now(internal::NowTicks());
- MojoDeadline deadline = TimeTicksToMojoDeadline(run_state.delayed_work_time,
- now);
- for (HandleToHandler::const_iterator i = handlers_.begin();
- i != handlers_.end(); ++i) {
- deadline = std::min(
- TimeTicksToMojoDeadline(i->second.deadline, now), deadline);
- }
- return deadline;
-}
-
-void MessagePumpMojo::WillSignalHandler() {
- FOR_EACH_OBSERVER(Observer, observers_, WillSignalHandler());
-}
-
-void MessagePumpMojo::DidSignalHandler() {
- FOR_EACH_OBSERVER(Observer, observers_, DidSignalHandler());
-}
-
-} // namespace common
-} // namespace mojo
diff --git a/mojo/common/message_pump_mojo.h b/mojo/common/message_pump_mojo.h
deleted file mode 100644
index 86dd8ac..0000000
--- a/mojo/common/message_pump_mojo.h
+++ /dev/null
@@ -1,136 +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_COMMON_MESSAGE_PUMP_MOJO_H_
-#define MOJO_COMMON_MESSAGE_PUMP_MOJO_H_
-
-#include <map>
-
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_pump.h"
-#include "base/observer_list.h"
-#include "base/synchronization/lock.h"
-#include "base/time/time.h"
-#include "mojo/common/mojo_common_export.h"
-#include "third_party/mojo/src/mojo/public/cpp/system/core.h"
-
-namespace mojo {
-namespace common {
-
-class MessagePumpMojoHandler;
-
-// Mojo implementation of MessagePump.
-class MOJO_COMMON_EXPORT MessagePumpMojo : public base::MessagePump {
- public:
- class Observer {
- public:
- Observer() {}
-
- virtual void WillSignalHandler() = 0;
- virtual void DidSignalHandler() = 0;
-
- protected:
- virtual ~Observer() {}
- };
-
- MessagePumpMojo();
- ~MessagePumpMojo() override;
-
- // Static factory function (for using with |base::Thread::Options|, wrapped
- // using |base::Bind()|).
- static scoped_ptr<base::MessagePump> Create();
-
- // Returns the MessagePumpMojo instance of the current thread, if it exists.
- static MessagePumpMojo* current();
-
- static bool IsCurrent() { return !!current(); }
-
- // Registers a MessagePumpMojoHandler for the specified handle. Only one
- // handler can be registered for a specified handle.
- // NOTE: a value of 0 for |deadline| indicates an indefinite timeout.
- void AddHandler(MessagePumpMojoHandler* handler,
- const Handle& handle,
- MojoHandleSignals wait_signals,
- base::TimeTicks deadline);
-
- void RemoveHandler(const Handle& handle);
-
- void AddObserver(Observer*);
- void RemoveObserver(Observer*);
-
- // MessagePump:
- void Run(Delegate* delegate) override;
- void Quit() override;
- void ScheduleWork() override;
- void ScheduleDelayedWork(const base::TimeTicks& delayed_work_time) override;
-
- private:
- struct RunState;
- struct WaitState;
-
- // Contains the data needed to track a request to AddHandler().
- struct Handler {
- Handler() : handler(NULL), wait_signals(MOJO_HANDLE_SIGNAL_NONE), id(0) {}
-
- MessagePumpMojoHandler* handler;
- MojoHandleSignals wait_signals;
- base::TimeTicks deadline;
- // See description of |MessagePumpMojo::next_handler_id_| for details.
- int id;
- };
-
- typedef std::map<Handle, Handler> HandleToHandler;
-
- // Implementation of Run().
- void DoRunLoop(RunState* run_state, Delegate* delegate);
-
- // Services the set of handles ready. If |block| is true this waits for a
- // handle to become ready, otherwise this does not block. Returns |true| if a
- // handle has become ready, |false| otherwise.
- bool DoInternalWork(const RunState& run_state, bool block);
-
- // Removes the given invalid handle. This is called if MojoWaitMany finds an
- // invalid handle.
- void RemoveInvalidHandle(const WaitState& wait_state,
- MojoResult result,
- uint32_t result_index);
-
- void SignalControlPipe(const RunState& run_state);
-
- WaitState GetWaitState(const RunState& run_state) const;
-
- // Returns the deadline for the call to MojoWaitMany().
- MojoDeadline GetDeadlineForWait(const RunState& run_state) const;
-
- void WillSignalHandler();
- void DidSignalHandler();
-
- // If non-NULL we're running (inside Run()). Member is reference to value on
- // stack.
- RunState* run_state_;
-
- // Lock for accessing |run_state_|. In general the only method that we have to
- // worry about is ScheduleWork(). All other methods are invoked on the same
- // thread.
- base::Lock run_state_lock_;
-
- HandleToHandler handlers_;
-
- // An ever increasing value assigned to each Handler::id. Used to detect
- // uniqueness while notifying. That is, while notifying expired timers we copy
- // |handlers_| and only notify handlers whose id match. If the id does not
- // match it means the handler was removed then added so that we shouldn't
- // notify it.
- int next_handler_id_;
-
- base::ObserverList<Observer> observers_;
-
- DISALLOW_COPY_AND_ASSIGN(MessagePumpMojo);
-};
-
-} // namespace common
-} // namespace mojo
-
-#endif // MOJO_COMMON_MESSAGE_PUMP_MOJO_H_
diff --git a/mojo/common/message_pump_mojo_handler.h b/mojo/common/message_pump_mojo_handler.h
deleted file mode 100644
index dd136ed..0000000
--- a/mojo/common/message_pump_mojo_handler.h
+++ /dev/null
@@ -1,29 +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_COMMON_MESSAGE_PUMP_MOJO_HANDLER_H_
-#define MOJO_COMMON_MESSAGE_PUMP_MOJO_HANDLER_H_
-
-#include "mojo/common/mojo_common_export.h"
-#include "third_party/mojo/src/mojo/public/cpp/system/core.h"
-
-namespace mojo {
-namespace common {
-
-// Used by MessagePumpMojo to notify when a handle is either ready or has become
-// invalid. In case of error, the handler will be removed.
-class MOJO_COMMON_EXPORT MessagePumpMojoHandler {
- public:
- virtual void OnHandleReady(const Handle& handle) = 0;
-
- virtual void OnHandleError(const Handle& handle, MojoResult result) = 0;
-
- protected:
- virtual ~MessagePumpMojoHandler() {}
-};
-
-} // namespace common
-} // namespace mojo
-
-#endif // MOJO_COMMON_MESSAGE_PUMP_MOJO_HANDLER_H_
diff --git a/mojo/common/message_pump_mojo_unittest.cc b/mojo/common/message_pump_mojo_unittest.cc
deleted file mode 100644
index 5d695f6..0000000
--- a/mojo/common/message_pump_mojo_unittest.cc
+++ /dev/null
@@ -1,124 +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/common/message_pump_mojo.h"
-
-#include "base/message_loop/message_loop_test.h"
-#include "base/run_loop.h"
-#include "mojo/common/message_pump_mojo_handler.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/mojo/src/mojo/public/cpp/system/core.h"
-
-namespace mojo {
-namespace common {
-namespace test {
-
-scoped_ptr<base::MessagePump> CreateMojoMessagePump() {
- return scoped_ptr<base::MessagePump>(new MessagePumpMojo());
-}
-
-RUN_MESSAGE_LOOP_TESTS(Mojo, &CreateMojoMessagePump);
-
-class CountingMojoHandler : public MessagePumpMojoHandler {
- public:
- CountingMojoHandler() : success_count_(0), error_count_(0) {}
-
- void OnHandleReady(const Handle& handle) override {
- ReadMessageRaw(static_cast<const MessagePipeHandle&>(handle),
- NULL,
- NULL,
- NULL,
- NULL,
- MOJO_READ_MESSAGE_FLAG_NONE);
- ++success_count_;
- }
- void OnHandleError(const Handle& handle, MojoResult result) override {
- ++error_count_;
- }
-
- int success_count() { return success_count_; }
- int error_count() { return error_count_; }
-
- private:
- int success_count_;
- int error_count_;
-
- DISALLOW_COPY_AND_ASSIGN(CountingMojoHandler);
-};
-
-class CountingObserver : public MessagePumpMojo::Observer {
- public:
- void WillSignalHandler() override { will_signal_handler_count++; }
- void DidSignalHandler() override { did_signal_handler_count++; }
-
- int will_signal_handler_count = 0;
- int did_signal_handler_count = 0;
-};
-
-TEST(MessagePumpMojo, RunUntilIdle) {
- base::MessageLoop message_loop(MessagePumpMojo::Create());
- CountingMojoHandler handler;
- MessagePipe handles;
- MessagePumpMojo::current()->AddHandler(&handler,
- handles.handle0.get(),
- MOJO_HANDLE_SIGNAL_READABLE,
- base::TimeTicks());
- WriteMessageRaw(
- handles.handle1.get(), NULL, 0, NULL, 0, MOJO_WRITE_MESSAGE_FLAG_NONE);
- WriteMessageRaw(
- handles.handle1.get(), NULL, 0, NULL, 0, MOJO_WRITE_MESSAGE_FLAG_NONE);
- base::RunLoop run_loop;
- run_loop.RunUntilIdle();
- EXPECT_EQ(2, handler.success_count());
-}
-
-TEST(MessagePumpMojo, Observer) {
- base::MessageLoop message_loop(MessagePumpMojo::Create());
-
- CountingObserver observer;
- MessagePumpMojo::current()->AddObserver(&observer);
-
- CountingMojoHandler handler;
- MessagePipe handles;
- MessagePumpMojo::current()->AddHandler(&handler,
- handles.handle0.get(),
- MOJO_HANDLE_SIGNAL_READABLE,
- base::TimeTicks());
- WriteMessageRaw(
- handles.handle1.get(), NULL, 0, NULL, 0, MOJO_WRITE_MESSAGE_FLAG_NONE);
- base::RunLoop run_loop;
- run_loop.RunUntilIdle();
- EXPECT_EQ(1, handler.success_count());
- EXPECT_EQ(1, observer.will_signal_handler_count);
- EXPECT_EQ(1, observer.did_signal_handler_count);
- MessagePumpMojo::current()->RemoveObserver(&observer);
-
- WriteMessageRaw(
- handles.handle1.get(), NULL, 0, NULL, 0, MOJO_WRITE_MESSAGE_FLAG_NONE);
- base::RunLoop run_loop2;
- run_loop2.RunUntilIdle();
- EXPECT_EQ(2, handler.success_count());
- EXPECT_EQ(1, observer.will_signal_handler_count);
- EXPECT_EQ(1, observer.did_signal_handler_count);
-}
-
-TEST(MessagePumpMojo, UnregisterAfterDeadline) {
- base::MessageLoop message_loop(MessagePumpMojo::Create());
- CountingMojoHandler handler;
- MessagePipe handles;
- MessagePumpMojo::current()->AddHandler(
- &handler,
- handles.handle0.get(),
- MOJO_HANDLE_SIGNAL_READABLE,
- base::TimeTicks::Now() - base::TimeDelta::FromSeconds(1));
- for (int i = 0; i < 2; ++i) {
- base::RunLoop run_loop;
- run_loop.RunUntilIdle();
- }
- EXPECT_EQ(1, handler.error_count());
-}
-
-} // namespace test
-} // namespace common
-} // namespace mojo
diff --git a/mojo/common/time_helper.cc b/mojo/common/time_helper.cc
deleted file mode 100644
index 36fd087..0000000
--- a/mojo/common/time_helper.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// 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/common/time_helper.h"
-
-#include "base/time/tick_clock.h"
-
-namespace mojo {
-namespace common {
-
-namespace {
-
-base::TickClock* tick_clock = NULL;
-
-} // namespace
-
-namespace test {
-
-void SetTickClockForTest(base::TickClock* clock) {
- tick_clock = clock;
-}
-} // namespace test
-
-namespace internal {
-
-base::TimeTicks NowTicks() {
- return tick_clock ? tick_clock->NowTicks() : base::TimeTicks::Now();
-}
-
-} // namespace internal
-} // namespace common
-} // namespace mojo
diff --git a/mojo/common/time_helper.h b/mojo/common/time_helper.h
deleted file mode 100644
index 365ae04..0000000
--- a/mojo/common/time_helper.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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_COMMON_TIME_HELPER_H_
-#define MOJO_COMMON_TIME_HELPER_H_
-
-#include "base/time/time.h"
-#include "mojo/common/mojo_common_export.h"
-
-namespace base {
-class TickClock;
-}
-
-namespace mojo {
-namespace common {
-namespace test {
-
-// Sets the TickClock used for getting TimeTicks::Now(). This is currently used
-// by both HandleWatcher and MessagePumpMojo.
-MOJO_COMMON_EXPORT void SetTickClockForTest(base::TickClock* clock);
-
-} // namespace test
-
-namespace internal {
-
-// Returns now. Used internally; generally not useful.
-MOJO_COMMON_EXPORT base::TimeTicks NowTicks();
-
-} // namespace internal
-} // namespace common
-} // namespace mojo
-
-#endif // MOJO_COMMON_TIME_HELPER_H_