Index: ipc/ipc_mojo_bootstrap.cc |
diff --git a/ipc/ipc_mojo_bootstrap.cc b/ipc/ipc_mojo_bootstrap.cc |
index 3ba136619a6bd920a3f0929284c5e4927f14f913..256f394ec0a8281f7d556fe75a936e6a88d8c7f3 100644 |
--- a/ipc/ipc_mojo_bootstrap.cc |
+++ b/ipc/ipc_mojo_bootstrap.cc |
@@ -161,7 +161,10 @@ class ChannelAssociatedGroupController |
return CreateScopedInterfaceEndpointHandle(id, true); |
} |
- void CloseEndpointHandle(mojo::InterfaceId id, bool is_local) override { |
+ void CloseEndpointHandle( |
+ mojo::InterfaceId id, |
+ bool is_local, |
+ const base::Optional<mojo::DisconnectReason>& reason) override { |
if (!mojo::IsValidInterfaceId(id)) |
return; |
@@ -182,8 +185,8 @@ class ChannelAssociatedGroupController |
MarkClosedAndMaybeRemove(endpoint); |
base::AutoUnlock unlocker(lock_); |
- if (!mojo::IsMasterInterfaceId(id)) |
- control_message_proxy_.NotifyPeerEndpointClosed(id); |
+ if (!mojo::IsMasterInterfaceId(id) || reason) |
+ control_message_proxy_.NotifyPeerEndpointClosed(id, reason); |
} |
mojo::InterfaceEndpointController* AttachEndpointClient( |
@@ -264,6 +267,15 @@ class ChannelAssociatedGroupController |
peer_closed_ = true; |
} |
+ const base::Optional<mojo::DisconnectReason>& disconnect_reason() const { |
+ return disconnect_reason_; |
+ } |
+ |
+ void set_disconnect_reason( |
+ const base::Optional<mojo::DisconnectReason>& disconnect_reason) { |
+ disconnect_reason_ = disconnect_reason; |
+ } |
+ |
base::SingleThreadTaskRunner* task_runner() const { |
return task_runner_.get(); |
} |
@@ -436,6 +448,7 @@ class ChannelAssociatedGroupController |
bool closed_ = false; |
bool peer_closed_ = false; |
+ base::Optional<mojo::DisconnectReason> disconnect_reason_; |
mojo::InterfaceEndpointClient* client_ = nullptr; |
scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
std::unique_ptr<mojo::SyncHandleWatcher> sync_watcher_; |
@@ -538,9 +551,11 @@ class ChannelAssociatedGroupController |
DCHECK(endpoint->task_runner() && endpoint->client()); |
if (endpoint->task_runner()->BelongsToCurrentThread() && !force_async) { |
mojo::InterfaceEndpointClient* client = endpoint->client(); |
+ base::Optional<mojo::DisconnectReason> reason( |
+ endpoint->disconnect_reason()); |
base::AutoUnlock unlocker(lock_); |
- client->NotifyError(); |
+ client->NotifyError(reason); |
} else { |
endpoint->task_runner()->PostTask( |
FROM_HERE, |
@@ -721,15 +736,18 @@ class ChannelAssociatedGroupController |
} |
// mojo::PipeControlMessageHandlerDelegate: |
- bool OnPeerAssociatedEndpointClosed(mojo::InterfaceId id) override { |
+ bool OnPeerAssociatedEndpointClosed( |
+ mojo::InterfaceId id, |
+ const base::Optional<mojo::DisconnectReason>& reason) override { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- if (mojo::IsMasterInterfaceId(id)) |
- return false; |
+ DCHECK(!mojo::IsMasterInterfaceId(id) || reason); |
scoped_refptr<ChannelAssociatedGroupController> keepalive(this); |
base::AutoLock locker(lock_); |
scoped_refptr<Endpoint> endpoint = FindOrInsertEndpoint(id, nullptr); |
+ if (reason) |
+ endpoint->set_disconnect_reason(reason); |
if (!endpoint->peer_closed()) { |
if (endpoint->client()) |
NotifyEndpointOfError(endpoint.get(), false /* force_async */); |
@@ -752,7 +770,7 @@ class ChannelAssociatedGroupController |
MarkClosedAndMaybeRemove(endpoint); |
} |
- control_message_proxy_.NotifyPeerEndpointClosed(id); |
+ control_message_proxy_.NotifyPeerEndpointClosed(id, base::nullopt); |
return true; |
} |