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

Side by Side Diff: mojo/public/cpp/bindings/lib/thread_safe_interface_ptr_base.h

Issue 2506383002: Mojo: adding a thread safe associated interface ptr. (Closed)
Patch Set: Fixed BUILD.gn 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_LIB_THREAD_SAFE_INTERFACE_PTR_BASE_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_THREAD_SAFE_INTERFACE_PTR_BASE_H_
7 7
8 namespace mojo { 8 namespace mojo {
9 9
10 #include <memory> 10 #include <memory>
11 11
12 #include "base/callback.h"
13 #include "base/macros.h" 12 #include "base/macros.h"
14 #include "base/memory/ref_counted.h" 13 #include "base/memory/ref_counted.h"
15 #include "base/task_runner.h" 14 #include "base/task_runner.h"
16 #include "base/threading/thread_task_runner_handle.h" 15 #include "base/threading/thread_task_runner_handle.h"
17 #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
21 struct ThreadSafeInterfacePtrDeleter; 18 struct ThreadSafeInterfacePtrDeleter;
22 19
23 // ThreadSafeInterfacePtr is a version of InterfacePtr that lets caller invoke 20 // Base class for thread safe interface pointers such as ThreadSafeInterfacePtr
24 // interface methods from any threads. Callbacks are called on the thread that 21 // and ThreadSafeAssociatedInterfacePtr.
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 //
30 // Ex:
31 // frob::FrobinatorPtr frobinator;
32 // frob::FrobinatorImpl impl(GetProxy(&frobinator));
33 // scoped_refptr<frob::ThreadSafeFrobinatorPtr> thread_safe_frobinator =
34 // frob::ThreadSafeFrobinatorPtr::Create(std::move(frobinator));
35 // (*thread_safe_frobinator)->FrobinateToTheMax();
36
37 template <typename Interface> 22 template <typename Interface>
38 class ThreadSafeInterfacePtr : public MessageReceiverWithResponder, 23 class ThreadSafeInterfacePtrBase : public MessageReceiverWithResponder,
39 public base::RefCountedThreadSafe<ThreadSafeInterfacePtr<Interface>, 24 public base::RefCountedThreadSafe<ThreadSafeInterfacePtrBase<Interface>,
40 ThreadSafeInterfacePtrDeleter> { 25 ThreadSafeInterfacePtrDeleter> {
41 public: 26 public:
42 using ProxyType = typename Interface::Proxy_; 27 using ProxyType = typename Interface::Proxy_;
43 28
44 using AcceptCallback = base::Callback<void(Message)>; 29 ~ThreadSafeInterfacePtrBase() override {}
45 using AcceptWithResponderCallback =
46 base::Callback<void(Message, std::unique_ptr<MessageReceiver>)>;
47 30
48 Interface* get() { return &proxy_; } 31 Interface* get() { return &proxy_; }
49 Interface* operator->() { return get(); } 32 Interface* operator->() { return get(); }
50 Interface& operator*() { return *get(); } 33 Interface& operator*() { return *get(); }
51 34
52 static scoped_refptr<ThreadSafeInterfacePtr<Interface>> Create( 35 protected:
53 InterfacePtr<Interface> interface_ptr) { 36 explicit ThreadSafeInterfacePtrBase(
54 if (!interface_ptr.is_bound()) {
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) 37 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
70 : interface_ptr_task_runner_(task_runner), 38 : interface_ptr_task_runner_(task_runner),
71 proxy_(this), 39 proxy_(this),
72 interface_ptr_(std::move(interface_ptr)) { 40 weak_ptr_factory_(this) {
73 // Note that it's important we do get the callback after interface_ptr_ has
74 // been set, as they would become invalid if interface_ptr_ is copied.
75 accept_callback_ = interface_ptr_.internal_state()->
76 GetThreadSafePtrAcceptCallback();
77 accept_with_responder_callback_ = interface_ptr_.internal_state()->
78 GetThreadSafePtrAcceptWithResponderCallback();
79 } 41 }
80 42
43 virtual void AcceptOnInterfacePtrThread(Message message) = 0;
44 virtual void AcceptWithResponderOnInterfacePtrThread(
45 Message message, std::unique_ptr<MessageReceiver> responder) = 0;
46
47 private:
48 friend class base::RefCountedThreadSafe<
49 ThreadSafeInterfacePtrBase<Interface>>;
50 friend struct ThreadSafeInterfacePtrDeleter;
51
81 void DeleteOnCorrectThread() const { 52 void DeleteOnCorrectThread() const {
82 if (!interface_ptr_task_runner_->BelongsToCurrentThread() && 53 if (!interface_ptr_task_runner_->BelongsToCurrentThread() &&
83 interface_ptr_task_runner_->DeleteSoon(FROM_HERE, this)) { 54 interface_ptr_task_runner_->DeleteSoon(FROM_HERE, this)) {
84 return; 55 return;
85 } 56 }
86 delete this; 57 delete this;
87 } 58 }
88 59
89 // MessageReceiverWithResponder implementation: 60 // MessageReceiverWithResponder implementation:
90 bool Accept(Message* message) override { 61 bool Accept(Message* message) override {
91 interface_ptr_task_runner_->PostTask( 62 interface_ptr_task_runner_->PostTask(
92 FROM_HERE, 63 FROM_HERE,
93 base::Bind(accept_callback_, base::Passed(std::move(*message)))); 64 base::Bind(&ThreadSafeInterfacePtrBase::AcceptOnInterfacePtrThread,
65 weak_ptr_factory_.GetWeakPtr(),
66 base::Passed(std::move(*message))));
94 return true; 67 return true;
95 } 68 }
96 69
97 bool AcceptWithResponder(Message* message, 70 bool AcceptWithResponder(Message* message,
98 MessageReceiver* responder) override { 71 MessageReceiver* responder) override {
99 auto forward_responder = base::MakeUnique<ForwardToCallingThread>( 72 auto forward_responder = base::MakeUnique<ForwardToCallingThread>(
100 base::WrapUnique(responder)); 73 base::WrapUnique(responder));
101 interface_ptr_task_runner_->PostTask( 74 interface_ptr_task_runner_->PostTask(
102 FROM_HERE, 75 FROM_HERE,
103 base::Bind(accept_with_responder_callback_, 76 base::Bind(&ThreadSafeInterfacePtrBase::
77 AcceptWithResponderOnInterfacePtrThread,
78 weak_ptr_factory_.GetWeakPtr(),
104 base::Passed(std::move(*message)), 79 base::Passed(std::move(*message)),
105 base::Passed(std::move(forward_responder)))); 80 base::Passed(std::move(forward_responder))));
106 return true; 81 return true;
107 } 82 }
108 83
109 class ForwardToCallingThread : public MessageReceiver { 84 class ForwardToCallingThread : public MessageReceiver {
110 public: 85 public:
111 explicit ForwardToCallingThread(std::unique_ptr<MessageReceiver> responder) 86 explicit ForwardToCallingThread(std::unique_ptr<MessageReceiver> responder)
112 : responder_(std::move(responder)), 87 : responder_(std::move(responder)),
113 caller_task_runner_(base::ThreadTaskRunnerHandle::Get()) { 88 caller_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
(...skipping 16 matching lines...) Expand all
130 Message message) { 105 Message message) {
131 ignore_result(responder->Accept(&message)); 106 ignore_result(responder->Accept(&message));
132 } 107 }
133 108
134 std::unique_ptr<MessageReceiver> responder_; 109 std::unique_ptr<MessageReceiver> responder_;
135 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; 110 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
136 }; 111 };
137 112
138 scoped_refptr<base::SingleThreadTaskRunner> interface_ptr_task_runner_; 113 scoped_refptr<base::SingleThreadTaskRunner> interface_ptr_task_runner_;
139 ProxyType proxy_; 114 ProxyType proxy_;
140 AcceptCallback accept_callback_; 115 base::WeakPtrFactory<ThreadSafeInterfacePtrBase> weak_ptr_factory_;
141 AcceptWithResponderCallback accept_with_responder_callback_;
142 InterfacePtr<Interface> interface_ptr_;
143 }; 116 };
144 117
145 struct ThreadSafeInterfacePtrDeleter { 118 struct ThreadSafeInterfacePtrDeleter {
146 template <typename Interface> 119 template <typename Interface>
147 static void Destruct(const ThreadSafeInterfacePtr<Interface>* interface_ptr) { 120 static void Destruct(
121 const ThreadSafeInterfacePtrBase<Interface>* interface_ptr) {
148 interface_ptr->DeleteOnCorrectThread(); 122 interface_ptr->DeleteOnCorrectThread();
149 } 123 }
150 }; 124 };
151 125
152 } // namespace mojo 126 } // namespace mojo
153 127
154 #endif // MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_H_ 128 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_THREAD_SAFE_INTERFACE_PTR_BASE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698