@@ -45,6 +45,8 @@ DbgCtl dbg_ctl_cache_hit_evac{"cache_hit_evac"};
4545
4646#endif
4747
48+ constexpr int MAX_READ_RECURSION_DEPTH = 10 ;
49+
4850} // end anonymous namespace
4951
5052uint32_t
@@ -749,8 +751,10 @@ Lread: {
749751int
750752CacheVC::openReadStartEarliest (int /* event ATS_UNUSED */ , Event * /* e ATS_UNUSED */ )
751753{
752- int ret = 0 ;
753- Doc *doc = nullptr ;
754+ int call_result = 0 ;
755+ int event_result = 0 ;
756+ Doc *doc = nullptr ;
757+ bool is_recursive_call = false ;
754758 cancel_trigger ();
755759 set_io_not_in_progress ();
756760 if (_action.cancelled ) {
@@ -815,10 +819,20 @@ CacheVC::openReadStartEarliest(int /* event ATS_UNUSED */, Event * /* e ATS_UNUS
815819 if (stripe->directory .probe (&key, stripe, &earliest_dir, &last_collision) ||
816820 dir_lookaside_probe (&key, stripe, &earliest_dir, nullptr )) {
817821 dir = earliest_dir;
818- if ((ret = do_read_call (&key)) == EVENT_RETURN) {
822+ if ((call_result = do_read_call (&key)) == EVENT_RETURN) {
823+ if (this ->handler == reinterpret_cast <ContinuationHandler>(&CacheVC::openReadStartEarliest)) {
824+ is_recursive_call = true ;
825+ if (recursive > MAX_READ_RECURSION_DEPTH) {
826+ char tmpstring[CRYPTO_HEX_SIZE];
827+ Error (" Too many recursive calls with %s" , key.toHexStr (tmpstring));
828+ goto Ldone;
829+ }
830+ ++recursive;
831+ }
832+
819833 goto Lcallreturn;
820834 }
821- return ret ;
835+ return call_result ;
822836 }
823837 // read has detected that alternate does not exist in the cache.
824838 // rewrite the vector.
@@ -868,10 +882,10 @@ CacheVC::openReadStartEarliest(int /* event ATS_UNUSED */, Event * /* e ATS_UNUS
868882 dir_set_tag (&od->single_doc_dir , od->single_doc_key .slice32 (2 ));
869883 }
870884 SET_HANDLER (&CacheVC::openReadVecWrite);
871- if ((ret = do_write_call ()) == EVENT_RETURN) {
885+ if ((call_result = do_write_call ()) == EVENT_RETURN) {
872886 goto Lcallreturn;
873887 }
874- return ret ;
888+ return call_result ;
875889 }
876890 }
877891 }
@@ -886,7 +900,11 @@ CacheVC::openReadStartEarliest(int /* event ATS_UNUSED */, Event * /* e ATS_UNUS
886900 _action.continuation ->handleEvent (CACHE_EVENT_OPEN_READ_FAILED, reinterpret_cast <void *>(-ECACHE_NO_DOC));
887901 return free_CacheVC (this );
888902Lcallreturn:
889- return handleEvent (AIO_EVENT_DONE, nullptr ); // hopefully a tail call
903+ event_result = handleEvent (AIO_EVENT_DONE, nullptr ); // hopefully a tail call
904+ if (is_recursive_call) {
905+ --recursive;
906+ }
907+ return event_result;
890908Lsuccess:
891909 if (write_vc) {
892910 ts::Metrics::Counter::increment (cache_rsb.read_busy_success );
0 commit comments