Chromium Code Reviews| 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_ |