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

Side by Side Diff: mojo/public/cpp/bindings/thread_safe_interface_ptr.h

Issue 2608163003: Change single-interface mojo bindings to use SequencedTaskRunner. (Closed)
Patch Set: Created 3 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 #ifndef MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_H_ 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_H_
7 7
8 #include <memory> 8 #include <memory>
9 9
10 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
12 #include "base/memory/ref_counted.h" 12 #include "base/memory/ref_counted.h"
13 #include "base/task_runner.h" 13 #include "base/task_runner.h"
14 #include "base/threading/thread_task_runner_handle.h" 14 #include "base/threading/sequenced_task_runner_handle.h"
15 #include "mojo/public/cpp/bindings/associated_interface_ptr.h" 15 #include "mojo/public/cpp/bindings/associated_interface_ptr.h"
16 #include "mojo/public/cpp/bindings/interface_ptr.h" 16 #include "mojo/public/cpp/bindings/interface_ptr.h"
17 #include "mojo/public/cpp/bindings/message.h" 17 #include "mojo/public/cpp/bindings/message.h"
18 18
19 namespace mojo { 19 namespace mojo {
20 20
21 struct ThreadSafeInterfacePtrDeleter; 21 struct ThreadSafeInterfacePtrDeleter;
22 22
23 // ThreadSafeInterfacePtr and ThreadSafeAssociatedInterfacePtr are versions of 23 // ThreadSafeInterfacePtr and ThreadSafeAssociatedInterfacePtr are versions of
24 // InterfacePtr and AssociatedInterfacePtr that let callers invoke 24 // InterfacePtr and AssociatedInterfacePtr that let callers invoke
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 } 60 }
61 61
62 // Creates a ThreadSafeInterfacePtrBase with no associated InterfacePtr. 62 // Creates a ThreadSafeInterfacePtrBase with no associated InterfacePtr.
63 // Call Bind() with the InterfacePtr once available, which must be called on 63 // Call Bind() with the InterfacePtr once available, which must be called on
64 // the |bind_task_runner|. 64 // the |bind_task_runner|.
65 // Providing the TaskRunner here allows you to post a task to 65 // Providing the TaskRunner here allows you to post a task to
66 // |bind_task_runner| to do the bind and then immediately start calling 66 // |bind_task_runner| to do the bind and then immediately start calling
67 // methods on the returned interface. 67 // methods on the returned interface.
68 static scoped_refptr<ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>> 68 static scoped_refptr<ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>>
69 CreateUnbound( 69 CreateUnbound(
70 const scoped_refptr<base::SingleThreadTaskRunner>& bind_task_runner) { 70 const scoped_refptr<base::SequencedTaskRunner>& bind_task_runner) {
71 scoped_refptr<ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>> ptr = 71 scoped_refptr<ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>> ptr =
72 new ThreadSafeInterfacePtrBase(); 72 new ThreadSafeInterfacePtrBase();
73 ptr->interface_ptr_task_runner_ = bind_task_runner; 73 ptr->interface_ptr_task_runner_ = bind_task_runner;
74 return ptr; 74 return ptr;
75 } 75 }
76 76
77 // Binds a ThreadSafeInterfacePtrBase previously created with CreateUnbound(). 77 // Binds a ThreadSafeInterfacePtrBase previously created with CreateUnbound().
78 // This must be called on the thread that |interface_ptr| should be used. 78 // This must be called on the thread that |interface_ptr| should be used.
79 // If created with CreateUnbound() that thread should be the same as the one 79 // If created with CreateUnbound() that thread should be the same as the one
80 // provided at creation time. 80 // provided at creation time.
81 bool Bind(InterfacePtrType<Interface> interface_ptr) { 81 bool Bind(InterfacePtrType<Interface> interface_ptr) {
82 DCHECK(!interface_ptr_task_runner_ || 82 DCHECK(!interface_ptr_task_runner_ ||
83 interface_ptr_task_runner_ == base::ThreadTaskRunnerHandle::Get()); 83 interface_ptr_task_runner_ ==
84 base::SequencedTaskRunnerHandle::Get());
84 if (!interface_ptr.is_bound()) { 85 if (!interface_ptr.is_bound()) {
85 LOG(ERROR) << "Attempting to bind a ThreadSafe[Associated]InterfacePtr " 86 LOG(ERROR) << "Attempting to bind a ThreadSafe[Associated]InterfacePtr "
86 "from an unbound InterfacePtr."; 87 "from an unbound InterfacePtr.";
87 return false; 88 return false;
88 } 89 }
89 interface_ptr_ = std::move(interface_ptr); 90 interface_ptr_ = std::move(interface_ptr);
90 interface_ptr_task_runner_ = base::ThreadTaskRunnerHandle::Get(); 91 interface_ptr_task_runner_ = base::SequencedTaskRunnerHandle::Get();
91 return true; 92 return true;
92 } 93 }
93 94
94 ~ThreadSafeInterfacePtrBase() override {} 95 ~ThreadSafeInterfacePtrBase() override {}
95 96
96 Interface* get() { return &proxy_; } 97 Interface* get() { return &proxy_; }
97 Interface* operator->() { return get(); } 98 Interface* operator->() { return get(); }
98 Interface& operator*() { return *get(); } 99 Interface& operator*() { return *get(); }
99 100
100 private: 101 private:
101 friend class base::RefCountedThreadSafe< 102 friend class base::RefCountedThreadSafe<
102 ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>>; 103 ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>>;
103 friend struct ThreadSafeInterfacePtrDeleter; 104 friend struct ThreadSafeInterfacePtrDeleter;
104 105
105 ThreadSafeInterfacePtrBase() : proxy_(this), weak_ptr_factory_(this) {} 106 ThreadSafeInterfacePtrBase() : proxy_(this), weak_ptr_factory_(this) {}
106 107
107 void DeleteOnCorrectThread() const { 108 void DeleteOnCorrectThread() const {
108 if (interface_ptr_task_runner_ && 109 if (interface_ptr_task_runner_ &&
109 !interface_ptr_task_runner_->BelongsToCurrentThread() && 110 !interface_ptr_task_runner_->RunsTasksOnCurrentThread() &&
110 interface_ptr_task_runner_->DeleteSoon(FROM_HERE, this)) { 111 interface_ptr_task_runner_->DeleteSoon(FROM_HERE, this)) {
111 return; 112 return;
112 } 113 }
113 delete this; 114 delete this;
114 } 115 }
115 116
116 // MessageReceiverWithResponder implementation: 117 // MessageReceiverWithResponder implementation:
117 bool Accept(Message* message) override { 118 bool Accept(Message* message) override {
118 interface_ptr_task_runner_->PostTask( 119 interface_ptr_task_runner_->PostTask(
119 FROM_HERE, 120 FROM_HERE,
(...skipping 23 matching lines...) Expand all
143 Message message, 144 Message message,
144 std::unique_ptr<MessageReceiver> responder) { 145 std::unique_ptr<MessageReceiver> responder) {
145 interface_ptr_.internal_state()->ForwardMessageWithResponder( 146 interface_ptr_.internal_state()->ForwardMessageWithResponder(
146 std::move(message), std::move(responder)); 147 std::move(message), std::move(responder));
147 } 148 }
148 149
149 class ForwardToCallingThread : public MessageReceiver { 150 class ForwardToCallingThread : public MessageReceiver {
150 public: 151 public:
151 explicit ForwardToCallingThread(std::unique_ptr<MessageReceiver> responder) 152 explicit ForwardToCallingThread(std::unique_ptr<MessageReceiver> responder)
152 : responder_(std::move(responder)), 153 : responder_(std::move(responder)),
153 caller_task_runner_(base::ThreadTaskRunnerHandle::Get()) { 154 caller_task_runner_(base::SequencedTaskRunnerHandle::Get()) {}
154 }
155 155
156 private: 156 private:
157 bool Accept(Message* message) { 157 bool Accept(Message* message) {
158 // The current instance will be deleted when this method returns, so we 158 // The current instance will be deleted when this method returns, so we
159 // have to relinquish the responder's ownership so it does not get 159 // have to relinquish the responder's ownership so it does not get
160 // deleted. 160 // deleted.
161 caller_task_runner_->PostTask(FROM_HERE, 161 caller_task_runner_->PostTask(FROM_HERE,
162 base::Bind(&ForwardToCallingThread::CallAcceptAndDeleteResponder, 162 base::Bind(&ForwardToCallingThread::CallAcceptAndDeleteResponder,
163 base::Passed(std::move(responder_)), 163 base::Passed(std::move(responder_)),
164 base::Passed(std::move(*message)))); 164 base::Passed(std::move(*message))));
165 return true; 165 return true;
166 } 166 }
167 167
168 static void CallAcceptAndDeleteResponder( 168 static void CallAcceptAndDeleteResponder(
169 std::unique_ptr<MessageReceiver> responder, 169 std::unique_ptr<MessageReceiver> responder,
170 Message message) { 170 Message message) {
171 ignore_result(responder->Accept(&message)); 171 ignore_result(responder->Accept(&message));
172 } 172 }
173 173
174 std::unique_ptr<MessageReceiver> responder_; 174 std::unique_ptr<MessageReceiver> responder_;
175 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; 175 scoped_refptr<base::SequencedTaskRunner> caller_task_runner_;
176 }; 176 };
177 177
178 scoped_refptr<base::SingleThreadTaskRunner> interface_ptr_task_runner_; 178 scoped_refptr<base::SequencedTaskRunner> interface_ptr_task_runner_;
179 ProxyType proxy_; 179 ProxyType proxy_;
180 InterfacePtrType<Interface> interface_ptr_; 180 InterfacePtrType<Interface> interface_ptr_;
181 base::WeakPtrFactory<ThreadSafeInterfacePtrBase> weak_ptr_factory_; 181 base::WeakPtrFactory<ThreadSafeInterfacePtrBase> weak_ptr_factory_;
182 }; 182 };
183 183
184 struct ThreadSafeInterfacePtrDeleter { 184 struct ThreadSafeInterfacePtrDeleter {
185 template <typename Interface, template <typename> class InterfacePtrType> 185 template <typename Interface, template <typename> class InterfacePtrType>
186 static void Destruct( 186 static void Destruct(
187 const ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>* 187 const ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>*
188 interface_ptr) { 188 interface_ptr) {
189 interface_ptr->DeleteOnCorrectThread(); 189 interface_ptr->DeleteOnCorrectThread();
190 } 190 }
191 }; 191 };
192 192
193 template <typename Interface> 193 template <typename Interface>
194 using ThreadSafeAssociatedInterfacePtr = 194 using ThreadSafeAssociatedInterfacePtr =
195 ThreadSafeInterfacePtrBase<Interface, AssociatedInterfacePtr>; 195 ThreadSafeInterfacePtrBase<Interface, AssociatedInterfacePtr>;
196 196
197 template <typename Interface> 197 template <typename Interface>
198 using ThreadSafeInterfacePtr = 198 using ThreadSafeInterfacePtr =
199 ThreadSafeInterfacePtrBase<Interface, InterfacePtr>; 199 ThreadSafeInterfacePtrBase<Interface, InterfacePtr>;
200 200
201 } // namespace mojo 201 } // namespace mojo
202 202
203 #endif // MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_H_ 203 #endif // MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_H_
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/tests/thread_per_task_sequenced_task_runner.cc ('k') | mojo/public/cpp/system/watcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698