1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Copyright 2014 The Chromium Authors. All rights reserved. 2645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Use of this source code is governed by a BSD-style license that can be 3645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// found in the LICENSE file. 4645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 5645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#ifndef MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_ 6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_ 7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <algorithm> 9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <utility> 10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <vector> 11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/bind.h" 13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/callback.h" 14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/macros.h" 15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/memory/weak_ptr.h" 16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/cpp/bindings/binding.h" 17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace mojo { 19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Use this class to manage a set of bindings, which are automatically destroyed 21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// and removed from the set when the pipe they are bound to is disconnected. 22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveztemplate <typename Interface> 23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass BindingSet { 24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public: 25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez BindingSet() {} 26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez ~BindingSet() { CloseAllBindings(); } 27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez void set_connection_error_handler(const base::Closure& error_handler) { 29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez error_handler_ = error_handler; 30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } 31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez void AddBinding(Interface* impl, InterfaceRequest<Interface> request) { 33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez auto binding = new Element(impl, std::move(request)); 34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez binding->set_connection_error_handler( 35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez base::Bind(&BindingSet::OnConnectionError, base::Unretained(this))); 36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bindings_.push_back(binding->GetWeakPtr()); 37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } 38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Returns an InterfacePtr bound to one end of a pipe whose other end is 40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // bound to |this|. 41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez InterfacePtr<Interface> CreateInterfacePtrAndBind(Interface* impl) { 42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez InterfacePtr<Interface> interface_ptr; 43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez AddBinding(impl, GetProxy(&interface_ptr)); 44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return interface_ptr; 45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } 46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez void CloseAllBindings() { 48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez for (const auto& it : bindings_) { 49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if (it) { 50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez it->Close(); 51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez delete it.get(); 52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } 53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } 54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bindings_.clear(); 55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } 56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bool empty() const { return bindings_.empty(); } 58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez private: 60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez class Element { 61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public: 62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez Element(Interface* impl, InterfaceRequest<Interface> request) 63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez : binding_(impl, std::move(request)), weak_ptr_factory_(this) { 64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez binding_.set_connection_error_handler( 65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez base::Bind(&Element::OnConnectionError, base::Unretained(this))); 66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } 67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez ~Element() {} 69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez void set_connection_error_handler(const base::Closure& error_handler) { 71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez error_handler_ = error_handler; 72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } 73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez base::WeakPtr<Element> GetWeakPtr() { 75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return weak_ptr_factory_.GetWeakPtr(); 76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } 77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez void Close() { binding_.Close(); } 79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 80645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez void OnConnectionError() { 81645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez base::Closure error_handler = error_handler_; 82645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez delete this; 83645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if (!error_handler.is_null()) 84645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez error_handler.Run(); 85645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } 86645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 87645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez private: 88645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez Binding<Interface> binding_; 89645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez base::Closure error_handler_; 90645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez base::WeakPtrFactory<Element> weak_ptr_factory_; 91645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 92645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DISALLOW_COPY_AND_ASSIGN(Element); 93645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez }; 94645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 95645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez void OnConnectionError() { 96645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Clear any deleted bindings. 97645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bindings_.erase(std::remove_if(bindings_.begin(), bindings_.end(), 98645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez [](const base::WeakPtr<Element>& p) { 99645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return p.get() == nullptr; 100645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez }), 101645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bindings_.end()); 102645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 103645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if (!error_handler_.is_null()) 104645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez error_handler_.Run(); 105645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } 106645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 107645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez base::Closure error_handler_; 108645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez std::vector<base::WeakPtr<Element>> bindings_; 109645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 110645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DISALLOW_COPY_AND_ASSIGN(BindingSet); 111645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}; 112645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 113645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez} // namespace mojo 114645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 115645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#endif // MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_ 116