Commit bfdf5d4b authored by jan.koester's avatar jan.koester
Browse files

test

parent 5b6ab140
Loading
Loading
Loading
Loading
+46 −6
Changes for src/httpd.cpp: 46 added lines, 6 removed lines.
Original line number Diff line number Diff line
@@ -924,11 +924,15 @@ void libhttppp::HttpEvent::_resumeH2Streams(HttpRequest &cureq,
                    cureq.h2state().peerStreamWindows.erase(sid);
                    streams.erase(it);
                } else {
                    // Signal the main connection so the epoll loop
                    // re-arms with EPOLLOUT and calls ResponseEvent,
                    // which will resume this stream without waiting
                    // for the client to send WINDOW_UPDATE.
                    cureq.slots[0].ResponsePending.store(true, std::memory_order_release);
                    // Signal and explicitly re-arm the real H2 connection.
                    // The synthetic per-stream request is not registered in
                    // epoll, therefore setting only ResponsePending is not
                    // sufficient to wake the connection again.
                    cureq.slots[0].ResponsePending.store(
                        true,
                        std::memory_order_release
                    );
                    netplus::requestWritablePoll(cureq);
                }
                break;  // Don't busy-loop; wait for next event
            }
@@ -1924,7 +1928,43 @@ void libhttppp::HttpEvent::ResponseEvent(netplus::con &curcon,const int tid,ULON
            // DATA generated above must be handed to the socket now. If the
            // socket is temporarily blocked, _flushSendDataNow() re-arms the
            // writable event so the response cannot remain parked forever.
            _flushSendDataNow(cureq);
            const bool fullyFlushed = _flushSendDataNow(cureq);

            /*
             * _flushSendDataNow() clears ResponsePending when the current
             * transport/application buffers are empty. That is correct for
             * completed responses, but not for an active streaming response:
             * the application may need another ResponseEvent call to produce
             * the next media chunk even though SendData is currently empty.
             *
             * Without this re-arm, an H2 video stream can stop after the first
             * chunk whenever no WINDOW_UPDATE or further inbound frame arrives.
             */
            const bool hasActiveStreams =
                cureq._h2 && !cureq._h2->activeStreams.empty();

            const bool hasPendingResponses =
                cureq._h2 && !cureq._h2->pendingResponses.empty();

            const bool hasQueuedApplicationData =
                cureq.SendData.pos < cureq.SendData.size();

            const bool hasQueuedTransportData =
                cureq.slots[0].csock &&
                cureq.slots[0].csock->hasPendingWrite();

            if (hasActiveStreams ||
                hasPendingResponses ||
                hasQueuedApplicationData ||
                hasQueuedTransportData ||
                !fullyFlushed) {
                cureq.slots[0].ResponsePending.store(
                    true,
                    std::memory_order_release
                );
                netplus::requestWritablePoll(cureq);
            }

            return;
        }