Copilot commented on code in PR #3573:
URL: https://github.com/apache/brpc/pull/3573#discussion_r4142435720


##########
src/brpc/ubshm/ub_endpoint.cpp:
##########
@@ -636,10 +667,13 @@ void* UBShmEndpoint::ProcessHandshakeAtServer(void* arg) {
         remote_extension.Deserialize(data);
         HelloFormatExtension local_extension = {
             HelloFormatExtension::WIRE_SIZE, UBR_DATA_FORMAT_NONE};
-        if (remote_extension.extension_len == HelloFormatExtension::WIRE_SIZE 
&&
-            remote_extension.format_id == UBR_DATA_FORMAT_LEGACY_64) {
-            local_extension.format_id = UBR_DATA_FORMAT_LEGACY_64;
-            selected_format = UBR_DATA_FORMAT_LEGACY_64;
+        if (remote_extension.extension_len == HelloFormatExtension::WIRE_SIZE) 
{
+            selected_format =
+                SelectDataFormat(local_format, remote_extension.format_id);
+        }
+        if (selected_format != UBR_DATA_FORMAT_NONE) {
+            local_extension.format_id =
+                static_cast<uint16_t>(selected_format);
         } else {
             ub_transport->_ub_state = UBShmTransport::UB_OFF;

Review Comment:
   When a V3 peer proposes `LEGACY_64` to an IPC server, 
`AllocateServerResources()` has already mapped both queues, registered the 
poller, started timers, and marked the `IPC_V2` transaction connected. Setting 
`UB_OFF` here leaves those resources active for a TCP-only connection. The 
heartbeat can eventually release the pooled transaction while this endpoint's 
ring and poller still hold its pointer; a reused slot could then be accessed as 
another connection. After completing the fallback handshake, abort the 
provisional transaction: unregister the poller, cancel its timers, release both 
mappings and the manager slot, and detach the ring without waiting for peer 
UBRing participation.



##########
src/brpc/ubshm/ub_ring.cpp:
##########
@@ -896,6 +1209,22 @@ RETURN_CODE UBRing::UbrMapRemoteShmAddTimer(SHM 
*local_trx_shm, const char *loca
         LOG(ERROR) << "Connect Trx map shared memory failed, remote shm=" << 
remote_trx_shm.name;
         return rc;
     }
+    if (format == UBR_DATA_FORMAT_LEGACY_64) {
+        InitializeClientRemoteLegacyFormat();
+        rc = InitializeClientLocalLegacyFormat();
+        if (LIKELY(rc == UBRING_OK)) {
+            InitializeClientLegacyFormat();
+        }
+    } else if (format == UBR_DATA_FORMAT_IPC_V2) {
+        rc = UbrPrepareIpcV2Format() == 0 ? UBRING_OK : UBRING_ERR;
+    } else {
+        rc = UBRING_ERR;
+    }
+    if (UNLIKELY(rc != UBRING_OK)) {
+        LOG(ERROR) << "Initialize client data format failed, local_name="
+                   << local_name << ", format=" << format;
+        return rc;

Review Comment:
   If the mapped peer queue fails `UbrPrepareIpcV2Format()` (for example, it 
has fewer than two aligned slots), this return leaves the client's local and 
remote shared-memory mappings and manager transaction allocated. No timer has 
started, so a TCP fallback on a long-lived socket keeps those resources 
indefinitely rather than reaching heartbeat cleanup. On this initialization 
failure, abort setup and release both mappings and the transaction (and remove 
the provisional poller registration) before sending ACK=0; do not use the 
normal close path, which waits for a connected peer.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to