This is an automated email from the ASF dual-hosted git repository.

cmcfarlen pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit 06a99bb1e6140bf4c2aae091102b0406529144a4
Author: Masaori Koshiba <[email protected]>
AuthorDate: Thu Dec 11 08:39:38 2025 +0900

    Break recursive call of CacheVC::openReadStartEarliest (#12710)
    
    * Break recursive call of CacheVC::openReadStartEarliest
    
    * Address comments from Copilot
    
    (cherry picked from commit 5e3f0525f6cbb5d05d4c1bc3b76758713a7444f1)
---
 src/iocore/cache/CacheRead.cc | 32 +++++++++++++++++++++++++-------
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/src/iocore/cache/CacheRead.cc b/src/iocore/cache/CacheRead.cc
index 2465562bd3..9826b0854d 100644
--- a/src/iocore/cache/CacheRead.cc
+++ b/src/iocore/cache/CacheRead.cc
@@ -45,6 +45,8 @@ DbgCtl dbg_ctl_cache_hit_evac{"cache_hit_evac"};
 
 #endif
 
+constexpr int MAX_READ_RECURSION_DEPTH = 10;
+
 } // end anonymous namespace
 
 uint32_t
@@ -749,8 +751,10 @@ Lcallreturn:
 int
 CacheVC::openReadStartEarliest(int /* event ATS_UNUSED */, Event * /* e 
ATS_UNUSED */)
 {
-  int  ret = 0;
-  Doc *doc = nullptr;
+  int  call_result       = 0;
+  int  event_result      = 0;
+  Doc *doc               = nullptr;
+  bool is_recursive_call = false;
   cancel_trigger();
   set_io_not_in_progress();
   if (_action.cancelled) {
@@ -814,10 +818,20 @@ CacheVC::openReadStartEarliest(int /* event ATS_UNUSED 
*/, Event * /* e ATS_UNUS
   Lread:
     if (dir_probe(&key, stripe, &earliest_dir, &last_collision) || 
dir_lookaside_probe(&key, stripe, &earliest_dir, nullptr)) {
       dir = earliest_dir;
-      if ((ret = do_read_call(&key)) == EVENT_RETURN) {
+      if ((call_result = do_read_call(&key)) == EVENT_RETURN) {
+        if (this->handler == 
reinterpret_cast<ContinuationHandler>(&CacheVC::openReadStartEarliest)) {
+          is_recursive_call = true;
+          if (recursive > MAX_READ_RECURSION_DEPTH) {
+            char tmpstring[CRYPTO_HEX_SIZE];
+            Error("Too many recursive calls with %s", key.toHexStr(tmpstring));
+            goto Ldone;
+          }
+          ++recursive;
+        }
+
         goto Lcallreturn;
       }
-      return ret;
+      return call_result;
     }
     // read has detected that alternate does not exist in the cache.
     // rewrite the vector.
@@ -867,10 +881,10 @@ CacheVC::openReadStartEarliest(int /* event ATS_UNUSED 
*/, Event * /* e ATS_UNUS
             dir_set_tag(&od->single_doc_dir, od->single_doc_key.slice32(2));
           }
           SET_HANDLER(&CacheVC::openReadVecWrite);
-          if ((ret = do_write_call()) == EVENT_RETURN) {
+          if ((call_result = do_write_call()) == EVENT_RETURN) {
             goto Lcallreturn;
           }
-          return ret;
+          return call_result;
         }
       }
     }
@@ -885,7 +899,11 @@ CacheVC::openReadStartEarliest(int /* event ATS_UNUSED */, 
Event * /* e ATS_UNUS
   _action.continuation->handleEvent(CACHE_EVENT_OPEN_READ_FAILED, 
reinterpret_cast<void *>(-ECACHE_NO_DOC));
   return free_CacheVC(this);
 Lcallreturn:
-  return handleEvent(AIO_EVENT_DONE, nullptr); // hopefully a tail call
+  event_result = handleEvent(AIO_EVENT_DONE, nullptr); // hopefully a tail call
+  if (is_recursive_call) {
+    --recursive;
+  }
+  return event_result;
 Lsuccess:
   if (write_vc) {
     ts::Metrics::Counter::increment(cache_rsb.read_busy_success);

Reply via email to