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_INTERFACE_PTR_SET_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_PTR_SET_H_ 7 8 #include <utility> 9 #include <vector> 10 11 #include "base/macros.h" 12 #include "base/memory/weak_ptr.h" 13 #include "mojo/public/cpp/bindings/associated_interface_ptr.h" 14 #include "mojo/public/cpp/bindings/interface_ptr.h" 15 16 namespace mojo { 17 namespace internal { 18 19 template <typename Interface, template <typename> class Ptr> 20 class PtrSet { 21 public: PtrSet()22 PtrSet() {} ~PtrSet()23 ~PtrSet() { CloseAll(); } 24 AddPtr(Ptr<Interface> ptr)25 void AddPtr(Ptr<Interface> ptr) { 26 auto weak_interface_ptr = new Element(std::move(ptr)); 27 ptrs_.push_back(weak_interface_ptr->GetWeakPtr()); 28 ClearNullPtrs(); 29 } 30 31 template <typename FunctionType> ForAllPtrs(FunctionType function)32 void ForAllPtrs(FunctionType function) { 33 for (const auto& it : ptrs_) { 34 if (it) 35 function(it->get()); 36 } 37 ClearNullPtrs(); 38 } 39 CloseAll()40 void CloseAll() { 41 for (const auto& it : ptrs_) { 42 if (it) 43 it->Close(); 44 } 45 ptrs_.clear(); 46 } 47 48 private: 49 class Element { 50 public: Element(Ptr<Interface> ptr)51 explicit Element(Ptr<Interface> ptr) 52 : ptr_(std::move(ptr)), weak_ptr_factory_(this) { 53 ptr_.set_connection_error_handler(base::Bind(&DeleteElement, this)); 54 } 55 ~Element()56 ~Element() {} 57 Close()58 void Close() { ptr_.reset(); } 59 get()60 Interface* get() { return ptr_.get(); } 61 GetWeakPtr()62 base::WeakPtr<Element> GetWeakPtr() { 63 return weak_ptr_factory_.GetWeakPtr(); 64 } 65 66 private: DeleteElement(Element * element)67 static void DeleteElement(Element* element) { delete element; } 68 69 Ptr<Interface> ptr_; 70 base::WeakPtrFactory<Element> weak_ptr_factory_; 71 72 DISALLOW_COPY_AND_ASSIGN(Element); 73 }; 74 ClearNullPtrs()75 void ClearNullPtrs() { 76 ptrs_.erase(std::remove_if(ptrs_.begin(), ptrs_.end(), 77 [](const base::WeakPtr<Element>& p) { 78 return p.get() == nullptr; 79 }), 80 ptrs_.end()); 81 } 82 83 std::vector<base::WeakPtr<Element>> ptrs_; 84 }; 85 86 } // namespace internal 87 88 template <typename Interface> 89 using InterfacePtrSet = internal::PtrSet<Interface, InterfacePtr>; 90 91 template <typename Interface> 92 using AssociatedInterfacePtrSet = 93 internal::PtrSet<Interface, AssociatedInterfacePtr>; 94 95 } // namespace mojo 96 97 #endif // MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_PTR_SET_H_ 98