pw_rpc: Do not hold locks while calling user code
- Add annotations and update code to ensure that rpc_lock() is not held
while calling user-provided ChannelOutput functions.
- Flag a few places in the code with TODOs to fix thread safety issues.
Change-Id: I8040bbdddad4d0b1f266e7214aea5e386c183aed
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/78120
Pigweed-Auto-Submit: Wyatt Hepler <hepler@google.com>
Reviewed-by: Alexei Frolov <frolv@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
diff --git a/pw_rpc/client.cc b/pw_rpc/client.cc
index f0f8181..424361a 100644
--- a/pw_rpc/client.cc
+++ b/pw_rpc/client.cc
@@ -50,6 +50,8 @@
}
if (call == nullptr || call->id() != packet.call_id()) {
+ internal::rpc_lock().unlock();
+
// The call for the packet does not exist. If the packet is a server stream
// message, notify the server so that it can kill the stream. Otherwise,
// silently drop the packet (as it would terminate the RPC anyway).
@@ -57,8 +59,6 @@
channel->Send(Packet::ClientError(packet, Status::FailedPrecondition()))
.IgnoreError();
PW_LOG_WARN("RPC client received stream message for an unknown call");
- } else {
- internal::rpc_lock().unlock();
}
return OkStatus(); // OK since the packet was handled
}
@@ -83,7 +83,6 @@
} else {
call->HandleError(Status::InvalidArgument());
PW_LOG_DEBUG("Received SERVER_STREAM for RPC without a server stream");
- internal::rpc_lock().lock();
// Report the error to the server so it can abort the RPC.
channel->Send(Packet::ClientError(packet, Status::InvalidArgument()))
.IgnoreError(); // Errors are logged in Channel::Send.