aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/grpc/patches/pr38907_fix_race_condition_in_perAttemptRecvTimeout_timer.patch
blob: 705258089c2c065652c6ba53ef08e9195d295c06 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
--- contrib/libs/grpc/src/core/ext/filters/client_channel/retry_filter.cc	(275a6f99de0655569f20495a7c5683e0b5e06c8d)
+++ contrib/libs/grpc/src/core/ext/filters/client_channel/retry_filter.cc	(working tree)
@@ -1265,28 +1265,30 @@ void RetryFilter::CallData::CallAttempt::OnPerAttemptRecvTimerLocked(
             call_attempt->per_attempt_recv_timer_handle_.has_value());
   }
   CallCombinerClosureList closures;
-  call_attempt->per_attempt_recv_timer_handle_.reset();
-  // Cancel this attempt.
-  // TODO(roth): When implementing hedging, we should not cancel the
-  // current attempt.
-  call_attempt->MaybeAddBatchForCancelOp(
-      grpc_error_set_int(
-          GRPC_ERROR_CREATE("retry perAttemptRecvTimeout exceeded"),
-          StatusIntProperty::kRpcStatus, GRPC_STATUS_CANCELLED),
-      &closures);
-  // Check whether we should retry.
-  if (call_attempt->ShouldRetry(/*status=*/y_absl::nullopt,
-                                /*server_pushback_ms=*/y_absl::nullopt)) {
-    // Mark current attempt as abandoned.
-    call_attempt->Abandon();
-    // We are retrying.  Start backoff timer.
-    calld->StartRetryTimer(/*server_pushback=*/y_absl::nullopt);
-  } else {
-    // Not retrying, so commit the call.
-    calld->RetryCommit(call_attempt);
-    // If retry state is no longer needed, switch to fast path for
-    // subsequent batches.
-    call_attempt->MaybeSwitchToFastPath();
+  if (call_attempt->per_attempt_recv_timer_handle_.has_value()) {
+    call_attempt->per_attempt_recv_timer_handle_.reset();
+    // Cancel this attempt.
+    // TODO(roth): When implementing hedging, we should not cancel the
+    // current attempt.
+    call_attempt->MaybeAddBatchForCancelOp(
+        grpc_error_set_int(
+            GRPC_ERROR_CREATE("retry perAttemptRecvTimeout exceeded"),
+            StatusIntProperty::kRpcStatus, GRPC_STATUS_CANCELLED),
+        &closures);
+    // Check whether we should retry.
+    if (call_attempt->ShouldRetry(/*status=*/y_absl::nullopt,
+                                  /*server_pushback_ms=*/y_absl::nullopt)) {
+        // Mark current attempt as abandoned.
+        call_attempt->Abandon();
+        // We are retrying.  Start backoff timer.
+        calld->StartRetryTimer(/*server_pushback=*/y_absl::nullopt);
+    } else {
+        // Not retrying, so commit the call.
+        calld->RetryCommit(call_attempt);
+        // If retry state is no longer needed, switch to fast path for
+        // subsequent batches.
+        call_attempt->MaybeSwitchToFastPath();
+    }
   }
   closures.RunClosures(calld->call_combiner_);
   call_attempt->Unref(DEBUG_LOCATION, "OnPerAttemptRecvTimer");