OLD | NEW |
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" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 // methods on the ThreadSafeInterfacePtr before it is bound. | 44 // methods on the ThreadSafeInterfacePtr before it is bound. |
45 | 45 |
46 template <typename Interface, template <typename> class InterfacePtrType> | 46 template <typename Interface, template <typename> class InterfacePtrType> |
47 class ThreadSafeInterfacePtrBase | 47 class ThreadSafeInterfacePtrBase |
48 : public MessageReceiverWithResponder, | 48 : public MessageReceiverWithResponder, |
49 public base::RefCountedThreadSafe< | 49 public base::RefCountedThreadSafe< |
50 ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>, | 50 ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>, |
51 ThreadSafeInterfacePtrDeleter> { | 51 ThreadSafeInterfacePtrDeleter> { |
52 public: | 52 public: |
53 using ProxyType = typename Interface::Proxy_; | 53 using ProxyType = typename Interface::Proxy_; |
| 54 using PtrInfoType = typename InterfacePtrType<Interface>::PtrInfoType; |
54 | 55 |
| 56 // Creates a ThreadSafeInterfacePtrBase wrapping an underlying non-thread-safe |
| 57 // InterfacePtrType which is bound to the calling thread. All messages sent |
| 58 // via this thread-safe proxy will internally be sent by first posting to this |
| 59 // (the calling) thread's TaskRunner. |
55 static scoped_refptr<ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>> | 60 static scoped_refptr<ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>> |
56 Create(InterfacePtrType<Interface> interface_ptr) { | 61 Create(InterfacePtrType<Interface> interface_ptr) { |
57 scoped_refptr<ThreadSafeInterfacePtrBase> ptr( | 62 scoped_refptr<ThreadSafeInterfacePtrBase> ptr( |
58 new ThreadSafeInterfacePtrBase()); | 63 new ThreadSafeInterfacePtrBase()); |
59 return ptr->Bind(std::move(interface_ptr)) ? ptr : nullptr; | 64 ptr->interface_ptr_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
| 65 return ptr->Bind(interface_ptr.PassInterface()) ? ptr : nullptr; |
60 } | 66 } |
61 | 67 |
62 // Creates a ThreadSafeInterfacePtrBase with no associated InterfacePtr. | 68 // Creates a ThreadSafeInterfacePtrBase which binds the underlying |
63 // Call Bind() with the InterfacePtr once available, which must be called on | 69 // non-thread-safe InterfacePtrType on the specified TaskRunner. All messages |
64 // the |bind_task_runner|. | 70 // sent via this thread-safe proxy will internally be sent by first posting to |
65 // Providing the TaskRunner here allows you to post a task to | 71 // that TaskRunner. |
66 // |bind_task_runner| to do the bind and then immediately start calling | |
67 // methods on the returned interface. | |
68 static scoped_refptr<ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>> | 72 static scoped_refptr<ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>> |
69 CreateUnbound( | 73 Create(PtrInfoType ptr_info, |
70 const scoped_refptr<base::SingleThreadTaskRunner>& bind_task_runner) { | 74 const scoped_refptr<base::SingleThreadTaskRunner>& bind_task_runner) { |
71 scoped_refptr<ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>> ptr = | 75 scoped_refptr<ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>> ptr = |
72 new ThreadSafeInterfacePtrBase(); | 76 new ThreadSafeInterfacePtrBase(); |
73 ptr->interface_ptr_task_runner_ = bind_task_runner; | 77 ptr->interface_ptr_task_runner_ = bind_task_runner; |
| 78 bind_task_runner->PostTask( |
| 79 FROM_HERE, |
| 80 base::Bind(base::IgnoreResult(&ThreadSafeInterfacePtrBase::Bind), ptr, |
| 81 base::Passed(&ptr_info))); |
74 return ptr; | 82 return ptr; |
75 } | 83 } |
76 | 84 |
77 // Binds a ThreadSafeInterfacePtrBase previously created with CreateUnbound(). | 85 // Binds a ThreadSafeInterfacePtrBase previously created with CreateUnbound(). |
78 // This must be called on the thread that |interface_ptr| should be used. | 86 // This must be called on the thread that |ptr_info| should be used. |
79 // If created with CreateUnbound() that thread should be the same as the one | 87 // If created with CreateUnbound() that thread should be the same as the one |
80 // provided at creation time. | 88 // provided at creation time. |
81 bool Bind(InterfacePtrType<Interface> interface_ptr) { | 89 bool Bind(PtrInfoType ptr_info) { |
82 DCHECK(!interface_ptr_task_runner_ || | 90 DCHECK_EQ(interface_ptr_task_runner_, base::ThreadTaskRunnerHandle::Get()); |
83 interface_ptr_task_runner_ == base::ThreadTaskRunnerHandle::Get()); | 91 if (!ptr_info.is_valid()) { |
84 if (!interface_ptr.is_bound()) { | |
85 LOG(ERROR) << "Attempting to bind a ThreadSafe[Associated]InterfacePtr " | 92 LOG(ERROR) << "Attempting to bind a ThreadSafe[Associated]InterfacePtr " |
86 "from an unbound InterfacePtr."; | 93 "from an unbound InterfacePtr."; |
87 return false; | 94 return false; |
88 } | 95 } |
89 interface_ptr_ = std::move(interface_ptr); | 96 interface_ptr_.Bind(std::move(ptr_info)); |
90 interface_ptr_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | |
91 return true; | 97 return true; |
92 } | 98 } |
93 | 99 |
94 ~ThreadSafeInterfacePtrBase() override {} | 100 ~ThreadSafeInterfacePtrBase() override {} |
95 | 101 |
96 Interface* get() { return &proxy_; } | 102 Interface* get() { return &proxy_; } |
97 Interface* operator->() { return get(); } | 103 Interface* operator->() { return get(); } |
98 Interface& operator*() { return *get(); } | 104 Interface& operator*() { return *get(); } |
99 | 105 |
100 private: | 106 private: |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 using ThreadSafeAssociatedInterfacePtr = | 200 using ThreadSafeAssociatedInterfacePtr = |
195 ThreadSafeInterfacePtrBase<Interface, AssociatedInterfacePtr>; | 201 ThreadSafeInterfacePtrBase<Interface, AssociatedInterfacePtr>; |
196 | 202 |
197 template <typename Interface> | 203 template <typename Interface> |
198 using ThreadSafeInterfacePtr = | 204 using ThreadSafeInterfacePtr = |
199 ThreadSafeInterfacePtrBase<Interface, InterfacePtr>; | 205 ThreadSafeInterfacePtrBase<Interface, InterfacePtr>; |
200 | 206 |
201 } // namespace mojo | 207 } // namespace mojo |
202 | 208 |
203 #endif // MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_H_ | 209 #endif // MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_H_ |
OLD | NEW |