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

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

Issue 2506383002: Mojo: adding a thread safe associated interface ptr. (Closed)
Patch Set: Resurecting comment Created 4 years, 1 month 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_BASE_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_BASE_H_
7
8 namespace mojo {
9 7
10 #include <memory> 8 #include <memory>
11 9
12 #include "base/callback.h"
13 #include "base/macros.h" 10 #include "base/macros.h"
14 #include "base/memory/ref_counted.h" 11 #include "base/memory/ref_counted.h"
15 #include "base/task_runner.h" 12 #include "base/task_runner.h"
16 #include "base/threading/thread_task_runner_handle.h" 13 #include "base/threading/thread_task_runner_handle.h"
14 #include "mojo/public/cpp/bindings/associated_interface_ptr.h"
17 #include "mojo/public/cpp/bindings/interface_ptr.h" 15 #include "mojo/public/cpp/bindings/interface_ptr.h"
18 #include "mojo/public/cpp/bindings/lib/interface_ptr_state.h"
19 #include "mojo/public/cpp/bindings/message.h" 16 #include "mojo/public/cpp/bindings/message.h"
20 17
18 namespace mojo {
19
21 struct ThreadSafeInterfacePtrDeleter; 20 struct ThreadSafeInterfacePtrDeleter;
22 21
23 // ThreadSafeInterfacePtr is a version of InterfacePtr that lets caller invoke 22 // ThreadSafeInterfacePtr and ThreadSafeAssociatedInterfacePtr are versions of
24 // interface methods from any threads. Callbacks are called on the thread that 23 // InterfacePtr and AssociatedInterfacePtr that let caller invoke
24 // interface methods from any threads. Callbacks are received on the thread that
25 // performed the interface call. 25 // performed the interface call.
26 // To create a ThreadSafeInterfacePtr, create first a regular InterfacePtr that
27 // you then provide to ThreadSafeInterfacePtr::Create.
28 // You can then call methods on the ThreadSafeInterfacePtr from any thread.
29 // 26 //
30 // Ex: 27 // To create a ThreadSafeInterfacePtr/ThreadSafeAssociatedInterfacePtr, first
28 // create a regular InterfacePtr/AssociatedInterfacePtr that
29 // you then provide to ThreadSafeInterfacePtr/AssociatedInterfacePtr::Create.
30 // You can then call methods on the
31 // ThreadSafeInterfacePtr/AssociatedInterfacePtr instance from any thread.
32 //
33 // Ex for ThreadSafeInterfacePtr:
31 // frob::FrobinatorPtr frobinator; 34 // frob::FrobinatorPtr frobinator;
32 // frob::FrobinatorImpl impl(GetProxy(&frobinator)); 35 // frob::FrobinatorImpl impl(GetProxy(&frobinator));
33 // scoped_refptr<frob::ThreadSafeFrobinatorPtr> thread_safe_frobinator = 36 // scoped_refptr<frob::ThreadSafeFrobinatorPtr> thread_safe_frobinator =
34 // frob::ThreadSafeFrobinatorPtr::Create(std::move(frobinator)); 37 // frob::ThreadSafeFrobinatorPtr::Create(std::move(frobinator));
35 // (*thread_safe_frobinator)->FrobinateToTheMax(); 38 // (*thread_safe_frobinator)->FrobinateToTheMax();
36 39
37 template <typename Interface> 40 template <typename Interface, template <typename> class InterfacePtrType>
38 class ThreadSafeInterfacePtr : public MessageReceiverWithResponder, 41 class ThreadSafeInterfacePtrBase
39 public base::RefCountedThreadSafe<ThreadSafeInterfacePtr<Interface>, 42 : public MessageReceiverWithResponder,
40 ThreadSafeInterfacePtrDeleter> { 43 public base::RefCountedThreadSafe<
44 ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>,
45 ThreadSafeInterfacePtrDeleter> {
41 public: 46 public:
42 using ProxyType = typename Interface::Proxy_; 47 using ProxyType = typename Interface::Proxy_;
43 48
44 using AcceptCallback = base::Callback<void(Message)>; 49 static scoped_refptr<ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>>
45 using AcceptWithResponderCallback = 50 Create(InterfacePtrType<Interface> interface_ptr) {
46 base::Callback<void(Message, std::unique_ptr<MessageReceiver>)>; 51 if (!interface_ptr.is_bound()) {
52 LOG(ERROR) << "Attempting to create a ThreadSafeInterfacePtr from an "
yzshen1 2016/11/17 19:21:41 nit: maybe change the comment slightly: ThreadSafe
Jay Civelli 2016/11/17 19:29:20 Done.
53 "unbound InterfacePtr.";
54 return nullptr;
55 }
56 return new ThreadSafeInterfacePtrBase(std::move(interface_ptr),
57 base::ThreadTaskRunnerHandle::Get());
58 }
59
60 ~ThreadSafeInterfacePtrBase() override {}
47 61
48 Interface* get() { return &proxy_; } 62 Interface* get() { return &proxy_; }
49 Interface* operator->() { return get(); } 63 Interface* operator->() { return get(); }
50 Interface& operator*() { return *get(); } 64 Interface& operator*() { return *get(); }
51 65
52 static scoped_refptr<ThreadSafeInterfacePtr<Interface>> Create( 66 protected:
53 InterfacePtr<Interface> interface_ptr) { 67 ThreadSafeInterfacePtrBase(
54 if (!interface_ptr.is_bound()) { 68 InterfacePtrType<Interface> interface_ptr,
55 LOG(ERROR) << "Attempting to create a ThreadSafeInterfacePtr from an "
56 "unbound InterfacePtr.";
57 return nullptr;
58 }
59 return new ThreadSafeInterfacePtr(std::move(interface_ptr),
60 base::ThreadTaskRunnerHandle::Get());
61 }
62
63 private:
64 friend class base::RefCountedThreadSafe<ThreadSafeInterfacePtr<Interface>>;
65 friend struct ThreadSafeInterfacePtrDeleter;
66
67 ThreadSafeInterfacePtr(
68 InterfacePtr<Interface> interface_ptr,
69 scoped_refptr<base::SingleThreadTaskRunner> task_runner) 69 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
70 : interface_ptr_task_runner_(task_runner), 70 : interface_ptr_task_runner_(task_runner),
71 proxy_(this), 71 proxy_(this),
72 interface_ptr_(std::move(interface_ptr)) { 72 interface_ptr_(std::move(interface_ptr)),
73 // Note that it's important we do get the callback after interface_ptr_ has 73 weak_ptr_factory_(this) {}
74 // been set, as they would become invalid if interface_ptr_ is copied. 74
75 accept_callback_ = interface_ptr_.internal_state()-> 75 private:
76 GetThreadSafePtrAcceptCallback(); 76 friend class base::RefCountedThreadSafe<
77 accept_with_responder_callback_ = interface_ptr_.internal_state()-> 77 ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>>;
78 GetThreadSafePtrAcceptWithResponderCallback(); 78 friend struct ThreadSafeInterfacePtrDeleter;
79 }
80 79
81 void DeleteOnCorrectThread() const { 80 void DeleteOnCorrectThread() const {
82 if (!interface_ptr_task_runner_->BelongsToCurrentThread() && 81 if (!interface_ptr_task_runner_->BelongsToCurrentThread() &&
83 interface_ptr_task_runner_->DeleteSoon(FROM_HERE, this)) { 82 interface_ptr_task_runner_->DeleteSoon(FROM_HERE, this)) {
84 return; 83 return;
85 } 84 }
86 delete this; 85 delete this;
87 } 86 }
88 87
89 // MessageReceiverWithResponder implementation: 88 // MessageReceiverWithResponder implementation:
90 bool Accept(Message* message) override { 89 bool Accept(Message* message) override {
91 interface_ptr_task_runner_->PostTask( 90 interface_ptr_task_runner_->PostTask(
92 FROM_HERE, 91 FROM_HERE,
93 base::Bind(accept_callback_, base::Passed(std::move(*message)))); 92 base::Bind(&ThreadSafeInterfacePtrBase::AcceptOnInterfacePtrThread,
93 weak_ptr_factory_.GetWeakPtr(),
94 base::Passed(std::move(*message))));
94 return true; 95 return true;
95 } 96 }
96 97
97 bool AcceptWithResponder(Message* message, 98 bool AcceptWithResponder(Message* message,
98 MessageReceiver* responder) override { 99 MessageReceiver* responder) override {
99 auto forward_responder = base::MakeUnique<ForwardToCallingThread>( 100 auto forward_responder = base::MakeUnique<ForwardToCallingThread>(
100 base::WrapUnique(responder)); 101 base::WrapUnique(responder));
101 interface_ptr_task_runner_->PostTask( 102 interface_ptr_task_runner_->PostTask(
102 FROM_HERE, 103 FROM_HERE, base::Bind(&ThreadSafeInterfacePtrBase::
103 base::Bind(accept_with_responder_callback_, 104 AcceptWithResponderOnInterfacePtrThread,
104 base::Passed(std::move(*message)), 105 weak_ptr_factory_.GetWeakPtr(),
105 base::Passed(std::move(forward_responder)))); 106 base::Passed(std::move(*message)),
107 base::Passed(std::move(forward_responder))));
106 return true; 108 return true;
107 } 109 }
108 110
111 void AcceptOnInterfacePtrThread(Message message) {
112 interface_ptr_.internal_state()->ForwardMessage(std::move(message));
113 }
114 void AcceptWithResponderOnInterfacePtrThread(
115 Message message,
116 std::unique_ptr<MessageReceiver> responder) {
117 interface_ptr_.internal_state()->ForwardMessageWithResponder(
118 std::move(message), std::move(responder));
119 }
120
109 class ForwardToCallingThread : public MessageReceiver { 121 class ForwardToCallingThread : public MessageReceiver {
110 public: 122 public:
111 explicit ForwardToCallingThread(std::unique_ptr<MessageReceiver> responder) 123 explicit ForwardToCallingThread(std::unique_ptr<MessageReceiver> responder)
112 : responder_(std::move(responder)), 124 : responder_(std::move(responder)),
113 caller_task_runner_(base::ThreadTaskRunnerHandle::Get()) { 125 caller_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
114 } 126 }
115 127
116 private: 128 private:
117 bool Accept(Message* message) { 129 bool Accept(Message* message) {
118 // The current instance will be deleted when this method returns, so we 130 // The current instance will be deleted when this method returns, so we
(...skipping 11 matching lines...) Expand all
130 Message message) { 142 Message message) {
131 ignore_result(responder->Accept(&message)); 143 ignore_result(responder->Accept(&message));
132 } 144 }
133 145
134 std::unique_ptr<MessageReceiver> responder_; 146 std::unique_ptr<MessageReceiver> responder_;
135 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; 147 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
136 }; 148 };
137 149
138 scoped_refptr<base::SingleThreadTaskRunner> interface_ptr_task_runner_; 150 scoped_refptr<base::SingleThreadTaskRunner> interface_ptr_task_runner_;
139 ProxyType proxy_; 151 ProxyType proxy_;
140 AcceptCallback accept_callback_; 152 InterfacePtrType<Interface> interface_ptr_;
141 AcceptWithResponderCallback accept_with_responder_callback_; 153 base::WeakPtrFactory<ThreadSafeInterfacePtrBase> weak_ptr_factory_;
142 InterfacePtr<Interface> interface_ptr_;
143 }; 154 };
144 155
145 struct ThreadSafeInterfacePtrDeleter { 156 struct ThreadSafeInterfacePtrDeleter {
146 template <typename Interface> 157 template <typename Interface, template <typename> class InterfacePtrType>
147 static void Destruct(const ThreadSafeInterfacePtr<Interface>* interface_ptr) { 158 static void Destruct(
159 const ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>*
160 interface_ptr) {
148 interface_ptr->DeleteOnCorrectThread(); 161 interface_ptr->DeleteOnCorrectThread();
149 } 162 }
150 }; 163 };
151 164
165 template <typename Interface>
166 using ThreadSafeAssociatedInterfacePtr =
167 ThreadSafeInterfacePtrBase<Interface, AssociatedInterfacePtr>;
168
169 template <typename Interface>
170 using ThreadSafeInterfacePtr =
171 ThreadSafeInterfacePtrBase<Interface, InterfacePtr>;
172
152 } // namespace mojo 173 } // namespace mojo
153 174
154 #endif // MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_H_ 175 #endif // MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_BASE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698