OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 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_COMMON_SERVICE_SET_H_ | |
6 #define MOJO_COMMON_SERVICE_SET_H_ | |
7 | |
8 #include "base/bind.h" | |
9 #include "base/callback_internal.h" | |
10 #include "base/containers/scoped_ptr_map.h" | |
11 #include "base/macros.h" | |
12 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" | |
13 | |
14 namespace mojo { | |
15 | |
16 // A set of mojo services where each service's lifetime is bound to its message | |
Anand Mistry (off Chromium)
2015/11/10 04:53:39
This could really do with a longer comment.
Sam McNally
2015/11/11 07:04:02
Done.
| |
17 // pipe. | |
18 template <typename Interface, typename Impl> | |
19 class ServiceSet { | |
20 public: | |
21 using ErrorHandler = Callback<void(Impl*)>; | |
22 class Iterator; | |
23 | |
24 ServiceSet() = default; | |
25 | |
26 void set_connection_error_handler(const ErrorHandler& error_handler) { | |
27 error_handler_ = error_handler; | |
28 } | |
29 | |
30 template <typename... Args> | |
31 Impl* AddService(InterfaceRequest<Interface> request, Args&&... args) { | |
Anand Mistry (off Chromium)
2015/11/10 04:53:39
This doesn't just add a service. Maybe rename to C
Sam McNally
2015/11/11 07:04:02
Done.
| |
32 auto holder = make_scoped_ptr(new Holder( | |
33 this, request.Pass(), base::internal::CallbackForward(args)...)); | |
34 Impl* impl = holder->impl(); | |
35 holders_.insert(impl, holder.Pass()); | |
36 return impl; | |
37 } | |
38 | |
39 void EraseService(Impl* impl) { | |
Anand Mistry (off Chromium)
2015/11/10 04:53:39
Maybe RemoveService, or DestroyService if you rena
Sam McNally
2015/11/11 07:04:02
Done.
| |
40 size_t num_erased = holders_.erase(impl); | |
41 DCHECK_EQ(1u, num_erased); | |
Anand Mistry (off Chromium)
2015/11/10 04:53:39
IWYU.
#include "base/logging.h"
Sam McNally
2015/11/11 07:04:02
Done.
| |
42 } | |
43 | |
44 void EraseAllServices() { holders_.clear(); } | |
Anand Mistry (off Chromium)
2015/11/10 04:53:39
Maybe clear() instead? It fits the stl-like patter
Sam McNally
2015/11/11 07:04:02
Done.
| |
45 | |
46 bool empty() const { return holders_.empty(); } | |
47 size_t size() const { return holders_.size(); } | |
48 Iterator begin() const { return Iterator(holders_.begin()); } | |
49 Iterator end() const { return Iterator(holders_.end()); } | |
50 | |
51 private: | |
52 class Holder; | |
53 using Container = base::ScopedPtrMap<Impl*, scoped_ptr<Holder>>; | |
54 | |
55 void OnConnectionError(Holder* holder) { | |
56 Impl* impl = holder->impl(); | |
57 EraseService(impl); | |
58 if (!error_handler_.is_null()) | |
59 error_handler_.Run(impl); | |
Anand Mistry (off Chromium)
2015/11/10 04:53:39
Hmmm. At this point, |impl| has been deleted. I ca
Sam McNally
2015/11/11 07:04:02
Done.
| |
60 } | |
61 | |
62 ErrorHandler error_handler_; | |
63 Container holders_; | |
64 | |
65 DISALLOW_COPY_AND_ASSIGN(ServiceSet); | |
66 }; | |
67 | |
68 template <typename Interface, typename Impl> | |
69 class ServiceSet<Interface, Impl>::Holder { | |
70 public: | |
71 using ErrorHandler = base::Callback<void(Holder*)>; | |
Anand Mistry (off Chromium)
2015/11/10 04:53:39
Unused?
Sam McNally
2015/11/11 07:04:02
Done.
| |
72 | |
73 template <typename... Args> | |
74 Holder(ServiceSet* service_set, | |
75 InterfaceRequest<Interface> request, | |
76 Args&&... args) | |
77 : impl_(base::internal::CallbackForward(args)...), | |
78 binding_(&impl_, request.Pass()), | |
79 service_set_(service_set) { | |
80 binding_.set_connection_error_handler( | |
81 base::Bind(&Holder::OnConnectionError, base::Unretained(this))); | |
82 } | |
83 | |
84 void OnConnectionError() { service_set_->OnConnectionError(this); } | |
85 | |
86 Impl* impl() { return &impl_; } | |
87 | |
88 private: | |
89 Impl impl_; | |
90 Binding<Interface> binding_; | |
91 | |
92 // Owns this. | |
93 ServiceSet* const service_set_; | |
94 | |
95 DISALLOW_COPY_AND_ASSIGN(Holder); | |
96 }; | |
97 | |
98 template <typename Interface, typename Impl> | |
99 class ServiceSet<Interface, Impl>::Iterator { | |
100 public: | |
101 using iterator_category = std::input_iterator_tag; | |
102 using difference_type = std::ptrdiff_t; | |
103 using value_type = Impl*; | |
104 using pointer = value_type*; | |
105 using reference = value_type&; | |
106 | |
107 Iterator() = default; | |
108 | |
109 Iterator& operator++() { | |
110 ++it_; | |
111 return *this; | |
112 } | |
113 | |
114 Impl* operator*() const { return it_->first; } | |
115 Impl* operator->() const { return it_->first; } | |
116 bool operator==(const Iterator& other) const { return it_ == other.it_; } | |
117 bool operator!=(const Iterator& other) const { return it_ != other.it_; } | |
118 | |
119 private: | |
120 using IteratorImpl = typename Container::const_iterator; | |
121 friend class ServiceSet; | |
122 | |
123 explicit Iterator(IteratorImpl it) : it_(it) {} | |
124 | |
125 IteratorImpl it_; | |
126 }; | |
127 | |
128 } // namespace mojo | |
129 | |
130 #endif // MOJO_COMMON_SERVICE_SET_H_ | |
OLD | NEW |