Loading src/httpd.cpp +15 −2 Original line number Diff line number Diff line Loading @@ -546,8 +546,21 @@ bool libhttppp::HttpEvent::_dispatchH2Stream(HttpRequest &cureq, [this, connOwner, trBox, sid, tid, args]() mutable { // The ONLY blocking call in this task — touches // *trBox (private to this task) only, never // cureq/h2state(). // cureq/h2state(). A backend call inside RequestEvent // (proxy timeout, connect failure, etc.) can throw -- // ThreadPool's own catch(...) around submitted tasks // would otherwise swallow it silently and never call // _finishH2Dispatch at all, leaving the stream with no // HEADERS/DATA/RST_STREAM ever sent (hangs forever) and // its peerStreamWindows entry leaked. Falling through to // _finishH2Dispatch unconditionally instead reuses its // existing "no response produced" cleanup below (*trBox // never got :res-valid set), which already sends // RST_STREAM(INTERNAL_ERROR) and erases the window entry. try { RequestEvent(**trBox, tid, args); } catch (...) { } HttpRequest &cureq2 = static_cast<HttpRequest&>(*connOwner); std::lock_guard<std::recursive_mutex> lk(cureq2.event_mutex); Loading Loading
src/httpd.cpp +15 −2 Original line number Diff line number Diff line Loading @@ -546,8 +546,21 @@ bool libhttppp::HttpEvent::_dispatchH2Stream(HttpRequest &cureq, [this, connOwner, trBox, sid, tid, args]() mutable { // The ONLY blocking call in this task — touches // *trBox (private to this task) only, never // cureq/h2state(). // cureq/h2state(). A backend call inside RequestEvent // (proxy timeout, connect failure, etc.) can throw -- // ThreadPool's own catch(...) around submitted tasks // would otherwise swallow it silently and never call // _finishH2Dispatch at all, leaving the stream with no // HEADERS/DATA/RST_STREAM ever sent (hangs forever) and // its peerStreamWindows entry leaked. Falling through to // _finishH2Dispatch unconditionally instead reuses its // existing "no response produced" cleanup below (*trBox // never got :res-valid set), which already sends // RST_STREAM(INTERNAL_ERROR) and erases the window entry. try { RequestEvent(**trBox, tid, args); } catch (...) { } HttpRequest &cureq2 = static_cast<HttpRequest&>(*connOwner); std::lock_guard<std::recursive_mutex> lk(cureq2.event_mutex); Loading