Skip to content

Commit

Permalink
pw_rpc: Guard the Nanopb and pwpb on_completed callbacks
Browse files Browse the repository at this point in the history
Move the on_completed_ callbacks for Nanopb and pwpb RPCs to a local
variable while the lock is held.

Bug: b/234876851
Change-Id: I5a2b16cdb658925ba1985f5700821483d2deab23
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/125230
Pigweed-Auto-Submit: Wyatt Hepler <[email protected]>
Commit-Queue: Auto-Submit <[email protected]>
Reviewed-by: Alexei Frolov <[email protected]>
  • Loading branch information
255 authored and CQ Bot Account committed Dec 23, 2022
1 parent c4a481b commit 580e279
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 8 deletions.
2 changes: 0 additions & 2 deletions pw_rpc/nanopb/method_union_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
namespace pw::rpc::internal {
namespace {

using std::byte;

template <typename Implementation>
class FakeGeneratedService : public Service {
public:
Expand Down
11 changes: 8 additions & 3 deletions pw_rpc/nanopb/public/pw_rpc/nanopb/client_reader_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,14 @@ class NanopbUnaryResponseClientCall : public UnaryResponseClientCall {

UnaryResponseClientCall::set_on_completed_locked(
[this](ConstByteSpan payload, Status status) {
if (nanopb_on_completed_) {
rpc_lock().lock();
auto nanopb_on_completed_local = std::move(nanopb_on_completed_);
rpc_lock().unlock();

if (nanopb_on_completed_local) {
Response response_struct{};
if (serde_->DecodeResponse(payload, &response_struct)) {
nanopb_on_completed_(response_struct, status);
nanopb_on_completed_local(response_struct, status);
} else {
// TODO(hepler): This should send a DATA_LOSS error and call the
// error callback.
Expand All @@ -118,7 +122,8 @@ class NanopbUnaryResponseClientCall : public UnaryResponseClientCall {
}

const NanopbMethodSerde* serde_;
Function<void(const Response&, Status)> nanopb_on_completed_;
Function<void(const Response&, Status)> nanopb_on_completed_
PW_GUARDED_BY(rpc_lock());
};

// Base class for server and bidirectional streaming calls.
Expand Down
11 changes: 8 additions & 3 deletions pw_rpc/pwpb/public/pw_rpc/pwpb/client_reader_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,16 @@ class PwpbUnaryResponseClientCall : public UnaryResponseClientCall {

UnaryResponseClientCall::set_on_completed_locked(
[this](ConstByteSpan payload, Status status) {
if (pwpb_on_completed_) {
rpc_lock().lock();
auto pwpb_on_completed_local = std::move(pwpb_on_completed_);
rpc_lock().unlock();

if (pwpb_on_completed_local) {
Response response{};
const Status decode_status =
serde().DecodeResponse(payload, response);
if (decode_status.ok()) {
pwpb_on_completed_(response, status);
pwpb_on_completed_local(response, status);
} else {
rpc_lock().lock();
CallOnError(Status::DataLoss());
Expand All @@ -151,7 +155,8 @@ class PwpbUnaryResponseClientCall : public UnaryResponseClientCall {
}

const PwpbMethodSerde* serde_;
Function<void(const Response&, Status)> pwpb_on_completed_;
Function<void(const Response&, Status)> pwpb_on_completed_
PW_GUARDED_BY(rpc_lock());
};

// internal::PwpbStreamResponseClientCall extends
Expand Down

0 comments on commit 580e279

Please sign in to comment.