@@ -35,7 +35,7 @@ AsyncHttpClient::AsyncHttpClient()
3535 // Optional: spawn a lightweight auto-loop task so users don't need to call client.loop() manually.
3636 xTaskCreatePinnedToCore (_autoLoopTaskThunk, // task entry
3737 " AsyncHttpAutoLoop" , // name
38- 2048 , // stack words
38+ 4096 , // stack words
3939 this , // parameter
4040 1 , // priority (low)
4141 &_autoLoopTaskHandle, // handle out
@@ -1038,7 +1038,10 @@ void AsyncHttpClient::cleanup(RequestContext* context) {
10381038 toDelete->close ();
10391039 delete toDelete;
10401040 }
1041- tryDequeue ();
1041+ // Guard against recursion: cleanup → tryDequeue → executeRequest → triggerError → cleanup → tryDequeue
1042+ // The outer tryDequeue's while-loop will handle remaining pending requests.
1043+ if (!_inTryDequeue)
1044+ tryDequeue ();
10421045}
10431046
10441047void AsyncHttpClient::triggerError (RequestContext* context, HttpClientError errorCode, const char * errorMessage) {
@@ -1064,13 +1067,15 @@ void AsyncHttpClient::loop() {
10641067 unlock ();
10651068 triggerError (ctx, REQUEST_TIMEOUT, " Request timeout" );
10661069 lock ();
1070+ continue ; // ctx may be freed; re-read at current index
10671071 }
10681072#endif
10691073 if (!ctx->cancelled .load () && !ctx->responseProcessed && ctx->transport && !ctx->headersSent &&
10701074 ctx->timing .connectTimeoutMs > 0 && (now - ctx->timing .connectStartMs ) > ctx->timing .connectTimeoutMs ) {
10711075 unlock ();
10721076 triggerError (ctx, CONNECT_TIMEOUT, " Connect timeout" );
10731077 lock ();
1078+ continue ; // ctx may be freed; re-read at current index
10741079 }
10751080 if (!ctx->cancelled .load () && !ctx->responseProcessed && ctx->transport && ctx->transport ->isHandshaking ()) {
10761081 uint32_t hsTimeout = ctx->transport ->getHandshakeTimeoutMs ();
@@ -1079,6 +1084,7 @@ void AsyncHttpClient::loop() {
10791084 unlock ();
10801085 triggerError (ctx, TLS_HANDSHAKE_TIMEOUT, " TLS handshake timeout" );
10811086 lock ();
1087+ continue ; // ctx may be freed; re-read at current index
10821088 }
10831089 }
10841090 if (!ctx->cancelled .load () && !ctx->responseProcessed && ctx->streamingBodyInProgress &&
@@ -1097,6 +1103,9 @@ void AsyncHttpClient::loop() {
10971103}
10981104
10991105void AsyncHttpClient::tryDequeue () {
1106+ if (_inTryDequeue)
1107+ return ; // prevent recursion via executeRequest → triggerError → cleanup → tryDequeue
1108+ _inTryDequeue = true ;
11001109 while (true ) {
11011110 lock ();
11021111 bool canStart = (_maxParallel == 0 || _activeRequests.size () < _maxParallel);
@@ -1110,6 +1119,7 @@ void AsyncHttpClient::tryDequeue() {
11101119 unlock ();
11111120 executeRequest (ctx);
11121121 }
1122+ _inTryDequeue = false ;
11131123}
11141124
11151125void AsyncHttpClient::sendStreamData (RequestContext* context) {
0 commit comments