Fix off-thread sync waits on SharedRemote
SharedRemote allows for sync waits sync waits from any thread, but
the implementation is kind of cheesy and does not properly coordinate
with the underlying endpoint to ensure that the wait is awoken in
every case where it should be. That can lead to deadlocks in various
edge cases.
This change fixes the issue by making MultiplexRouter and
InterfaceEndpointClient aware of off-thread sync waits and allowing
them to explicitly wake up when a reply to a specific off-thread sync
message arrives.
Bug: 1196476
Change-Id: If5145784b0bdb976d896f7fbf7d9c2f4fe126abc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2826525
Commit-Queue: Ken Rockot <[email protected]>
Reviewed-by: Robert Sesek <[email protected]>
Cr-Commit-Position: refs/heads/master@{#873795}
diff --git a/ipc/ipc_mojo_bootstrap.cc b/ipc/ipc_mojo_bootstrap.cc
index 1fc3b95..ff8673b 100644
--- a/ipc/ipc_mojo_bootstrap.cc
+++ b/ipc/ipc_mojo_bootstrap.cc
@@ -582,6 +582,8 @@
return sync_watcher_->SyncWatch(should_stop);
}
+ void RegisterExternalSyncWaiter(uint64_t request_id) override {}
+
private:
friend class base::RefCountedThreadSafe<Endpoint>;
@@ -849,7 +851,8 @@
return control_message_handler_.Accept(message);
mojo::InterfaceId id = message->interface_id();
- DCHECK(mojo::IsValidInterfaceId(id));
+ if (!mojo::IsValidInterfaceId(id))
+ return false;
base::ReleasableAutoLock locker(&lock_);
Endpoint* endpoint = FindEndpoint(id);
@@ -902,11 +905,6 @@
return true;
}
- // We do not expect to receive sync responses on the primary endpoint
- // thread. If it's happening, it's a bug.
- DCHECK(!message->has_flag(mojo::Message::kFlagIsSync) ||
- !message->has_flag(mojo::Message::kFlagIsResponse));
-
locker.Release();
// It's safe to access |client| here without holding a lock, because this
// code runs on a proxy thread and |client| can't be destroyed from any