| Index: mojo/public/cpp/bindings/lib/multiplex_router.cc
|
| diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.cc b/mojo/public/cpp/bindings/lib/multiplex_router.cc
|
| index 14ea64740756a9377829c23512a2eb1b7b457603..1681b7fa2d0a215ba59c3ac777ec6130bebecbb1 100644
|
| --- a/mojo/public/cpp/bindings/lib/multiplex_router.cc
|
| +++ b/mojo/public/cpp/bindings/lib/multiplex_router.cc
|
| @@ -61,6 +61,15 @@ class MultiplexRouter::InterfaceEndpoint
|
| peer_closed_ = true;
|
| }
|
|
|
| + const base::Optional<DisconnectReason>& disconnect_reason() const {
|
| + return disconnect_reason_;
|
| + }
|
| + void set_disconnect_reason(
|
| + const base::Optional<DisconnectReason>& disconnect_reason) {
|
| + router_->AssertLockAcquired();
|
| + disconnect_reason_ = disconnect_reason;
|
| + }
|
| +
|
| base::SingleThreadTaskRunner* task_runner() const {
|
| return task_runner_.get();
|
| }
|
| @@ -228,6 +237,8 @@ class MultiplexRouter::InterfaceEndpoint
|
| // Whether the peer endpoint has been closed.
|
| bool peer_closed_;
|
|
|
| + base::Optional<DisconnectReason> disconnect_reason_;
|
| +
|
| // The task runner on which |client_|'s methods can be called.
|
| scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
|
| // Not owned. It is null if no client is attached to this endpoint.
|
| @@ -399,7 +410,10 @@ ScopedInterfaceEndpointHandle MultiplexRouter::CreateLocalEndpointHandle(
|
| return CreateScopedInterfaceEndpointHandle(id, true);
|
| }
|
|
|
| -void MultiplexRouter::CloseEndpointHandle(InterfaceId id, bool is_local) {
|
| +void MultiplexRouter::CloseEndpointHandle(
|
| + InterfaceId id,
|
| + bool is_local,
|
| + const base::Optional<DisconnectReason>& reason) {
|
| if (!IsValidInterfaceId(id))
|
| return;
|
|
|
| @@ -422,9 +436,9 @@ void MultiplexRouter::CloseEndpointHandle(InterfaceId id, bool is_local) {
|
| DCHECK(!endpoint->closed());
|
| UpdateEndpointStateMayRemove(endpoint, ENDPOINT_CLOSED);
|
|
|
| - if (!IsMasterInterfaceId(id)) {
|
| + if (!IsMasterInterfaceId(id) || reason) {
|
| MayAutoUnlock unlocker(lock_.get());
|
| - control_message_proxy_.NotifyPeerEndpointClosed(id);
|
| + control_message_proxy_.NotifyPeerEndpointClosed(id, reason);
|
| }
|
|
|
| ProcessTasks(NO_DIRECT_CLIENT_CALLS, nullptr);
|
| @@ -572,14 +586,18 @@ bool MultiplexRouter::Accept(Message* message) {
|
| return true;
|
| }
|
|
|
| -bool MultiplexRouter::OnPeerAssociatedEndpointClosed(InterfaceId id) {
|
| +bool MultiplexRouter::OnPeerAssociatedEndpointClosed(
|
| + InterfaceId id,
|
| + const base::Optional<DisconnectReason>& reason) {
|
| AssertLockAcquired();
|
|
|
| - if (IsMasterInterfaceId(id))
|
| - return false;
|
| + DCHECK(!IsMasterInterfaceId(id) || reason);
|
|
|
| InterfaceEndpoint* endpoint = FindOrInsertEndpoint(id, nullptr);
|
|
|
| + if (reason)
|
| + endpoint->set_disconnect_reason(reason);
|
| +
|
| // It is possible that this endpoint has been set as peer closed. That is
|
| // because when the message pipe is closed, all the endpoints are updated with
|
| // PEER_ENDPOINT_CLOSED. We continue to process remaining tasks in the queue,
|
| @@ -608,7 +626,7 @@ bool MultiplexRouter::OnAssociatedEndpointClosedBeforeSent(InterfaceId id) {
|
| UpdateEndpointStateMayRemove(endpoint, ENDPOINT_CLOSED);
|
|
|
| MayAutoUnlock unlocker(lock_.get());
|
| - control_message_proxy_.NotifyPeerEndpointClosed(id);
|
| + control_message_proxy_.NotifyPeerEndpointClosed(id, base::nullopt);
|
|
|
| return true;
|
| }
|
| @@ -739,6 +757,9 @@ bool MultiplexRouter::ProcessNotifyErrorTask(
|
| DCHECK(endpoint->task_runner()->BelongsToCurrentThread());
|
|
|
| InterfaceEndpointClient* client = endpoint->client();
|
| + base::Optional<DisconnectReason> disconnect_reason(
|
| + endpoint->disconnect_reason());
|
| +
|
| {
|
| // We must unlock before calling into |client| because it may call this
|
| // object within NotifyError(). Holding the lock will lead to deadlock.
|
| @@ -746,7 +767,7 @@ bool MultiplexRouter::ProcessNotifyErrorTask(
|
| // It is safe to call into |client| without the lock. Because |client| is
|
| // always accessed on the same thread, including DetachEndpointClient().
|
| MayAutoUnlock unlocker(lock_.get());
|
| - client->NotifyError();
|
| + client->NotifyError(disconnect_reason);
|
| }
|
| return true;
|
| }
|
| @@ -795,7 +816,7 @@ bool MultiplexRouter::ProcessIncomingMessage(
|
| // messages for the master endpoint, we will get here.
|
| MayAutoUnlock unlocker(lock_.get());
|
| if (!IsMasterInterfaceId(id))
|
| - control_message_proxy_.NotifyPeerEndpointClosed(id);
|
| + control_message_proxy_.NotifyPeerEndpointClosed(id, base::nullopt);
|
| return true;
|
| }
|
|
|
|
|