Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: mojo/public/cpp/bindings/binding_set.h

Issue 2283543002: Add support for dispatch contexts on BindingSet (Closed)
Patch Set: . Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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_BINDING_SET_H_ 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_
7 7
8 #include <algorithm>
9 #include <utility> 8 #include <utility>
10 #include <vector>
11 9
12 #include "base/bind.h" 10 #include "base/bind.h"
13 #include "base/callback.h" 11 #include "base/callback.h"
14 #include "base/macros.h" 12 #include "base/macros.h"
15 #include "base/memory/weak_ptr.h"
16 #include "mojo/public/cpp/bindings/binding.h" 13 #include "mojo/public/cpp/bindings/binding.h"
14 #include "mojo/public/cpp/bindings/interface_ptr.h"
15 #include "mojo/public/cpp/bindings/interface_request.h"
16 #include "mojo/public/cpp/bindings/message.h"
17 17
18 namespace mojo { 18 namespace mojo {
19 19
20 template <typename BindingType>
21 struct BindingSetTraits;
22
23 template <typename Interface>
24 struct BindingSetTraits<Binding<Interface>> {
25 using ProxyType = InterfacePtr<Interface>;
26 using RequestType = InterfaceRequest<Interface>;
27
28 static RequestType GetProxy(ProxyType* proxy) {
29 return mojo::GetProxy(proxy);
30 }
31 };
32
20 // Use this class to manage a set of bindings, which are automatically destroyed 33 // Use this class to manage a set of bindings, which are automatically destroyed
21 // and removed from the set when the pipe they are bound to is disconnected. 34 // and removed from the set when the pipe they are bound to is disconnected.
22 template <typename Interface> 35 template <typename Interface, typename BindingType = Binding<Interface>>
23 class BindingSet { 36 class BindingSet {
24 public: 37 public:
38 using Traits = BindingSetTraits<BindingType>;
39 using ProxyType = typename Traits::ProxyType;
40 using RequestType = typename Traits::RequestType;
41
25 BindingSet() {} 42 BindingSet() {}
26 ~BindingSet() { CloseAllBindings(); }
27 43
28 void set_connection_error_handler(const base::Closure& error_handler) { 44 void set_connection_error_handler(const base::Closure& error_handler) {
29 error_handler_ = error_handler; 45 error_handler_ = error_handler;
30 } 46 }
31 47
32 void AddBinding(Interface* impl, InterfaceRequest<Interface> request) { 48 void AddBinding(Interface* impl,
33 auto binding = new Element(impl, std::move(request)); 49 RequestType request,
34 binding->set_connection_error_handler( 50 void* context = nullptr) {
35 base::Bind(&BindingSet::OnConnectionError, base::Unretained(this))); 51 std::unique_ptr<Entry> entry =
36 bindings_.push_back(binding->GetWeakPtr()); 52 base::MakeUnique<Entry>(impl, std::move(request), this, context);
53 bindings_.insert(std::make_pair(entry.get(), std::move(entry)));
37 } 54 }
38 55
39 // Returns an InterfacePtr bound to one end of a pipe whose other end is 56 // Returns a proxy bound to one end of a pipe whose other end is bound to
40 // bound to |this|. 57 // |this|.
41 InterfacePtr<Interface> CreateInterfacePtrAndBind(Interface* impl) { 58 ProxyType CreateInterfacePtrAndBind(Interface* impl) {
42 InterfacePtr<Interface> interface_ptr; 59 ProxyType proxy;
43 AddBinding(impl, GetProxy(&interface_ptr)); 60 AddBinding(impl, Traits::GetProxy(&proxy));
yzshen1 2016/08/26 16:30:48 Is it intentional that we don't provide a similar
Ken Rockot(use gerrit already) 2016/08/26 17:01:20 It's not possible to implement since we wouldn't k
yzshen1 2016/08/26 18:11:28 Right. I don't think it is that important to suppo
44 return interface_ptr; 61 return proxy;
45 } 62 }
46 63
47 void CloseAllBindings() { 64 void CloseAllBindings() {}
yzshen1 2016/08/26 16:30:48 Why this is a non-op?
Ken Rockot(use gerrit already) 2016/08/26 17:01:20 Oops :> Fixed
48 for (const auto& it : bindings_) {
49 if (it) {
50 it->Close();
51 delete it.get();
52 }
53 }
54 bindings_.clear();
55 }
56 65
57 bool empty() const { return bindings_.empty(); } 66 bool empty() const { return bindings_.empty(); }
58 67
68 // Implementations may call this when processing a dispatched message. During
69 // the extent of a message dispatch (or connection error handler invocation),
70 // this will return the context associated with the binding which received
71 // the message (or error.) Use AddBinding() to associated a context with a
72 // specific binding.
73 void* dispatch_context() const { return dispatch_context_; }
74
59 private: 75 private:
60 class Element { 76 friend class Entry;
77
78 class Entry {
61 public: 79 public:
62 Element(Interface* impl, InterfaceRequest<Interface> request) 80 Entry(Interface* impl,
63 : binding_(impl, std::move(request)), weak_ptr_factory_(this) { 81 RequestType request,
64 binding_.set_connection_error_handler( 82 BindingSet* binding_set,
65 base::Bind(&Element::OnConnectionError, base::Unretained(this))); 83 void* context)
66 } 84 : binding_(impl, std::move(request)),
67 85 binding_set_(binding_set),
68 ~Element() {} 86 context_(context) {
69 87 binding_.AddFilter(base::MakeUnique<DispatchFilter>(this));
yzshen1 2016/08/26 16:30:48 Do we expect that setting context is a common oper
Ken Rockot(use gerrit already) 2016/08/26 17:01:20 Seems reasonable. I've added a mojo::BindingSetDis
70 void set_connection_error_handler(const base::Closure& error_handler) { 88 binding_.set_connection_error_handler(base::Bind(
71 error_handler_ = error_handler; 89 &Entry::OnConnectionError, base::Unretained(this)));
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 base::Closure error_handler = error_handler_;
82 delete this;
83 if (!error_handler.is_null())
84 error_handler.Run();
85 } 90 }
86 91
87 private: 92 private:
88 Binding<Interface> binding_; 93 class DispatchFilter : public MessageReceiver {
89 base::Closure error_handler_; 94 public:
90 base::WeakPtrFactory<Element> weak_ptr_factory_; 95 explicit DispatchFilter(Entry* entry) : entry_(entry) {}
96 ~DispatchFilter() override {}
91 97
92 DISALLOW_COPY_AND_ASSIGN(Element); 98 private:
99 // MessageReceiver:
100 bool Accept(Message* message) override {
101 entry_->WillDispatch();
102 return true;
103 }
104
105 Entry* entry_;
106
107 DISALLOW_COPY_AND_ASSIGN(DispatchFilter);
108 };
109
110 void WillDispatch() {
111 binding_set_->set_dispatch_context(context_);
112 }
113
114 void OnConnectionError() {
115 WillDispatch();
116 binding_set_->OnConnectionError(this);
117 }
118
119 BindingType binding_;
120 BindingSet* const binding_set_;
121 void* const context_;
122
123 DISALLOW_COPY_AND_ASSIGN(Entry);
93 }; 124 };
94 125
95 void OnConnectionError() { 126 void set_dispatch_context(void* context) { dispatch_context_ = context; }
96 // Clear any deleted bindings. 127
97 bindings_.erase(std::remove_if(bindings_.begin(), bindings_.end(), 128 void OnConnectionError(Entry* entry) {
98 [](const base::WeakPtr<Element>& p) { 129 auto it = bindings_.find(entry);
99 return p.get() == nullptr; 130 DCHECK(it != bindings_.end());
100 }), 131 bindings_.erase(it);
101 bindings_.end());
102 132
103 if (!error_handler_.is_null()) 133 if (!error_handler_.is_null())
104 error_handler_.Run(); 134 error_handler_.Run();
105 } 135 }
106 136
107 base::Closure error_handler_; 137 base::Closure error_handler_;
108 std::vector<base::WeakPtr<Element>> bindings_; 138 std::map<Entry*, std::unique_ptr<Entry>> bindings_;
139 void* dispatch_context_ = nullptr;
109 140
110 DISALLOW_COPY_AND_ASSIGN(BindingSet); 141 DISALLOW_COPY_AND_ASSIGN(BindingSet);
111 }; 142 };
112 143
113 } // namespace mojo 144 } // namespace mojo
114 145
115 #endif // MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_ 146 #endif // MOJO_PUBLIC_CPP_BINDINGS_BINDING_SET_H_
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/associated_binding_set.h ('k') | mojo/public/cpp/bindings/lib/binding_state.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698