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 2f547bc2e52cf81ae0b7b6315b17e52278bdcab2..f05461840b271783a323e6d90dfd953fe75fcecf 100644 |
--- a/mojo/public/cpp/bindings/lib/multiplex_router.cc |
+++ b/mojo/public/cpp/bindings/lib/multiplex_router.cc |
@@ -526,11 +526,18 @@ bool MultiplexRouter::OnPeerAssociatedEndpointClosed(InterfaceId id) { |
return false; |
InterfaceEndpoint* endpoint = FindOrInsertEndpoint(id, nullptr); |
- DCHECK(!endpoint->peer_closed()); |
- if (endpoint->client()) |
- tasks_.push_back(Task::CreateNotifyErrorTask(endpoint)); |
- UpdateEndpointStateMayRemove(endpoint, PEER_ENDPOINT_CLOSED); |
+ // 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, |
+ // as long as there are refs keeping the router alive. If there is a |
+ // PeerAssociatedEndpointClosedEvent control message in the queue, we will get |
+ // here and see that the endpoint has been marked as peer closed. |
+ if (!endpoint->peer_closed()) { |
+ if (endpoint->client()) |
+ tasks_.push_back(Task::CreateNotifyErrorTask(endpoint)); |
+ UpdateEndpointStateMayRemove(endpoint, PEER_ENDPOINT_CLOSED); |
+ } |
// No need to trigger a ProcessTasks() because it is already on the stack. |