Index: mojo/public/cpp/bindings/lib/interface_impl_internal.h |
diff --git a/mojo/public/cpp/bindings/lib/interface_impl_internal.h b/mojo/public/cpp/bindings/lib/interface_impl_internal.h |
index d94d12de0c90b01dc98de781fada535c55f5cbb0..79f59d82b29920feda90849e6a3a13f01b1f664d 100644 |
--- a/mojo/public/cpp/bindings/lib/interface_impl_internal.h |
+++ b/mojo/public/cpp/bindings/lib/interface_impl_internal.h |
@@ -31,12 +31,21 @@ class InterfaceImplState : public ErrorHandler { |
explicit InterfaceImplState(InterfaceImplBase<Interface>* instance) |
: router_(NULL), |
- proxy_(NULL) { |
+ proxy_(NULL), |
+ instance_bound_to_pipe_(false) |
+#ifndef NDEBUG |
+ , |
+ deleting_instance_due_to_error_(false) |
+#endif |
+ { |
MOJO_DCHECK(instance); |
stub_.set_sink(instance); |
} |
virtual ~InterfaceImplState() { |
+#ifndef NDEBUG |
+ MOJO_DCHECK(!instance_bound_to_pipe_ || deleting_instance_due_to_error_); |
+#endif |
delete proxy_; |
if (router_) { |
router_->set_error_handler(NULL); |
@@ -46,13 +55,15 @@ class InterfaceImplState : public ErrorHandler { |
void BindProxy( |
InterfacePtr<Interface>* ptr, |
+ bool instance_bound_to_pipe, |
const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { |
MessagePipe pipe; |
ptr->Bind(pipe.handle0.Pass(), waiter); |
- Bind(pipe.handle1.Pass(), waiter); |
+ Bind(pipe.handle1.Pass(), instance_bound_to_pipe, waiter); |
} |
void Bind(ScopedMessagePipeHandle handle, |
+ bool instance_bound_to_pipe, |
const MojoAsyncWaiter* waiter) { |
MOJO_DCHECK(!router_); |
@@ -67,6 +78,8 @@ class InterfaceImplState : public ErrorHandler { |
proxy_ = new typename Client::Proxy_(router_); |
+ instance_bound_to_pipe_ = instance_bound_to_pipe; |
+ |
instance()->OnConnectionEstablished(); |
} |
@@ -84,12 +97,27 @@ class InterfaceImplState : public ErrorHandler { |
} |
virtual void OnConnectionError() MOJO_OVERRIDE { |
+ // If the the instance is not bound to the pipe, the instance might choose |
+ // to delete itself in the OnConnectionError handler, which would in turn |
+ // delete this. Save the error behavior before invoking the error handler |
+ // so we can correctly decide what to do. |
+ bool bound = instance_bound_to_pipe_; |
instance()->OnConnectionError(); |
+ if (!bound) |
+ return; |
+#ifndef NDEBUG |
+ deleting_instance_due_to_error_ = true; |
+#endif |
+ delete instance(); |
} |
Router* router_; |
typename Client::Proxy_* proxy_; |
typename Interface::Stub_ stub_; |
+ bool instance_bound_to_pipe_; |
+#ifndef NDEBUG |
+ bool deleting_instance_due_to_error_; |
+#endif |
MOJO_DISALLOW_COPY_AND_ASSIGN(InterfaceImplState); |
}; |