| 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->Bind(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 // This must be called on the thread that |interface_ptr| should be used. |
| 70 bool Bind(InterfacePtrType<Interface> interface_ptr) { |
| 71 DCHECK(!interface_ptr_task_runner_); |
| 51 if (!interface_ptr.is_bound()) { | 72 if (!interface_ptr.is_bound()) { |
| 52 LOG(ERROR) << "Attempting to create a ThreadSafe[Associated]InterfacePtr " | 73 LOG(ERROR) << "Attempting to bind a ThreadSafe[Associated]InterfacePtr " |
| 53 "from an unbound InterfacePtr."; | 74 "from an unbound InterfacePtr."; |
| 54 return nullptr; | 75 return false; |
| 55 } | 76 } |
| 56 return new ThreadSafeInterfacePtrBase(std::move(interface_ptr), | 77 interface_ptr_ = std::move(interface_ptr); |
| 57 base::ThreadTaskRunnerHandle::Get()); | 78 interface_ptr_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
| 79 return true; |
| 58 } | 80 } |
| 59 | 81 |
| 60 ~ThreadSafeInterfacePtrBase() override {} | 82 ~ThreadSafeInterfacePtrBase() override {} |
| 61 | 83 |
| 62 Interface* get() { return &proxy_; } | 84 Interface* get() { return &proxy_; } |
| 63 Interface* operator->() { return get(); } | 85 Interface* operator->() { return get(); } |
| 64 Interface& operator*() { return *get(); } | 86 Interface& operator*() { return *get(); } |
| 65 | 87 |
| 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: | 88 private: |
| 76 friend class base::RefCountedThreadSafe< | 89 friend class base::RefCountedThreadSafe< |
| 77 ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>>; | 90 ThreadSafeInterfacePtrBase<Interface, InterfacePtrType>>; |
| 78 friend struct ThreadSafeInterfacePtrDeleter; | 91 friend struct ThreadSafeInterfacePtrDeleter; |
| 79 | 92 |
| 93 ThreadSafeInterfacePtrBase() : proxy_(this), weak_ptr_factory_(this) {} |
| 94 |
| 80 void DeleteOnCorrectThread() const { | 95 void DeleteOnCorrectThread() const { |
| 81 if (!interface_ptr_task_runner_->BelongsToCurrentThread() && | 96 if (interface_ptr_task_runner_ && |
| 97 !interface_ptr_task_runner_->BelongsToCurrentThread() && |
| 82 interface_ptr_task_runner_->DeleteSoon(FROM_HERE, this)) { | 98 interface_ptr_task_runner_->DeleteSoon(FROM_HERE, this)) { |
| 83 return; | 99 return; |
| 84 } | 100 } |
| 85 delete this; | 101 delete this; |
| 86 } | 102 } |
| 87 | 103 |
| 88 // MessageReceiverWithResponder implementation: | 104 // MessageReceiverWithResponder implementation: |
| 89 bool Accept(Message* message) override { | 105 bool Accept(Message* message) override { |
| 90 interface_ptr_task_runner_->PostTask( | 106 interface_ptr_task_runner_->PostTask( |
| 91 FROM_HERE, | 107 FROM_HERE, |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 template <typename Interface> | 181 template <typename Interface> |
| 166 using ThreadSafeAssociatedInterfacePtr = | 182 using ThreadSafeAssociatedInterfacePtr = |
| 167 ThreadSafeInterfacePtrBase<Interface, AssociatedInterfacePtr>; | 183 ThreadSafeInterfacePtrBase<Interface, AssociatedInterfacePtr>; |
| 168 | 184 |
| 169 template <typename Interface> | 185 template <typename Interface> |
| 170 using ThreadSafeInterfacePtr = | 186 using ThreadSafeInterfacePtr = |
| 171 ThreadSafeInterfacePtrBase<Interface, InterfacePtr>; | 187 ThreadSafeInterfacePtrBase<Interface, InterfacePtr>; |
| 172 | 188 |
| 173 } // namespace mojo | 189 } // namespace mojo |
| 174 | 190 |
| 175 #endif // MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_BASE_H_ | 191 #endif // MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_INTERFACE_PTR_H_ |
| OLD | NEW |