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

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

Issue 2522333002: Provide a Mojo equivalent of ThreadSafeSender. (Closed)
Patch Set: Clean-up Created 4 years 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_BASE_H_ 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_BASE_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/ref_counted.h" 11 #include "base/memory/ref_counted.h"
12 #include "base/task_runner.h" 12 #include "base/task_runner.h"
13 #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" 14 #include "mojo/public/cpp/bindings/associated_interface_ptr.h"
15 #include "mojo/public/cpp/bindings/interface_ptr.h" 15 #include "mojo/public/cpp/bindings/interface_ptr.h"
16 #include "mojo/public/cpp/bindings/message.h" 16 #include "mojo/public/cpp/bindings/message.h"
17 17
18 namespace mojo { 18 namespace mojo {
19 19
20 struct ThreadSafeInterfacePtrDeleter; 20 struct ThreadSafeInterfacePtrDeleter;
21 21
22 // ThreadSafeInterfacePtr and ThreadSafeAssociatedInterfacePtr are versions of 22 // ThreadSafeInterfacePtr and ThreadSafeAssociatedInterfacePtr are versions of
23 // InterfacePtr and AssociatedInterfacePtr that let caller invoke 23 // InterfacePtr and AssociatedInterfacePtr that let callers invoke
24 // interface methods from any threads. Callbacks are received on the thread that 24 // interface methods from any threads. Callbacks are received on the thread that
25 // performed the interface call. 25 // performed the interface call.
26 // 26 //
27 // To create a ThreadSafeInterfacePtr/ThreadSafeAssociatedInterfacePtr, first 27 // To create a ThreadSafeInterfacePtr/ThreadSafeAssociatedInterfacePtr, first
28 // create a regular InterfacePtr/AssociatedInterfacePtr that 28 // create a regular InterfacePtr/AssociatedInterfacePtr that
29 // you then provide to ThreadSafeInterfacePtr/AssociatedInterfacePtr::Create. 29 // you then provide to ThreadSafeInterfacePtr/AssociatedInterfacePtr::Create.
30 // You can then call methods on the 30 // You can then call methods on the
31 // ThreadSafeInterfacePtr/AssociatedInterfacePtr instance from any thread. 31 // ThreadSafeInterfacePtr/AssociatedInterfacePtr instance from any thread.
32 // 32 //
33 // Ex for ThreadSafeInterfacePtr: 33 // Ex for ThreadSafeInterfacePtr:
34 // frob::FrobinatorPtr frobinator; 34 // frob::FrobinatorPtr frobinator;
35 // frob::FrobinatorImpl impl(GetProxy(&frobinator)); 35 // frob::FrobinatorImpl impl(GetProxy(&frobinator));
36 // scoped_refptr<frob::ThreadSafeFrobinatorPtr> thread_safe_frobinator = 36 // scoped_refptr<frob::ThreadSafeFrobinatorPtr> thread_safe_frobinator =
37 // frob::ThreadSafeFrobinatorPtr::Create(std::move(frobinator)); 37 // frob::ThreadSafeFrobinatorPtr::Create(std::move(frobinator));
38 // (*thread_safe_frobinator)->FrobinateToTheMax(); 38 // (*thread_safe_frobinator)->FrobinateToTheMax();
39 //
40 // An alternate way is to create the ThreadSafeInterfacePtr unbound (not
41 // associated with an InterfacePtr) and call Bind() at a later time when the
42 // InterfacePtr becomes available. Note that you shouldn't call any interface
43 // methods on the ThreadSafeInterfacePtr before it is bound.
39 44
40 template <typename Interface, template <typename> class InterfacePtrType> 45 template <typename Interface, template <typename> class InterfacePtrType>
41 class ThreadSafeInterfacePtrBase 46 class ThreadSafeInterfacePtrBase
42 : public MessageReceiverWithResponder, 47 : public MessageReceiverWithResponder,
43 public base::RefCountedThreadSafe< 48 public base::RefCountedThreadSafe<
44 ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>, 49 ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>,
45 ThreadSafeInterfacePtrDeleter> { 50 ThreadSafeInterfacePtrDeleter> {
46 public: 51 public:
47 using ProxyType = typename Interface::Proxy_; 52 using ProxyType = typename Interface::Proxy_;
48 53
49 static scoped_refptr<ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>> 54 static scoped_refptr<ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>>
50 Create(InterfacePtrType<Interface> interface_ptr) { 55 Create(InterfacePtrType<Interface> interface_ptr) {
56 scoped_refptr<ThreadSafeInterfacePtrBase> ptr(
57 new ThreadSafeInterfacePtrBase());
58 return ptr->BindToCurrentThread(std::move(interface_ptr)) ? ptr : nullptr;
59 }
60
61 // Creates a ThreadSafeInterfacePtrBase with no associated InterfacePtr.
62 // Call Bind() with the InterfacePtr once available.
63 static scoped_refptr<ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>>
64 CreateUnbound() {
65 return new ThreadSafeInterfacePtrBase();
66 }
67
68 // Binds a ThreadSafeInterfacePtrBase previously created with CreateUnbound().
69 bool BindToCurrentThread(InterfacePtrType<Interface> interface_ptr) {
yzshen1 2016/11/28 18:05:45 Comment on line 42/62 calls this method "Bind()".
Jay Civelli 2016/11/28 18:46:10 Good point, changed to Bind() and added a comment
70 DCHECK(!interface_ptr_task_runner_);
51 if (!interface_ptr.is_bound()) { 71 if (!interface_ptr.is_bound()) {
52 LOG(ERROR) << "Attempting to create a ThreadSafe[Associated]InterfacePtr " 72 LOG(ERROR) << "Attempting to bind a ThreadSafe[Associated]InterfacePtr "
53 "from an unbound InterfacePtr."; 73 "from an unbound InterfacePtr.";
54 return nullptr; 74 return false;
55 } 75 }
56 return new ThreadSafeInterfacePtrBase(std::move(interface_ptr), 76 interface_ptr_ = std::move(interface_ptr);
57 base::ThreadTaskRunnerHandle::Get()); 77 interface_ptr_task_runner_ = base::ThreadTaskRunnerHandle::Get();
78 return true;
58 } 79 }
59 80
60 ~ThreadSafeInterfacePtrBase() override {} 81 ~ThreadSafeInterfacePtrBase() override {}
61 82
62 Interface* get() { return &proxy_; } 83 Interface* get() { return &proxy_; }
63 Interface* operator->() { return get(); } 84 Interface* operator->() { return get(); }
64 Interface& operator*() { return *get(); } 85 Interface& operator*() { return *get(); }
65 86
66 protected:
67 ThreadSafeInterfacePtrBase(
68 InterfacePtrType<Interface> interface_ptr,
69 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
70 : interface_ptr_task_runner_(task_runner),
71 proxy_(this),
72 interface_ptr_(std::move(interface_ptr)),
73 weak_ptr_factory_(this) {}
74
75 private: 87 private:
76 friend class base::RefCountedThreadSafe< 88 friend class base::RefCountedThreadSafe<
77 ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>>; 89 ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>>;
78 friend struct ThreadSafeInterfacePtrDeleter; 90 friend struct ThreadSafeInterfacePtrDeleter;
79 91
92 ThreadSafeInterfacePtrBase() : proxy_(this), weak_ptr_factory_(this) {}
93
80 void DeleteOnCorrectThread() const { 94 void DeleteOnCorrectThread() const {
81 if (!interface_ptr_task_runner_->BelongsToCurrentThread() && 95 if (interface_ptr_task_runner_ &&
96 !interface_ptr_task_runner_->BelongsToCurrentThread() &&
82 interface_ptr_task_runner_->DeleteSoon(FROM_HERE, this)) { 97 interface_ptr_task_runner_->DeleteSoon(FROM_HERE, this)) {
83 return; 98 return;
84 } 99 }
85 delete this; 100 delete this;
86 } 101 }
87 102
88 // MessageReceiverWithResponder implementation: 103 // MessageReceiverWithResponder implementation:
89 bool Accept(Message* message) override { 104 bool Accept(Message* message) override {
90 interface_ptr_task_runner_->PostTask( 105 interface_ptr_task_runner_->PostTask(
91 FROM_HERE, 106 FROM_HERE,
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 template <typename Interface> 180 template <typename Interface>
166 using ThreadSafeAssociatedInterfacePtr = 181 using ThreadSafeAssociatedInterfacePtr =
167 ThreadSafeInterfacePtrBase<Interface, AssociatedInterfacePtr>; 182 ThreadSafeInterfacePtrBase<Interface, AssociatedInterfacePtr>;
168 183
169 template <typename Interface> 184 template <typename Interface>
170 using ThreadSafeInterfacePtr = 185 using ThreadSafeInterfacePtr =
171 ThreadSafeInterfacePtrBase<Interface, InterfacePtr>; 186 ThreadSafeInterfacePtrBase<Interface, InterfacePtr>;
172 187
173 } // namespace mojo 188 } // namespace mojo
174 189
175 #endif // MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_BASE_H_ 190 #endif // MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698