| 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..fb1142de96abdeab1773d986539cc74872628342
|
| --- /dev/null
|
| +++ b/media/mojo/services/strong_binding_set.h
|
| @@ -0,0 +1,97 @@
|
| +// 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 {
|
| + public:
|
| + using BindingId = size_t;
|
| + using RequestType = mojo::InterfaceRequest<Interface>;
|
| +
|
| + StrongBindingSet() {}
|
| + ~StrongBindingSet() {}
|
| +
|
| + // Adds a new binding to the set which binds |request| to |impl|.
|
| + BindingId 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)));
|
| + return binding_id;
|
| + }
|
| +
|
| + // Removes a binding from the set. Note that this is safe to call even if the
|
| + // binding corresponding to |binding_id| has already been removed.
|
| + // Returns |true| if the binding was removed and |false| if it didn't exist.
|
| + bool RemoveBinding(BindingId binding_id) {
|
| + auto it = bindings_.find(binding_id);
|
| + if (it == bindings_.end())
|
| + return false;
|
| + bindings_.erase(it);
|
| + return true;
|
| + }
|
| +
|
| + 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) {
|
| + // base::Unretained() is safe because |this| is owned by the
|
| + // |binding_set|.
|
| + binding_.set_connection_error_with_reason_handler(
|
| + base::Bind(&StrongBindingSet::OnConnectionError,
|
| + base::Unretained(binding_set), binding_id));
|
| + }
|
| +
|
| + // 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) {
|
| + bool success = RemoveBinding(binding_id);
|
| + DCHECK(success) << "Binding for ID " << binding_id << " does not exist.";
|
| + }
|
| +
|
| + 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_
|
|
|