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

Side by Side Diff: mojo/public/cpp/bindings/strong_binding.h

Issue 2326913003: Privatize StrongBinding lifetime management (Closed)
Patch Set: rebase Created 4 years, 3 months 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_H_ 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_H_
7 7
8 #include <memory>
8 #include <utility> 9 #include <utility>
9 10
10 #include "base/bind.h" 11 #include "base/bind.h"
11 #include "base/callback.h" 12 #include "base/callback.h"
12 #include "base/logging.h" 13 #include "base/logging.h"
13 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/memory/weak_ptr.h"
14 #include "mojo/public/cpp/bindings/binding.h" 16 #include "mojo/public/cpp/bindings/binding.h"
15 #include "mojo/public/cpp/bindings/filter_chain.h" 17 #include "mojo/public/cpp/bindings/filter_chain.h"
16 #include "mojo/public/cpp/bindings/interface_ptr.h" 18 #include "mojo/public/cpp/bindings/interface_ptr.h"
17 #include "mojo/public/cpp/bindings/interface_request.h" 19 #include "mojo/public/cpp/bindings/interface_request.h"
18 #include "mojo/public/cpp/bindings/lib/router.h" 20 #include "mojo/public/cpp/bindings/lib/router.h"
19 #include "mojo/public/cpp/bindings/message_header_validator.h" 21 #include "mojo/public/cpp/bindings/message_header_validator.h"
20 #include "mojo/public/cpp/system/core.h" 22 #include "mojo/public/cpp/system/core.h"
21 23
22 namespace mojo { 24 namespace mojo {
23 25
26 template <typename Interface>
27 class StrongBinding;
28
29 template <typename Interface>
30 using StrongBindingPtr = base::WeakPtr<StrongBinding<Interface>>;
31
24 // This connects an interface implementation strongly to a pipe. When a 32 // This connects an interface implementation strongly to a pipe. When a
25 // connection error is detected the implementation is deleted. Deleting the 33 // connection error is detected the implementation is deleted.
26 // connector also closes the pipe.
27 // 34 //
28 // Example of an implementation that is always bound strongly to a pipe 35 // To use, call StrongBinding<T>::Create() (see below) or the helper
36 // MakeStrongBinding function:
29 // 37 //
30 // class StronglyBound : public Foo { 38 // mojo::MakeStrongBinding(base::MakeUnique<FooImpl>(),
31 // public: 39 // std::move(foo_request));
32 // explicit StronglyBound(InterfaceRequest<Foo> request)
33 // : binding_(this, std::move(request)) {}
34 // 40 //
35 // // Foo implementation here
36 //
37 // private:
38 // StrongBinding<Foo> binding_;
39 // };
40 //
41 // class MyFooFactory : public InterfaceFactory<Foo> {
42 // public:
43 // void Create(..., InterfaceRequest<Foo> request) override {
44 // new StronglyBound(std::move(request)); // The binding now owns the
45 // // instance of StronglyBound.
46 // }
47 // };
48 //
49 // This class is thread hostile once it is bound to a message pipe. Until it is
50 // bound, it may be bound or destroyed on any thread.
51 template <typename Interface> 41 template <typename Interface>
52 class StrongBinding { 42 class StrongBinding {
53 public: 43 public:
54 explicit StrongBinding(Interface* impl) : binding_(impl) {} 44 // Create a new StrongBinding instance. The instance owns itself, cleaning up
55 45 // only in the event of a pipe connection error. Returns a WeakPtr to the new
56 StrongBinding(Interface* impl, ScopedMessagePipeHandle handle) 46 // StrongBinding instance.
57 : StrongBinding(impl) { 47 static StrongBindingPtr<Interface> Create(
58 Bind(std::move(handle)); 48 std::unique_ptr<Interface> impl,
59 } 49 InterfaceRequest<Interface> request) {
60 50 StrongBinding* binding =
61 StrongBinding(Interface* impl, InterfacePtr<Interface>* ptr) 51 new StrongBinding(std::move(impl), std::move(request));
62 : StrongBinding(impl) { 52 return binding->weak_factory_.GetWeakPtr();
63 Bind(ptr);
64 }
65
66 StrongBinding(Interface* impl, InterfaceRequest<Interface> request)
67 : StrongBinding(impl) {
68 Bind(std::move(request));
69 }
70
71 ~StrongBinding() {}
72
73 void Bind(ScopedMessagePipeHandle handle) {
74 DCHECK(!binding_.is_bound());
75 binding_.Bind(std::move(handle));
76 binding_.set_connection_error_handler(
77 base::Bind(&StrongBinding::OnConnectionError, base::Unretained(this)));
78 }
79
80 void Bind(InterfacePtr<Interface>* ptr) {
81 DCHECK(!binding_.is_bound());
82 binding_.Bind(ptr);
83 binding_.set_connection_error_handler(
84 base::Bind(&StrongBinding::OnConnectionError, base::Unretained(this)));
85 }
86
87 void Bind(InterfaceRequest<Interface> request) {
88 DCHECK(!binding_.is_bound());
89 binding_.Bind(std::move(request));
90 binding_.set_connection_error_handler(
91 base::Bind(&StrongBinding::OnConnectionError, base::Unretained(this)));
92 }
93
94 bool WaitForIncomingMethodCall() {
95 return binding_.WaitForIncomingMethodCall();
96 } 53 }
97 54
98 // Note: The error handler must not delete the interface implementation. 55 // Note: The error handler must not delete the interface implementation.
99 // 56 //
100 // This method may only be called after this StrongBinding has been bound to a 57 // This method may only be called after this StrongBinding has been bound to a
101 // message pipe. 58 // message pipe.
102 void set_connection_error_handler(const base::Closure& error_handler) { 59 void set_connection_error_handler(const base::Closure& error_handler) {
103 DCHECK(binding_.is_bound()); 60 DCHECK(binding_.is_bound());
104 connection_error_handler_ = error_handler; 61 connection_error_handler_ = error_handler;
105 } 62 }
106 63
107 Interface* impl() { return binding_.impl(); } 64 // Forces the binding to close. This destroys the StrongBinding instance.
65 void Close() { delete this; }
66
67 Interface* impl() { return impl_.get(); }
68
108 // Exposed for testing, should not generally be used. 69 // Exposed for testing, should not generally be used.
109 internal::Router* internal_router() { return binding_.internal_router(); } 70 internal::Router* internal_router() { return binding_.internal_router(); }
110 71
111 void OnConnectionError() {
112 if (!connection_error_handler_.is_null())
113 connection_error_handler_.Run();
114 delete binding_.impl();
115 }
116
117 // Sends a message on the underlying message pipe and runs the current 72 // Sends a message on the underlying message pipe and runs the current
118 // message loop until its response is received. This can be used in tests to 73 // message loop until its response is received. This can be used in tests to
119 // verify that no message was sent on a message pipe in response to some 74 // verify that no message was sent on a message pipe in response to some
120 // stimulus. 75 // stimulus.
121 void FlushForTesting() { binding_.FlushForTesting(); } 76 void FlushForTesting() { binding_.FlushForTesting(); }
122 77
123 private: 78 private:
79 StrongBinding(std::unique_ptr<Interface> impl,
80 InterfaceRequest<Interface> request)
81 : impl_(std::move(impl)),
82 binding_(impl_.get(), std::move(request)),
83 weak_factory_(this) {
84 binding_.set_connection_error_handler(
85 base::Bind(&StrongBinding::OnConnectionError, base::Unretained(this)));
86 }
87
88 ~StrongBinding() {}
89
90 void OnConnectionError() {
91 if (!connection_error_handler_.is_null())
92 connection_error_handler_.Run();
93 Close();
94 }
95
96 std::unique_ptr<Interface> impl_;
124 base::Closure connection_error_handler_; 97 base::Closure connection_error_handler_;
125 Binding<Interface> binding_; 98 Binding<Interface> binding_;
99 base::WeakPtrFactory<StrongBinding> weak_factory_;
126 100
127 DISALLOW_COPY_AND_ASSIGN(StrongBinding); 101 DISALLOW_COPY_AND_ASSIGN(StrongBinding);
128 }; 102 };
129 103
104 template <typename Interface, typename Impl>
105 StrongBindingPtr<Interface> MakeStrongBinding(
106 std::unique_ptr<Impl> impl,
107 InterfaceRequest<Interface> request) {
108 return StrongBinding<Interface>::Create(std::move(impl), std::move(request));
109 }
110
130 } // namespace mojo 111 } // namespace mojo
131 112
132 #endif // MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_H_ 113 #endif // MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_H_
OLDNEW
« no previous file with comments | « media/mojo/services/service_factory_impl.cc ('k') | mojo/public/cpp/bindings/tests/associated_interface_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698