OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_ |
| 6 #define MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_ |
| 7 |
| 8 #include <algorithm> |
| 9 #include <utility> |
| 10 #include <vector> |
| 11 |
| 12 #include "base/macros.h" |
| 13 #include "base/memory/weak_ptr.h" |
| 14 #include "mojo/public/cpp/bindings/binding.h" |
| 15 |
| 16 namespace mojo { |
| 17 |
| 18 // Use this class to manage a set of bindings, which are automatically destroyed |
| 19 // and removed from the set when the pipe they bound to is disconnected. |
| 20 template <typename Interface> |
| 21 class BindingSet { |
| 22 public: |
| 23 using GenericInterface = typename Interface::GenericInterface; |
| 24 |
| 25 BindingSet() {} |
| 26 ~BindingSet() { CloseAllBindings(); } |
| 27 |
| 28 void set_connection_error_handler(const Closure& error_handler) { |
| 29 error_handler_ = error_handler; |
| 30 } |
| 31 |
| 32 void AddBinding(Interface* impl, InterfaceRequest<GenericInterface> request) { |
| 33 auto binding = new Element(impl, std::move(request)); |
| 34 binding->set_connection_error_handler([this]() { OnConnectionError(); }); |
| 35 bindings_.push_back(binding->GetWeakPtr()); |
| 36 } |
| 37 |
| 38 // Returns an InterfacePtr bound to one end of a pipe whose other end is |
| 39 // bound to |this|. |
| 40 InterfacePtr<Interface> CreateInterfacePtrAndBind(Interface* impl) { |
| 41 InterfacePtr<Interface> interface_ptr; |
| 42 AddBinding(impl, GetProxy(&interface_ptr)); |
| 43 return interface_ptr; |
| 44 } |
| 45 |
| 46 void CloseAllBindings() { |
| 47 for (const auto& it : bindings_) { |
| 48 if (it) { |
| 49 it->Close(); |
| 50 delete it.get(); |
| 51 } |
| 52 } |
| 53 bindings_.clear(); |
| 54 } |
| 55 |
| 56 bool empty() const { return bindings_.empty(); } |
| 57 |
| 58 private: |
| 59 class Element { |
| 60 public: |
| 61 using GenericInterface = typename Interface::GenericInterface; |
| 62 |
| 63 Element(Interface* impl, InterfaceRequest<GenericInterface> request) |
| 64 : binding_(impl, std::move(request)), weak_ptr_factory_(this) { |
| 65 binding_.set_connection_error_handler([this]() { OnConnectionError(); }); |
| 66 } |
| 67 |
| 68 ~Element() {} |
| 69 |
| 70 void set_connection_error_handler(const Closure& error_handler) { |
| 71 error_handler_ = error_handler; |
| 72 } |
| 73 |
| 74 base::WeakPtr<Element> GetWeakPtr() { |
| 75 return weak_ptr_factory_.GetWeakPtr(); |
| 76 } |
| 77 |
| 78 void Close() { binding_.Close(); } |
| 79 |
| 80 void OnConnectionError() { |
| 81 Closure error_handler = error_handler_; |
| 82 delete this; |
| 83 error_handler.Run(); |
| 84 } |
| 85 |
| 86 private: |
| 87 Binding<Interface> binding_; |
| 88 Closure error_handler_; |
| 89 base::WeakPtrFactory<Element> weak_ptr_factory_; |
| 90 |
| 91 DISALLOW_COPY_AND_ASSIGN(Element); |
| 92 }; |
| 93 |
| 94 void OnConnectionError() { |
| 95 // Clear any deleted bindings. |
| 96 bindings_.erase(std::remove_if(bindings_.begin(), bindings_.end(), |
| 97 [](const base::WeakPtr<Element>& p) { |
| 98 return p.get() == nullptr; |
| 99 }), |
| 100 bindings_.end()); |
| 101 |
| 102 error_handler_.Run(); |
| 103 } |
| 104 |
| 105 Closure error_handler_; |
| 106 std::vector<base::WeakPtr<Element>> bindings_; |
| 107 |
| 108 DISALLOW_COPY_AND_ASSIGN(BindingSet); |
| 109 }; |
| 110 |
| 111 } // namespace mojo |
| 112 |
| 113 #endif // MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_ |
OLD | NEW |