Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(123)

Unified Diff: extensions/browser/mojo/stash_backend.cc

Issue 648853007: Add handle waiting to StashBackend. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « extensions/browser/mojo/stash_backend.h ('k') | extensions/browser/mojo/stash_backend_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: extensions/browser/mojo/stash_backend.cc
diff --git a/extensions/browser/mojo/stash_backend.cc b/extensions/browser/mojo/stash_backend.cc
index da4842d3340035a88ce8c840ebb327c7705c2eb1..8fa2fbd850b97cb20aac473f8b2aac77cf5e7ab5 100644
--- a/extensions/browser/mojo/stash_backend.cc
+++ b/extensions/browser/mojo/stash_backend.cc
@@ -4,7 +4,11 @@
#include "extensions/browser/mojo/stash_backend.h"
+#include "base/bind.h"
+#include "third_party/mojo/src/mojo/public/cpp/environment/async_waiter.h"
+
namespace extensions {
+namespace {
// An implementation of StashService that forwards calls to a StashBackend.
class StashServiceImpl : public mojo::InterfaceImpl<StashService> {
Ken Rockot(use gerrit already) 2015/02/06 04:21:27 Maybe nix the InterfaceImpl base and just implemen
Sam McNally 2015/02/06 05:48:22 Done.
@@ -24,7 +28,66 @@ class StashServiceImpl : public mojo::InterfaceImpl<StashService> {
DISALLOW_COPY_AND_ASSIGN(StashServiceImpl);
};
-StashBackend::StashBackend() : weak_factory_(this) {
+StashServiceImpl::StashServiceImpl(base::WeakPtr<StashBackend> backend)
+ : backend_(backend) {
+}
+
+StashServiceImpl::~StashServiceImpl() {
+}
+
+void StashServiceImpl::AddToStash(
+ mojo::Array<StashedObjectPtr> stashed_objects) {
+ if (!backend_)
+ return;
+ backend_->AddToStash(stashed_objects.Pass());
+}
+
+void StashServiceImpl::RetrieveStash(
+ const mojo::Callback<void(mojo::Array<StashedObjectPtr>)>& callback) {
+ if (!backend_) {
+ callback.Run(mojo::Array<StashedObjectPtr>(0));
+ return;
+ }
+ callback.Run(backend_->RetrieveStash());
+}
+
+} // namespace
+
+// A stash entry for a stashed object. This handles notifications if a handle
+// within the stashed object is readable.
+class StashBackend::StashEntry {
+ public:
+ // Construct a StashEntry for |stashed_object|. If |on_handle_readable| is
+ // non-null, it will be invoked when any handle on |stashed_object| is
+ // readable.
+ StashEntry(StashedObjectPtr stashed_object,
+ const base::Closure& on_handle_readable);
+ ~StashEntry();
+
+ // Returns the stashed object.
+ StashedObjectPtr Release();
+
+ // Cancels notifications for handles becoming readable.
+ void CancelHandleNotifications();
+
+ private:
+ // Invoked when a handle within |stashed_object_| is readable.
+ void OnHandleReady(MojoResult result);
+
+ // The waiters that are waiting for handles to be readable.
+ std::vector<linked_ptr<mojo::AsyncWaiter>> waiters_;
Ken Rockot(use gerrit already) 2015/02/06 04:21:27 Maybe use a ScopedVector for the waiters instead?
Sam McNally 2015/02/06 05:48:22 Done.
+
+ StashedObjectPtr stashed_object_;
+
+ // If non-null, a callback to call when a handle contained within
+ // |stashed_object_| is readable.
+ const base::Closure on_handle_readable_;
+};
+
+StashBackend::StashBackend(const base::Closure& on_handle_readable)
+ : on_handle_readable_(on_handle_readable),
+ has_notified_(false),
+ weak_factory_(this) {
}
StashBackend::~StashBackend() {
@@ -32,14 +95,22 @@ StashBackend::~StashBackend() {
void StashBackend::AddToStash(mojo::Array<StashedObjectPtr> stashed_objects) {
for (size_t i = 0; i < stashed_objects.size(); i++) {
- stashed_objects_.push_back(stashed_objects[i].Pass());
+ stashed_objects_.push_back(linked_ptr<StashEntry>(new StashEntry(
Ken Rockot(use gerrit already) 2015/02/06 04:21:27 Seems like stashed_objects_ could also be a Scoped
Sam McNally 2015/02/06 05:48:22 Done.
+ stashed_objects[i].Pass(),
+ has_notified_ ? base::Closure()
+ : base::Bind(&StashBackend::OnHandleReady,
+ weak_factory_.GetWeakPtr()))));
}
}
mojo::Array<StashedObjectPtr> StashBackend::RetrieveStash() {
- if (stashed_objects_.is_null())
- stashed_objects_.resize(0);
- return stashed_objects_.Pass();
+ has_notified_ = false;
+ mojo::Array<StashedObjectPtr> result(0);
+ for (auto& entry : stashed_objects_) {
+ result.push_back(entry->Release());
+ }
+ stashed_objects_.clear();
+ return result.Pass();
}
void StashBackend::BindToRequest(mojo::InterfaceRequest<StashService> request) {
@@ -47,27 +118,47 @@ void StashBackend::BindToRequest(mojo::InterfaceRequest<StashService> request) {
&request);
}
-StashServiceImpl::StashServiceImpl(base::WeakPtr<StashBackend> backend)
- : backend_(backend) {
+void StashBackend::OnHandleReady() {
+ DCHECK(!has_notified_);
+ has_notified_ = true;
+ for (auto& entry : stashed_objects_) {
+ entry->CancelHandleNotifications();
+ }
+ if (!on_handle_readable_.is_null())
+ on_handle_readable_.Run();
}
-StashServiceImpl::~StashServiceImpl() {
+StashBackend::StashEntry::StashEntry(StashedObjectPtr stashed_object,
+ const base::Closure& on_handle_readable)
+ : stashed_object_(stashed_object.Pass()),
+ on_handle_readable_(on_handle_readable) {
+ if (on_handle_readable_.is_null() || !stashed_object_->monitor_handles)
+ return;
+
+ for (size_t i = 0; i < stashed_object_->stashed_handles.size(); i++) {
+ waiters_.push_back(linked_ptr<mojo::AsyncWaiter>(new mojo::AsyncWaiter(
+ stashed_object_->stashed_handles[i].get(), MOJO_HANDLE_SIGNAL_READABLE,
+ base::Bind(&StashBackend::StashEntry::OnHandleReady,
+ base::Unretained(this)))));
+ }
}
-void StashServiceImpl::AddToStash(
- mojo::Array<StashedObjectPtr> stashed_objects) {
- if (!backend_)
- return;
- backend_->AddToStash(stashed_objects.Pass());
+StashBackend::StashEntry::~StashEntry() {
}
-void StashServiceImpl::RetrieveStash(
- const mojo::Callback<void(mojo::Array<StashedObjectPtr>)>& callback) {
- if (!backend_) {
- callback.Run(mojo::Array<StashedObjectPtr>(0));
+StashedObjectPtr StashBackend::StashEntry::Release() {
+ waiters_.clear();
+ return stashed_object_.Pass();
+}
+
+void StashBackend::StashEntry::CancelHandleNotifications() {
+ waiters_.clear();
+}
+
+void StashBackend::StashEntry::OnHandleReady(MojoResult result) {
+ if (result != MOJO_RESULT_OK)
return;
- }
- callback.Run(backend_->RetrieveStash());
+ on_handle_readable_.Run();
}
} // namespace extensions
« no previous file with comments | « extensions/browser/mojo/stash_backend.h ('k') | extensions/browser/mojo/stash_backend_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698