1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
// Copyright 2014 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 MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_H_
#define MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_H_
#include <assert.h>
#include <utility>
#include "mojo/public/c/environment/async_waiter.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/callback.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/bindings/lib/filter_chain.h"
#include "mojo/public/cpp/bindings/lib/message_header_validator.h"
#include "mojo/public/cpp/bindings/lib/router.h"
#include "mojo/public/cpp/system/core.h"
namespace mojo {
// This connects an interface implementation strongly to a pipe. When a
// connection error is detected the implementation is deleted. Deleting the
// connector also closes the pipe.
//
// Example of an implementation that is always bound strongly to a pipe
//
// class StronglyBound : public Foo {
// public:
// explicit StronglyBound(InterfaceRequest<Foo> request)
// : binding_(this, request.Pass()) {}
//
// // Foo implementation here
//
// private:
// StrongBinding<Foo> binding_;
// };
//
// class MyFooFactory : public InterfaceFactory<Foo> {
// public:
// void Create(..., InterfaceRequest<Foo> request) override {
// new StronglyBound(request.Pass()); // The binding now owns the
// // instance of StronglyBound.
// }
// };
//
// This class is thread hostile once it is bound to a message pipe. Until it is
// bound, it may be bound or destroyed on any thread.
template <typename Interface>
class StrongBinding {
MOJO_MOVE_ONLY_TYPE(StrongBinding)
public:
explicit StrongBinding(Interface* impl) : binding_(impl) {}
StrongBinding(
Interface* impl,
ScopedMessagePipeHandle handle,
const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter())
: StrongBinding(impl) {
Bind(std::move(handle), waiter);
}
StrongBinding(
Interface* impl,
InterfacePtr<Interface>* ptr,
const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter())
: StrongBinding(impl) {
Bind(ptr, waiter);
}
StrongBinding(
Interface* impl,
InterfaceRequest<Interface> request,
const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter())
: StrongBinding(impl) {
Bind(std::move(request), waiter);
}
~StrongBinding() {}
void Bind(
ScopedMessagePipeHandle handle,
const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
assert(!binding_.is_bound());
binding_.Bind(std::move(handle), waiter);
binding_.set_connection_error_handler([this]() { OnConnectionError(); });
}
void Bind(
InterfacePtr<Interface>* ptr,
const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
assert(!binding_.is_bound());
binding_.Bind(ptr, waiter);
binding_.set_connection_error_handler([this]() { OnConnectionError(); });
}
void Bind(
InterfaceRequest<Interface> request,
const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
assert(!binding_.is_bound());
binding_.Bind(std::move(request), waiter);
binding_.set_connection_error_handler([this]() { OnConnectionError(); });
}
bool WaitForIncomingMethodCall() {
return binding_.WaitForIncomingMethodCall();
}
// Note: The error handler must not delete the interface implementation.
//
// This method may only be called after this StrongBinding has been bound to a
// message pipe.
void set_connection_error_handler(const Closure& error_handler) {
assert(binding_.is_bound());
connection_error_handler_ = error_handler;
}
Interface* impl() { return binding_.impl(); }
// Exposed for testing, should not generally be used.
internal::Router* internal_router() { return binding_.internal_router(); }
void OnConnectionError() {
connection_error_handler_.Run();
delete binding_.impl();
}
private:
Closure connection_error_handler_;
Binding<Interface> binding_;
};
} // namespace mojo
#endif // MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_H_
|