|
| 1 | +From 061e86519f587308d44e424e02e6b6b208ddafe4 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Jerome Soumagne <jerome.soumagne@hpe.com> |
| 3 | +Date: Mon, 20 Jul 2026 17:14:52 -0500 |
| 4 | +Subject: [PATCH] HG core: fix handling of canceled event on send unexpected |
| 5 | + |
| 6 | +In rare cases, the underlying provider could return a canceled event |
| 7 | +without explicit user cancelation, which would lead to a lingering |
| 8 | +recv not canceled (since CANCELED is handled separately from other |
| 9 | +error codes). This could have in turn led to a hang until explicit |
| 10 | +cancelation was made. |
| 11 | +--- |
| 12 | + src/mercury_core.c | 48 ++++++++++++++++++++++++++-------------------- |
| 13 | + 1 file changed, 27 insertions(+), 21 deletions(-) |
| 14 | + |
| 15 | +diff --git a/src/mercury_core.c b/src/mercury_core.c |
| 16 | +index 06404586..eb7d2803 100644 |
| 17 | +--- a/src/mercury_core.c |
| 18 | ++++ b/src/mercury_core.c |
| 19 | +@@ -4433,30 +4433,36 @@ hg_core_send_input_cb(const struct na_cb_info *callback_info) |
| 20 | + |
| 21 | + if (callback_info->ret == NA_SUCCESS) { |
| 22 | + /* Nothing */ |
| 23 | +- } else if (callback_info->ret == NA_CANCELED) { |
| 24 | +- HG_CHECK_SUBSYS_WARNING(rpc, |
| 25 | +- hg_atomic_get32(&hg_core_handle->status) & HG_CORE_OP_COMPLETED, |
| 26 | +- "Operation was completed"); |
| 27 | +- HG_LOG_SUBSYS_DEBUG( |
| 28 | +- rpc, "NA_CANCELED event on handle %p", (void *) hg_core_handle); |
| 29 | +- |
| 30 | +- hg_atomic_cas32(&hg_core_handle->ret_status, (int32_t) HG_SUCCESS, |
| 31 | +- (int32_t) HG_CANCELED); |
| 32 | +- } else { /* All other errors */ |
| 33 | +- char addr_buf[HG_CORE_ADDR_MAX_SIZE]; |
| 34 | +- size_t addr_buf_size = sizeof(addr_buf); |
| 35 | ++ } else { |
| 36 | + int32_t status; |
| 37 | + |
| 38 | +- /* Mark handle as errored */ |
| 39 | +- status = hg_atomic_or32(&hg_core_handle->status, HG_CORE_OP_ERRORED); |
| 40 | ++ if (callback_info->ret == NA_CANCELED) { |
| 41 | ++ status = hg_atomic_get32(&hg_core_handle->status); |
| 42 | + |
| 43 | +- /* Keep first non-success ret status */ |
| 44 | +- hg_atomic_cas32(&hg_core_handle->ret_status, (int32_t) HG_SUCCESS, |
| 45 | +- (int32_t) callback_info->ret); |
| 46 | +- HG_LOG_SUBSYS_ERROR(rpc, "NA callback returned error (%s, dest=\"%s\")", |
| 47 | +- NA_Error_to_string(callback_info->ret), |
| 48 | +- hg_core_na_addr_to_string(hg_core_handle->na_class, |
| 49 | +- hg_core_handle->na_addr, addr_buf, &addr_buf_size)); |
| 50 | ++ HG_CHECK_SUBSYS_WARNING( |
| 51 | ++ rpc, status & HG_CORE_OP_COMPLETED, "Operation was completed"); |
| 52 | ++ HG_LOG_SUBSYS_DEBUG( |
| 53 | ++ rpc, "NA_CANCELED event on handle %p", (void *) hg_core_handle); |
| 54 | ++ |
| 55 | ++ hg_atomic_cas32(&hg_core_handle->ret_status, (int32_t) HG_SUCCESS, |
| 56 | ++ (int32_t) HG_CANCELED); |
| 57 | ++ } else { /* All other errors */ |
| 58 | ++ char addr_buf[HG_CORE_ADDR_MAX_SIZE]; |
| 59 | ++ size_t addr_buf_size = sizeof(addr_buf); |
| 60 | ++ |
| 61 | ++ /* Mark handle as errored */ |
| 62 | ++ status = |
| 63 | ++ hg_atomic_or32(&hg_core_handle->status, HG_CORE_OP_ERRORED); |
| 64 | ++ |
| 65 | ++ /* Keep first non-success ret status */ |
| 66 | ++ hg_atomic_cas32(&hg_core_handle->ret_status, (int32_t) HG_SUCCESS, |
| 67 | ++ (int32_t) callback_info->ret); |
| 68 | ++ HG_LOG_SUBSYS_ERROR(rpc, |
| 69 | ++ "NA callback returned error (%s, dest=\"%s\")", |
| 70 | ++ NA_Error_to_string(callback_info->ret), |
| 71 | ++ hg_core_na_addr_to_string(hg_core_handle->na_class, |
| 72 | ++ hg_core_handle->na_addr, addr_buf, &addr_buf_size)); |
| 73 | ++ } |
| 74 | + |
| 75 | + if (!(status & HG_CORE_OP_CANCELED) && |
| 76 | + !(hg_atomic_get32(&hg_core_handle->flags) & HG_CORE_NO_RESPONSE)) { |
0 commit comments