Chromium Code Reviews| 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_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 Loading... | |
| 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_ | 
| OLD | NEW |