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

Side by Side 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: rebase 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/browser/mojo/stash_backend.h" 5 #include "extensions/browser/mojo/stash_backend.h"
6 6
7 #include "base/bind.h"
8 #include "third_party/mojo/src/mojo/public/cpp/environment/async_waiter.h"
9
7 namespace extensions { 10 namespace extensions {
11 namespace {
8 12
9 // An implementation of StashService that forwards calls to a StashBackend. 13 // An implementation of StashService that forwards calls to a StashBackend.
10 class StashServiceImpl : public mojo::InterfaceImpl<StashService> { 14 class StashServiceImpl : public mojo::InterfaceImpl<StashService> {
11 public: 15 public:
12 explicit StashServiceImpl(base::WeakPtr<StashBackend> backend); 16 explicit StashServiceImpl(base::WeakPtr<StashBackend> backend);
13 ~StashServiceImpl() override; 17 ~StashServiceImpl() override;
14 18
15 // mojo::InterfaceImpl<StashService> overrides. 19 // mojo::InterfaceImpl<StashService> overrides.
16 void AddToStash(mojo::Array<StashedObjectPtr> stash) override; 20 void AddToStash(mojo::Array<StashedObjectPtr> stash) override;
17 void RetrieveStash( 21 void RetrieveStash(
18 const mojo::Callback<void(mojo::Array<StashedObjectPtr> stash)>& callback) 22 const mojo::Callback<void(mojo::Array<StashedObjectPtr> stash)>& callback)
19 override; 23 override;
20 24
21 private: 25 private:
22 base::WeakPtr<StashBackend> backend_; 26 base::WeakPtr<StashBackend> backend_;
23 27
24 DISALLOW_COPY_AND_ASSIGN(StashServiceImpl); 28 DISALLOW_COPY_AND_ASSIGN(StashServiceImpl);
25 }; 29 };
26 30
27 StashBackend::StashBackend() : weak_factory_(this) { 31 StashServiceImpl::StashServiceImpl(base::WeakPtr<StashBackend> backend)
32 : backend_(backend) {
33 }
34
35 StashServiceImpl::~StashServiceImpl() {
36 }
37
38 void StashServiceImpl::AddToStash(
39 mojo::Array<StashedObjectPtr> stashed_objects) {
40 if (!backend_)
41 return;
42 backend_->AddToStash(stashed_objects.Pass());
43 }
44
45 void StashServiceImpl::RetrieveStash(
46 const mojo::Callback<void(mojo::Array<StashedObjectPtr>)>& callback) {
47 if (!backend_) {
48 callback.Run(mojo::Array<StashedObjectPtr>(0));
49 return;
50 }
51 callback.Run(backend_->RetrieveStash());
52 }
53
54 } // namespace
55
56 // A stash entry for a stashed object. This handles notifications if a handle
57 // within the stashed object is readable.
58 class StashBackend::StashEntry {
59 public:
60 // Construct an StashEntry for |stashed_object|. If |on_handle_readable| is
Anand Mistry (off Chromium) 2015/02/05 11:10:33 s/an/a
Sam McNally 2015/02/05 23:35:31 Done.
61 // non-null, it will be invoked when any handle on |stashed_object| is
62 // readable.
63 StashEntry(StashedObjectPtr stashed_object,
64 const base::Closure& on_handle_readable);
65 ~StashEntry();
66
67 // Returns the stashed object.
68 StashedObjectPtr Release();
69
70 // Cancels notifications for handles becoming readable.
71 void CancelHandleNotifications();
72
73 private:
74 // Invoked when a handle within |stashed_object_| is readable.
75 void OnHandleReady(MojoResult result);
76
77 // The waiters that are waiting for handles to be readable.
78 std::vector<linked_ptr<mojo::AsyncWaiter>> waiters_;
79
80 StashedObjectPtr stashed_object_;
81
82 // If non-null, a callback to call when a handle contained within
83 // |stashed_object_| is readable.
84 const base::Closure on_handle_readable_;
85 };
86
87 StashBackend::StashBackend(const base::Closure& on_handle_readable)
88 : on_handle_readable_(on_handle_readable),
89 has_notified_(false),
90 weak_factory_(this) {
28 } 91 }
29 92
30 StashBackend::~StashBackend() { 93 StashBackend::~StashBackend() {
31 } 94 }
32 95
33 void StashBackend::AddToStash(mojo::Array<StashedObjectPtr> stashed_objects) { 96 void StashBackend::AddToStash(mojo::Array<StashedObjectPtr> stashed_objects) {
34 for (size_t i = 0; i < stashed_objects.size(); i++) { 97 for (size_t i = 0; i < stashed_objects.size(); i++) {
35 stashed_objects_.push_back(stashed_objects[i].Pass()); 98 stashed_objects_.push_back(linked_ptr<StashEntry>(new StashEntry(
99 stashed_objects[i].Pass(),
100 has_notified_ ? base::Closure()
101 : base::Bind(&StashBackend::OnHandleReady,
102 weak_factory_.GetWeakPtr()))));
36 } 103 }
37 } 104 }
38 105
39 mojo::Array<StashedObjectPtr> StashBackend::RetrieveStash() { 106 mojo::Array<StashedObjectPtr> StashBackend::RetrieveStash() {
40 if (stashed_objects_.is_null()) 107 has_notified_ = false;
41 stashed_objects_.resize(0); 108 mojo::Array<StashedObjectPtr> result(0);
42 return stashed_objects_.Pass(); 109 for (auto& entry : stashed_objects_) {
110 result.push_back(entry->Release());
111 }
112 stashed_objects_.clear();
113 return result.Pass();
43 } 114 }
44 115
45 void StashBackend::BindToRequest(mojo::InterfaceRequest<StashService> request) { 116 void StashBackend::BindToRequest(mojo::InterfaceRequest<StashService> request) {
46 mojo::BindToRequest(new StashServiceImpl(weak_factory_.GetWeakPtr()), 117 mojo::BindToRequest(new StashServiceImpl(weak_factory_.GetWeakPtr()),
47 &request); 118 &request);
48 } 119 }
49 120
50 StashServiceImpl::StashServiceImpl(base::WeakPtr<StashBackend> backend) 121 void StashBackend::OnHandleReady() {
51 : backend_(backend) { 122 DCHECK(!has_notified_);
123 has_notified_ = true;
124 for (auto& entry : stashed_objects_) {
125 entry->CancelHandleNotifications();
126 }
127 if (!on_handle_readable_.is_null())
128 on_handle_readable_.Run();
52 } 129 }
53 130
54 StashServiceImpl::~StashServiceImpl() { 131 StashBackend::StashEntry::StashEntry(StashedObjectPtr stashed_object,
132 const base::Closure& on_handle_readable)
133 : stashed_object_(stashed_object.Pass()),
134 on_handle_readable_(on_handle_readable) {
135 if (on_handle_readable_.is_null() || !stashed_object_->monitor_handles)
136 return;
137
138 for (size_t i = 0; i < stashed_object_->stashed_handles.size(); i++) {
139 waiters_.push_back(linked_ptr<mojo::AsyncWaiter>(new mojo::AsyncWaiter(
140 stashed_object_->stashed_handles[i].get(), MOJO_HANDLE_SIGNAL_READABLE,
141 base::Bind(&StashBackend::StashEntry::OnHandleReady,
142 base::Unretained(this)))));
143 }
55 } 144 }
56 145
57 void StashServiceImpl::AddToStash( 146 StashBackend::StashEntry::~StashEntry() {
58 mojo::Array<StashedObjectPtr> stashed_objects) {
59 if (!backend_)
60 return;
61 backend_->AddToStash(stashed_objects.Pass());
62 } 147 }
63 148
64 void StashServiceImpl::RetrieveStash( 149 StashedObjectPtr StashBackend::StashEntry::Release() {
65 const mojo::Callback<void(mojo::Array<StashedObjectPtr>)>& callback) { 150 waiters_.clear();
66 if (!backend_) { 151 return stashed_object_.Pass();
67 callback.Run(mojo::Array<StashedObjectPtr>(0)); 152 }
153
154 void StashBackend::StashEntry::CancelHandleNotifications() {
155 waiters_.clear();
156 }
157
158 void StashBackend::StashEntry::OnHandleReady(MojoResult result) {
159 if (result != MOJO_RESULT_OK)
68 return; 160 return;
69 } 161 on_handle_readable_.Run();
70 callback.Run(backend_->RetrieveStash());
71 } 162 }
72 163
73 } // namespace extensions 164 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698