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

Side by Side Diff: media/mojo/services/strong_binding_set.h

Issue 2530613003: media: Fix lifetime of InterfaceFactoryImpl and created impls (Closed)
Patch Set: comments addressed Created 4 years 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
(Empty)
1 // Copyright 2016 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 MEDIA_MOJO_SERVICES_STRONG_BINDING_SET_H_
6 #define MEDIA_MOJO_SERVICES_STRONG_BINDING_SET_H_
7
8 #include <map>
9 #include <memory>
10 #include <utility>
11
12 #include "base/bind.h"
13 #include "base/macros.h"
14 #include "base/memory/ptr_util.h"
15 #include "mojo/public/cpp/bindings/binding.h"
16 #include "mojo/public/cpp/bindings/interface_request.h"
17
18 namespace media {
19
20 // This class manages a set of bindings. When the pipe a binding is bound to is
21 // disconnected, the binding is automatically destroyed and removed from the
22 // set, and the interface implementation is deleted. When the StrongBindingSet
23 // is destructed, all outstanding bindings in the set are destroyed and all the
24 // bound interface implementations are automatically deleted.
25 template <typename Interface>
26 class StrongBindingSet {
27 public:
28 using BindingId = size_t;
29 using RequestType = mojo::InterfaceRequest<Interface>;
30
31 StrongBindingSet() {}
32 ~StrongBindingSet() {}
33
34 // Adds a new binding to the set which binds |request| to |impl|.
35 BindingId AddBinding(std::unique_ptr<Interface> impl, RequestType request) {
36 BindingId binding_id = next_binding_id_++;
37 std::unique_ptr<Entry> entry = base::MakeUnique<Entry>(
38 std::move(impl), std::move(request), this, binding_id);
39 bindings_.insert(std::make_pair(binding_id, std::move(entry)));
40 return binding_id;
41 }
42
43 // Removes a binding from the set. Note that this is safe to call even if the
44 // binding corresponding to |binding_id| has already been removed.
45 // Returns |true| if the binding was removed and |false| if it didn't exist.
46 bool RemoveBinding(BindingId binding_id) {
47 auto it = bindings_.find(binding_id);
48 if (it == bindings_.end())
49 return false;
50 bindings_.erase(it);
51 return true;
52 }
53
54 private:
55 class Entry {
56 public:
57 Entry(std::unique_ptr<Interface> impl,
58 RequestType request,
59 StrongBindingSet* binding_set,
60 BindingId binding_id)
61 : impl_(std::move(impl)),
62 binding_(impl_.get(), std::move(request)),
63 binding_set_(binding_set),
64 binding_id_(binding_id) {
65 // base::Unretained() is safe because |this| is owned by the
66 // |binding_set|.
67 binding_.set_connection_error_with_reason_handler(
68 base::Bind(&StrongBindingSet::OnConnectionError,
69 base::Unretained(binding_set), binding_id));
70 }
71
72 // Holds ownership of the interface implementation.
73 std::unique_ptr<Interface> impl_;
74
75 mojo::Binding<Interface> binding_;
76 StrongBindingSet* const binding_set_;
77 const BindingId binding_id_;
78
79 DISALLOW_COPY_AND_ASSIGN(Entry);
80 };
81
82 void OnConnectionError(BindingId binding_id,
83 uint32_t custom_reason,
84 const std::string& description) {
85 bool success = RemoveBinding(binding_id);
86 DCHECK(success) << "Binding for ID " << binding_id << " does not exist.";
87 }
88
89 std::map<BindingId, std::unique_ptr<Entry>> bindings_;
90 BindingId next_binding_id_ = 0;
91
92 DISALLOW_COPY_AND_ASSIGN(StrongBindingSet);
93 };
94
95 } // namespace media
96
97 #endif // MEDIA_MOJO_SERVICES_STRONG_BINDING_SET_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698