diff options
Diffstat (limited to 'mojo/public/cpp/system')
-rw-r--r-- | mojo/public/cpp/system/BUILD.gn | 2 | ||||
-rw-r--r-- | mojo/public/cpp/system/tests/BUILD.gn | 2 | ||||
-rw-r--r-- | mojo/public/cpp/system/tests/watcher_unittest.cc | 186 | ||||
-rw-r--r-- | mojo/public/cpp/system/watcher.cc | 134 | ||||
-rw-r--r-- | mojo/public/cpp/system/watcher.h | 117 |
5 files changed, 0 insertions, 441 deletions
diff --git a/mojo/public/cpp/system/BUILD.gn b/mojo/public/cpp/system/BUILD.gn index dc2d28c..d5298f2 100644 --- a/mojo/public/cpp/system/BUILD.gn +++ b/mojo/public/cpp/system/BUILD.gn @@ -11,8 +11,6 @@ source_set("system") { "handle.h", "macros.h", "message_pipe.h", - "watcher.cc", - "watcher.h", ] public_deps = [ diff --git a/mojo/public/cpp/system/tests/BUILD.gn b/mojo/public/cpp/system/tests/BUILD.gn index e7c8f29..068f009 100644 --- a/mojo/public/cpp/system/tests/BUILD.gn +++ b/mojo/public/cpp/system/tests/BUILD.gn @@ -8,11 +8,9 @@ source_set("tests") { sources = [ "core_unittest.cc", "macros_unittest.cc", - "watcher_unittest.cc", ] deps = [ - "//base", "//mojo/public/c/system/tests", "//mojo/public/cpp/environment:standalone", "//mojo/public/cpp/system", diff --git a/mojo/public/cpp/system/tests/watcher_unittest.cc b/mojo/public/cpp/system/tests/watcher_unittest.cc deleted file mode 100644 index ea78a56..0000000 --- a/mojo/public/cpp/system/tests/watcher_unittest.cc +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright 2016 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 "base/bind.h" -#include "base/callback.h" -#include "base/memory/scoped_ptr.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/thread_task_runner_handle.h" -#include "mojo/public/c/system/types.h" -#include "mojo/public/cpp/system/message_pipe.h" -#include "mojo/public/cpp/system/watcher.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace { - -template <typename Handler> -void RunResultHandler(Handler f, MojoResult result) { f(result); } - -template <typename Handler> -Watcher::ReadyCallback OnReady(Handler f) { - return base::Bind(&RunResultHandler<Handler>, f); -} - -Watcher::ReadyCallback NotReached() { - return OnReady([] (MojoResult) { NOTREACHED(); }); -} - -class WatcherTest : public testing::Test { - public: - WatcherTest() {} - ~WatcherTest() override {} - - void SetUp() override { - message_loop_.reset(new base::MessageLoop); - } - - void TearDown() override { - message_loop_.reset(); - } - - protected: - scoped_ptr<base::MessageLoop> message_loop_; -}; - -TEST_F(WatcherTest, WatchBasic) { - ScopedMessagePipeHandle a, b; - CreateMessagePipe(nullptr, &a, &b); - - bool notified = false; - base::RunLoop run_loop; - Watcher b_watcher; - EXPECT_EQ(MOJO_RESULT_OK, - b_watcher.Start(b.get(), MOJO_HANDLE_SIGNAL_READABLE, - OnReady([&] (MojoResult result) { - EXPECT_EQ(MOJO_RESULT_OK, result); - notified = true; - run_loop.Quit(); - }))); - EXPECT_TRUE(b_watcher.IsWatching()); - - EXPECT_EQ(MOJO_RESULT_OK, WriteMessageRaw(a.get(), "hello", 5, nullptr, 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); - run_loop.Run(); - EXPECT_TRUE(notified); - - b_watcher.Cancel(); -} - -TEST_F(WatcherTest, WatchUnsatisfiable) { - ScopedMessagePipeHandle a, b; - CreateMessagePipe(nullptr, &a, &b); - a.reset(); - - Watcher b_watcher; - EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, - b_watcher.Start(b.get(), MOJO_HANDLE_SIGNAL_READABLE, - NotReached())); - EXPECT_FALSE(b_watcher.IsWatching()); -} - -TEST_F(WatcherTest, WatchInvalidHandle) { - ScopedMessagePipeHandle a, b; - CreateMessagePipe(nullptr, &a, &b); - a.reset(); - b.reset(); - - Watcher b_watcher; - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, - b_watcher.Start(b.get(), MOJO_HANDLE_SIGNAL_READABLE, - NotReached())); - EXPECT_FALSE(b_watcher.IsWatching()); -} - -TEST_F(WatcherTest, Cancel) { - ScopedMessagePipeHandle a, b; - CreateMessagePipe(nullptr, &a, &b); - - base::RunLoop run_loop; - Watcher b_watcher; - EXPECT_EQ(MOJO_RESULT_OK, - b_watcher.Start(b.get(), MOJO_HANDLE_SIGNAL_READABLE, - NotReached())); - EXPECT_TRUE(b_watcher.IsWatching()); - b_watcher.Cancel(); - EXPECT_FALSE(b_watcher.IsWatching()); - - // This should never trigger the watcher. - EXPECT_EQ(MOJO_RESULT_OK, WriteMessageRaw(a.get(), "hello", 5, nullptr, 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); - - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, run_loop.QuitClosure()); - run_loop.Run(); -} - -TEST_F(WatcherTest, CancelOnClose) { - ScopedMessagePipeHandle a, b; - CreateMessagePipe(nullptr, &a, &b); - - base::RunLoop run_loop; - Watcher b_watcher; - EXPECT_EQ(MOJO_RESULT_OK, - b_watcher.Start(b.get(), MOJO_HANDLE_SIGNAL_READABLE, - OnReady([&] (MojoResult result) { - EXPECT_EQ(MOJO_RESULT_CANCELLED, result); - run_loop.Quit(); - }))); - EXPECT_TRUE(b_watcher.IsWatching()); - - // This should trigger the watcher above. - b.reset(); - - run_loop.Run(); - - EXPECT_FALSE(b_watcher.IsWatching()); -} - -TEST_F(WatcherTest, CancelOnDestruction) { - ScopedMessagePipeHandle a, b; - CreateMessagePipe(nullptr, &a, &b); - base::RunLoop run_loop; - { - Watcher b_watcher; - EXPECT_EQ(MOJO_RESULT_OK, - b_watcher.Start(b.get(), MOJO_HANDLE_SIGNAL_READABLE, - NotReached())); - EXPECT_TRUE(b_watcher.IsWatching()); - - // |b_watcher| should be cancelled when it goes out of scope. - } - - // This should never trigger the watcher above. - EXPECT_EQ(MOJO_RESULT_OK, WriteMessageRaw(a.get(), "hello", 5, nullptr, 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, run_loop.QuitClosure()); - run_loop.Run(); -} - -TEST_F(WatcherTest, NotifyOnMessageLoopDestruction) { - ScopedMessagePipeHandle a, b; - CreateMessagePipe(nullptr, &a, &b); - - bool notified = false; - Watcher b_watcher; - EXPECT_EQ(MOJO_RESULT_OK, - b_watcher.Start(b.get(), MOJO_HANDLE_SIGNAL_READABLE, - OnReady([&] (MojoResult result) { - EXPECT_EQ(MOJO_RESULT_ABORTED, result); - notified = true; - }))); - EXPECT_TRUE(b_watcher.IsWatching()); - - message_loop_.reset(); - - EXPECT_TRUE(notified); - - EXPECT_TRUE(b_watcher.IsWatching()); - b_watcher.Cancel(); -} - -} // namespace -} // namespace mojo diff --git a/mojo/public/cpp/system/watcher.cc b/mojo/public/cpp/system/watcher.cc deleted file mode 100644 index ad965ff..0000000 --- a/mojo/public/cpp/system/watcher.cc +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright 2016 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/system/watcher.h" - -#include "base/bind.h" -#include "base/location.h" -#include "base/macros.h" -#include "base/message_loop/message_loop.h" -#include "base/thread_task_runner_handle.h" -#include "mojo/public/c/system/functions.h" - -namespace mojo { - -class Watcher::MessageLoopObserver - : public base::MessageLoop::DestructionObserver { - public: - explicit MessageLoopObserver(Watcher* watcher) : watcher_(watcher) { - base::MessageLoop::current()->AddDestructionObserver(this); - } - - ~MessageLoopObserver() override { - StopObservingIfNecessary(); - } - - private: - // base::MessageLoop::DestructionObserver: - void WillDestroyCurrentMessageLoop() override { - StopObservingIfNecessary(); - if (watcher_->IsWatching()) - watcher_->OnHandleReady(MOJO_RESULT_ABORTED); - } - - void StopObservingIfNecessary() { - if (is_observing_) { - is_observing_ = false; - base::MessageLoop::current()->RemoveDestructionObserver(this); - } - } - - bool is_observing_ = true; - Watcher* watcher_; - - DISALLOW_COPY_AND_ASSIGN(MessageLoopObserver); -}; - -Watcher::Watcher() - : task_runner_(base::ThreadTaskRunnerHandle::Get()), - weak_factory_(this) { - weak_self_ = weak_factory_.GetWeakPtr(); -} - -Watcher::~Watcher() { - if(IsWatching()) - Cancel(); -} - -bool Watcher::IsWatching() const { - DCHECK(thread_checker_.CalledOnValidThread()); - return handle_.is_valid(); -} - -MojoResult Watcher::Start(Handle handle, - MojoHandleSignals signals, - const ReadyCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!IsWatching()); - DCHECK(!callback.is_null()); - - message_loop_observer_.reset(new MessageLoopObserver(this)); - callback_ = callback; - handle_ = handle; - MojoResult result = MojoWatch(handle_.value(), signals, - &Watcher::CallOnHandleReady, - reinterpret_cast<uintptr_t>(this)); - if (result != MOJO_RESULT_OK) { - handle_.set_value(kInvalidHandleValue); - callback_.Reset(); - message_loop_observer_.reset(); - DCHECK(result == MOJO_RESULT_FAILED_PRECONDITION || - result == MOJO_RESULT_INVALID_ARGUMENT); - return result; - } - - return MOJO_RESULT_OK; -} - -void Watcher::Cancel() { - DCHECK(thread_checker_.CalledOnValidThread()); - - // The watch may have already been cancelled if the handle was closed. - if (!handle_.is_valid()) - return; - - MojoResult result = - MojoCancelWatch(handle_.value(), reinterpret_cast<uintptr_t>(this)); - message_loop_observer_.reset(); - DCHECK_EQ(result, MOJO_RESULT_OK); - handle_.set_value(kInvalidHandleValue); - callback_.Reset(); -} - -void Watcher::OnHandleReady(MojoResult result) { - DCHECK(thread_checker_.CalledOnValidThread()); - - ReadyCallback callback = callback_; - if (result == MOJO_RESULT_CANCELLED) { - message_loop_observer_.reset(); - handle_.set_value(kInvalidHandleValue); - callback_.Reset(); - } - - // NOTE: It's legal for |callback| to delete |this|. - if (!callback.is_null()) - callback.Run(result); -} - -// static -void Watcher::CallOnHandleReady(uintptr_t context, - MojoResult result, - MojoHandleSignalsState signals_state) { - // NOTE: It is safe to assume the Watcher still exists because this callback - // will never be run after the Watcher's destructor. - // - // TODO: Maybe we should also expose |signals_state| throught he Watcher API. - // Current HandleWatcher users have no need for it, so it's omitted here. - Watcher* watcher = reinterpret_cast<Watcher*>(context); - watcher->task_runner_->PostTask( - FROM_HERE, - base::Bind(&Watcher::OnHandleReady, watcher->weak_self_, result)); -} - -} // namespace mojo diff --git a/mojo/public/cpp/system/watcher.h b/mojo/public/cpp/system/watcher.h deleted file mode 100644 index cd068aa..0000000 --- a/mojo/public/cpp/system/watcher.h +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2016 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_SYSTEM_WATCHER_H_ -#define MOJO_PUBLIC_CPP_SYSTEM_WATCHER_H_ - -#include "base/callback.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" -#include "base/single_thread_task_runner.h" -#include "base/threading/thread_checker.h" -#include "mojo/public/c/system/types.h" -#include "mojo/public/cpp/system/handle.h" - -namespace mojo { - -// A Watcher watches a single Mojo handle for signal state changes. -// -// NOTE: Watchers may only be used on threads which have a running MessageLoop. -class Watcher { - public: - // A callback to be called any time a watched handle changes state in some - // interesting way. The |result| argument indicates one of the following - // conditions depending on its value: - // - // |MOJO_RESULT_OK|: One or more of the signals being watched is satisfied. - // - // |MOJO_RESULT_FAILED_PRECONDITION|: None of the signals being watched can - // ever be satisfied again. - // - // |MOJO_RESULT_CANCELLED|: The handle has been closed and the watch has - // been cancelled implicitly. - // - // |MOJO_RESULT_ABORTED|: Notifications can no longer be delivered for this - // watcher for some unspecified reason, e.g., the watching thread may - // be shutting down soon. Note that it is still necessary to explicitly - // Cancel() the watch in this case. - using ReadyCallback = base::Callback<void(MojoResult result)>; - - // TODO(rockot/yzshen): Support giving Watcher an explicit TaskRunner for - // more fine-grained control over dispatch behavior. - Watcher(); - - // NOTE: This destructor automatically calls |Cancel()| if the Watcher is - // still active. - ~Watcher(); - - // Indicates if the Watcher is currently watching a handle. - bool IsWatching() const; - - // Starts watching |handle|. A Watcher may only watch one handle at a time, - // but it is safe to call this more than once as long as the previous watch - // has been cancelled (i.e. |is_watching()| returns |false|.) - // - // If no signals in |signals| can ever be satisfied for |handle|, this returns - // |MOJO_RESULT_FAILED_PRECONDITION|. - // - // If |handle| is not a valid watchable (message or data pipe) handle, this - // returns |MOJO_RESULT_INVALID_ARGUMENT|. - // - // Otherwise |MOJO_RESULT_OK| is returned and the handle will be watched until - // closure or cancellation. - // - // Once the watch is started, |callback| may be called at any time on the - // current thread until |Cancel()| is called or the handle is closed. - // - // Destroying the Watcher implicitly calls |Cancel()|. - MojoResult Start(Handle handle, - MojoHandleSignals signals, - const ReadyCallback& callback); - - // Cancels the current watch. Once this returns, the callback previously - // passed to |Start()| will never be called again for this Watcher. - void Cancel(); - - private: - class MessageLoopObserver; - friend class MessageLoopObserver; - - void OnHandleReady(MojoResult result); - - static void CallOnHandleReady(uintptr_t context, - MojoResult result, - MojoHandleSignalsState signals_state); - - base::ThreadChecker thread_checker_; - - // The TaskRunner of this Watcher's owning thread. This field is safe to - // access from any thread. - const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - - scoped_ptr<MessageLoopObserver> message_loop_observer_; - - // A persistent weak reference to this Watcher which can be passed to the - // Dispatcher any time this object should be signalled. Safe to access (but - // not to dereference!) from any thread. - base::WeakPtr<Watcher> weak_self_; - - // Fields below must only be accessed on the Watcher's owning thread. - - // The handle currently under watch. Not owned. - Handle handle_; - - // The callback to call when the handle is signaled. - ReadyCallback callback_; - - base::WeakPtrFactory<Watcher> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(Watcher); -}; - -} // namespace mojo - -#endif // MOJO_PUBLIC_CPP_SYSTEM_WATCHER_H_ |