pw_rpc: Clean up comments; call MarkClosed() in MoveFrom()
- Have Call::MoveFrom() call MarkClosed() to reduce duplication.
- Set the call ID to 0 when a call is closed.
- Make the public set_on_next() function protected.
- Expand or update a few comments.
Change-Id: I0bd01fa802661b7532fe797d805e5cdf24e7f829
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/126750
Reviewed-by: Alexei Frolov <frolv@google.com>
Pigweed-Auto-Submit: Wyatt Hepler <hepler@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
diff --git a/pw_rpc/call.cc b/pw_rpc/call.cc
index 1a3f160..ed16c1f 100644
--- a/pw_rpc/call.cc
+++ b/pw_rpc/call.cc
@@ -102,8 +102,7 @@
on_next_ = std::move(other.on_next_);
// Mark the other call inactive, unregister it, and register this one.
- other.rpc_state_ = kInactive;
- other.client_stream_state_ = kClientStreamInactive;
+ other.MarkClosed();
endpoint().UnregisterCall(other);
endpoint().RegisterUniqueCall(*this);
diff --git a/pw_rpc/call_test.cc b/pw_rpc/call_test.cc
index 49101e8..8971658 100644
--- a/pw_rpc/call_test.cc
+++ b/pw_rpc/call_test.cc
@@ -293,6 +293,32 @@
EXPECT_EQ(calls, 2 + PW_RPC_CLIENT_STREAM_END_CALLBACK);
}
+TEST_F(ServerReaderWriterTest, Move_ClearsCallAndChannelId) {
+ rpc_lock().lock();
+ reader_writer_.set_id(999);
+ EXPECT_NE(reader_writer_.channel_id_locked(), 0u);
+ rpc_lock().unlock();
+
+ FakeServerReaderWriter destination(std::move(reader_writer_));
+
+ LockGuard lock(rpc_lock());
+ EXPECT_EQ(reader_writer_.id(), 0u);
+ EXPECT_EQ(reader_writer_.channel_id_locked(), 0u);
+}
+
+TEST_F(ServerReaderWriterTest, Close_ClearsCallAndChannelId) {
+ rpc_lock().lock();
+ reader_writer_.set_id(999);
+ EXPECT_NE(reader_writer_.channel_id_locked(), 0u);
+ rpc_lock().unlock();
+
+ EXPECT_EQ(OkStatus(), reader_writer_.Finish());
+
+ LockGuard lock(rpc_lock());
+ EXPECT_EQ(reader_writer_.id(), 0u);
+ EXPECT_EQ(reader_writer_.channel_id_locked(), 0u);
+}
+
} // namespace
} // namespace internal
} // namespace pw::rpc
diff --git a/pw_rpc/public/pw_rpc/internal/call.h b/pw_rpc/public/pw_rpc/internal/call.h
index 7e6a677..2a3b79a 100644
--- a/pw_rpc/public/pw_rpc/internal/call.h
+++ b/pw_rpc/public/pw_rpc/internal/call.h
@@ -129,16 +129,21 @@
void set_id(uint32_t id) PW_EXCLUSIVE_LOCKS_REQUIRED(rpc_lock()) { id_ = id; }
+ // Public function for accessing the channel ID of this call. Set to 0 when
+ // the call is closed.
uint32_t channel_id() const PW_LOCKS_EXCLUDED(rpc_lock()) {
LockGuard lock(rpc_lock());
return channel_id_locked();
}
+
uint32_t channel_id_locked() const PW_EXCLUSIVE_LOCKS_REQUIRED(rpc_lock()) {
return channel_id_;
}
+
uint32_t service_id() const PW_EXCLUSIVE_LOCKS_REQUIRED(rpc_lock()) {
return service_id_;
}
+
uint32_t method_id() const PW_EXCLUSIVE_LOCKS_REQUIRED(rpc_lock()) {
return method_id_;
}
@@ -173,13 +178,13 @@
pwpb::PacketType::SERVER_ERROR, {}, error);
}
- // Public call that ends the client stream for a client call.
+ // Public function that ends the client stream for a client call.
Status CloseClientStream() PW_LOCKS_EXCLUDED(rpc_lock()) {
LockGuard lock(rpc_lock());
return CloseClientStreamLocked();
}
- // Internal call that closes the client stream.
+ // Internal function that closes the client stream.
Status CloseClientStreamLocked() PW_EXCLUSIVE_LOCKS_REQUIRED(rpc_lock()) {
client_stream_state_ = kClientStreamInactive;
return SendPacket(pwpb::PacketType::CLIENT_STREAM_END, {}, {});
@@ -198,8 +203,6 @@
// is closed.
void SendInitialClientRequest(ConstByteSpan payload)
PW_UNLOCK_FUNCTION(rpc_lock()) {
- // TODO(b/234876851): Ensure the call object is locked before releasing the
- // RPC mutex.
if (const Status status = SendPacket(pwpb::PacketType::REQUEST, payload);
!status.ok()) {
HandleError(status);
@@ -233,9 +236,8 @@
// service unregistered). Does NOT unregister the call! The calls must be
// removed when iterating over the list in the endpoint.
void Abort() PW_EXCLUSIVE_LOCKS_REQUIRED(rpc_lock()) {
- // Locking here is problematic because CallOnError releases rpc_lock().
- //
- // b/234876851 must be addressed before the locking here can be cleaned up.
+ // TODO(b/260922913): Locking here is problematic because CallOnError
+ // releases rpc_lock().
MarkClosed();
CallOnError(Status::Aborted());
@@ -256,14 +258,6 @@
return client_stream_state_ == kClientStreamActive;
}
- // Keep this public so the Nanopb implementation can set it from a helper
- // function.
- void set_on_next(Function<void(ConstByteSpan)>&& on_next)
- PW_LOCKS_EXCLUDED(rpc_lock()) {
- LockGuard lock(rpc_lock());
- set_on_next_locked(std::move(on_next));
- }
-
protected:
// Creates an inactive Call.
constexpr Call()
@@ -294,17 +288,27 @@
return *endpoint_;
}
+ // Public function that sets the on_next function in the raw API.
+ void set_on_next(Function<void(ConstByteSpan)>&& on_next)
+ PW_LOCKS_EXCLUDED(rpc_lock()) {
+ LockGuard lock(rpc_lock());
+ set_on_next_locked(std::move(on_next));
+ }
+
+ // Internal function that sets on_next.
void set_on_next_locked(Function<void(ConstByteSpan)>&& on_next)
PW_EXCLUSIVE_LOCKS_REQUIRED(rpc_lock()) {
on_next_ = std::move(on_next);
}
+ // Public function that sets the on_error callback.
void set_on_error(Function<void(Status)>&& on_error)
PW_LOCKS_EXCLUDED(rpc_lock()) {
LockGuard lock(rpc_lock());
set_on_error_locked(std::move(on_error));
}
+ // Internal function that sets on_error.
void set_on_error_locked(Function<void(Status)>&& on_error)
PW_EXCLUSIVE_LOCKS_REQUIRED(rpc_lock()) {
on_error_ = std::move(on_error);
@@ -320,7 +324,7 @@
pwpb::PacketType::RESPONSE, {}, status);
}
- // Cancels an RPC. For client calls only.
+ // Cancels an RPC. Public function for client calls only.
Status Cancel() PW_LOCKS_EXCLUDED(rpc_lock()) {
LockGuard lock(rpc_lock());
return CloseAndSendFinalPacketLocked(
@@ -360,6 +364,7 @@
void MarkClosed() PW_EXCLUSIVE_LOCKS_REQUIRED(rpc_lock()) {
channel_id_ = Channel::kUnassignedChannelId;
+ id_ = 0;
rpc_state_ = kInactive;
client_stream_state_ = kClientStreamInactive;
}
diff --git a/pw_rpc/public/pw_rpc/internal/client_call.h b/pw_rpc/public/pw_rpc/internal/client_call.h
index db1cd76..48af2d2 100644
--- a/pw_rpc/public/pw_rpc/internal/client_call.h
+++ b/pw_rpc/public/pw_rpc/internal/client_call.h
@@ -57,8 +57,7 @@
CallProperties properties) PW_EXCLUSIVE_LOCKS_REQUIRED(rpc_lock())
: Call(client, channel_id, service_id, method_id, properties) {}
- // Sends CLIENT_STREAM_END if applicable, releases any held payload buffer,
- // and marks the call as closed.
+ // Sends CLIENT_STREAM_END if applicable and marks the call as closed.
void CloseClientCall() PW_EXCLUSIVE_LOCKS_REQUIRED(rpc_lock());
void MoveClientCallFrom(ClientCall& other)
diff --git a/pw_rpc/pw_rpc_private/fake_server_reader_writer.h b/pw_rpc/pw_rpc_private/fake_server_reader_writer.h
index b5222d4..89c5d91 100644
--- a/pw_rpc/pw_rpc_private/fake_server_reader_writer.h
+++ b/pw_rpc/pw_rpc_private/fake_server_reader_writer.h
@@ -67,6 +67,9 @@
// Expose a few additional methods for test use.
ServerCall& as_server_call() { return *this; }
+ using Call::channel_id_locked;
+ using Call::id;
+ using Call::set_id;
};
class FakeServerWriter : private FakeServerReaderWriter {