| 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 |