Index: media/mojo/services/strong_binding_set.h |
diff --git a/media/mojo/services/strong_binding_set.h b/media/mojo/services/strong_binding_set.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1b4232db662c2ddaf457c3241bb96c5db38517dc |
--- /dev/null |
+++ b/media/mojo/services/strong_binding_set.h |
@@ -0,0 +1,87 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef MEDIA_MOJO_SERVICES_STRONG_BINDING_SET_H_ |
+#define MEDIA_MOJO_SERVICES_STRONG_BINDING_SET_H_ |
+ |
+#include <map> |
+#include <memory> |
+#include <utility> |
+ |
+#include "base/bind.h" |
+#include "base/macros.h" |
+#include "base/memory/ptr_util.h" |
+#include "mojo/public/cpp/bindings/binding.h" |
+#include "mojo/public/cpp/bindings/interface_request.h" |
+ |
+namespace media { |
+ |
+// This class manages a set of bindings. When the pipe a binding is bound to is |
+// disconnected, the binding is automatically destroyed and removed from the |
+// set, and the interface implementation is deleted. When the StrongBindingSet |
+// is destructed, all outstanding bindings in the set are destroyed and all the |
+// bound interface implementations are automatically deleted. |
+template <typename Interface> |
+class StrongBindingSet { |
xhwang
2016/11/23 22:27:09
rockot: Following our offline discussion. Please t
xhwang
2016/11/29 10:20:57
Test added.
|
+ public: |
+ using BindingId = size_t; |
+ using RequestType = mojo::InterfaceRequest<Interface>; |
+ |
+ StrongBindingSet() {} |
+ ~StrongBindingSet() {} |
+ |
+ void AddBinding(std::unique_ptr<Interface> impl, RequestType request) { |
+ BindingId binding_id = next_binding_id_++; |
+ std::unique_ptr<Entry> entry = base::MakeUnique<Entry>( |
+ std::move(impl), std::move(request), this, binding_id); |
+ bindings_.insert(std::make_pair(binding_id, std::move(entry))); |
+ } |
+ |
+ private: |
+ class Entry { |
+ public: |
+ Entry(std::unique_ptr<Interface> impl, |
+ RequestType request, |
+ StrongBindingSet* binding_set, |
+ BindingId binding_id) |
+ : impl_(std::move(impl)), |
+ binding_(impl_.get(), std::move(request)), |
+ binding_set_(binding_set), |
+ binding_id_(binding_id) { |
+ binding_.set_connection_error_with_reason_handler( |
+ base::Bind(&Entry::OnConnectionError, base::Unretained(this))); |
Ken Rockot(use gerrit already)
2016/11/23 22:33:31
nit, you could just bind directly to BindingSet::O
xhwang
2016/11/29 10:20:57
Done.
|
+ } |
+ |
+ void OnConnectionError(uint32_t custom_reason, |
+ const std::string& description) { |
+ binding_set_->OnConnectionError(binding_id_, custom_reason, description); |
+ } |
+ |
+ // Holds ownership of the interface implementation. |
+ std::unique_ptr<Interface> impl_; |
+ |
+ mojo::Binding<Interface> binding_; |
+ StrongBindingSet* const binding_set_; |
+ const BindingId binding_id_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(Entry); |
+ }; |
+ |
+ void OnConnectionError(BindingId binding_id, |
+ uint32_t custom_reason, |
+ const std::string& description) { |
+ auto it = bindings_.find(binding_id); |
+ DCHECK(it != bindings_.end()); |
+ bindings_.erase(it); |
+ } |
+ |
+ std::map<BindingId, std::unique_ptr<Entry>> bindings_; |
+ BindingId next_binding_id_ = 0; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(StrongBindingSet); |
+}; |
+ |
+} // namespace media |
+ |
+#endif // MEDIA_MOJO_SERVICES_STRONG_BINDING_SET_H_ |