pw_rpc: Properly clean up ServerWriters

- Finish a ServerWriter before moving into it.
- Remove and re-register a ServerWriter when it is moved.
- Finish all ServerWriters when destructing a Server.

Change-Id: I8e2cb7270e1eb2f52c40cb418190a071131c89ca
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/13760
Reviewed-by: Alexei Frolov <frolv@google.com>
Commit-Queue: Wyatt Hepler <hepler@google.com>
diff --git a/pw_rpc/base_server_writer.cc b/pw_rpc/base_server_writer.cc
index 1e23fc8..31da1d2 100644
--- a/pw_rpc/base_server_writer.cc
+++ b/pw_rpc/base_server_writer.cc
@@ -26,11 +26,20 @@
 }
 
 BaseServerWriter& BaseServerWriter::operator=(BaseServerWriter&& other) {
+  Finish();
+
+  state_ = other.state_;
+
+  if (other.open()) {
+    other.call_.server().RemoveWriter(other);
+    other.state_ = kClosed;
+
+    other.call_.server().RegisterWriter(*this);
+  }
+
   call_ = std::move(other.call_);
   response_ = std::move(other.response_);
-  state_ = std::move(other.state_);
 
-  other.state_ = kClosed;
   return *this;
 }
 
diff --git a/pw_rpc/public/pw_rpc/server.h b/pw_rpc/public/pw_rpc/server.h
index c8b0476..5b439a1 100644
--- a/pw_rpc/public/pw_rpc/server.h
+++ b/pw_rpc/public/pw_rpc/server.h
@@ -30,6 +30,8 @@
       : channels_(static_cast<internal::Channel*>(channels.data()),
                   channels.size()) {}
 
+  ~Server();
+
   // Registers a service with the server. This should not be called directly
   // with an internal::Service; instead, use a generated class which inherits
   // from it.
diff --git a/pw_rpc/server.cc b/pw_rpc/server.cc
index 7f20a36..20afc77 100644
--- a/pw_rpc/server.cc
+++ b/pw_rpc/server.cc
@@ -29,6 +29,14 @@
 using internal::Packet;
 using internal::PacketType;
 
+Server::~Server() {
+  // Since the writers remove themselves from the server in Finish(), remove the
+  // first writer until no writers remain.
+  while (!writers_.empty()) {
+    writers_.front().Finish();
+  }
+}
+
 void Server::ProcessPacket(std::span<const byte> data,
                            ChannelOutput& interface) {
   Packet packet = Packet::FromBuffer(data);