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

Unified Diff: mojo/public/cpp/bindings/strong_binding.h

Issue 2515873003: Mojo C++ Bindings: Introduce mojo::SupportsStrongBinding
Patch Set: . Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | mojo/public/cpp/bindings/tests/associated_interface_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/public/cpp/bindings/strong_binding.h
diff --git a/mojo/public/cpp/bindings/strong_binding.h b/mojo/public/cpp/bindings/strong_binding.h
index 99d10956c6f040e2835ff9f705f713f38486a641..f2efeb293da39ca1f739429e8644718cda50bb88 100644
--- a/mojo/public/cpp/bindings/strong_binding.h
+++ b/mojo/public/cpp/bindings/strong_binding.h
@@ -31,6 +31,33 @@ class StrongBinding;
template <typename Interface>
using StrongBindingPtr = base::WeakPtr<StrongBinding<Interface>>;
+// Interface implementations must inherit this in order to support being
+// strongly bound to a message pipe.
+template <typename Interface>
+class SupportsStrongBinding : public Interface {
+ public:
+ virtual ~SupportsStrongBinding() {
+ if (binding_) {
+ // Dissociate |this| from the binding before closing it.
+ ignore_result(binding_->Release().release());
+
+ // Deletes |*binding_|.
+ binding_->Close();
+ }
+ }
+
+ private:
+ friend class StrongBinding<Interface>;
+
+ void set_binding(const StrongBindingPtr<Interface>& binding) {
+ binding_ = binding;
+ }
+
+ StrongBindingPtr<Interface> binding_;
+
+ DISALLOW_COPY_AND_ASSIGN(SupportsStrongBinding);
+};
+
// This connects an interface implementation strongly to a pipe. When a
// connection error is detected the implementation is deleted.
//
@@ -46,12 +73,19 @@ class StrongBinding {
// Create a new StrongBinding instance. The instance owns itself, cleaning up
// only in the event of a pipe connection error. Returns a WeakPtr to the new
// StrongBinding instance.
+ //
+ // Note that it's also safe for |impl| to delete itself at any time.
+ template <typename Impl>
static StrongBindingPtr<Interface> Create(
dcheng 2016/11/21 10:42:12 Would this still need to return a weak pointer to
- std::unique_ptr<Interface> impl,
+ std::unique_ptr<Impl> impl,
InterfaceRequest<Interface> request) {
+ SupportsStrongBinding<Interface>* raw_impl = impl.get();
StrongBinding* binding =
new StrongBinding(std::move(impl), std::move(request));
- return binding->weak_factory_.GetWeakPtr();
+ StrongBindingPtr<Interface> weak_binding =
+ binding->weak_factory_.GetWeakPtr();
+ raw_impl->set_binding(weak_binding);
+ return weak_binding;
}
// Note: The error handler must not delete the interface implementation.
@@ -74,6 +108,10 @@ class StrongBinding {
// Forces the binding to close. This destroys the StrongBinding instance.
void Close() { delete this; }
+ std::unique_ptr<Interface> Release() WARN_UNUSED_RESULT {
+ return std::move(impl_);
+ }
+
Interface* impl() { return impl_.get(); }
// Exposed for testing, should not generally be used.
@@ -95,7 +133,12 @@ class StrongBinding {
base::Bind(&StrongBinding::OnConnectionError, base::Unretained(this)));
}
- ~StrongBinding() {}
+ ~StrongBinding() {
+ // Ensure any WeakPtrs are invalidated *before* |impl_| is destroyed,
+ // otherwise the |impl_|'s destructor will attempt to reenter this object to
+ // Close it.
+ weak_factory_.InvalidateWeakPtrs();
+ }
void OnConnectionError(uint32_t custom_reason,
const std::string& description) {
@@ -115,6 +158,7 @@ class StrongBinding {
DISALLOW_COPY_AND_ASSIGN(StrongBinding);
};
+// Convenient helper wrapping StrongBinding::Create. See above.
template <typename Interface, typename Impl>
StrongBindingPtr<Interface> MakeStrongBinding(
std::unique_ptr<Impl> impl,
« no previous file with comments | « no previous file | mojo/public/cpp/bindings/tests/associated_interface_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698