Commit 6ad2e9b7 authored by Jan Koester's avatar Jan Koester
Browse files

test

parent 03b5afad
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#include <shared_mutex>
#include <condition_variable>
#include <atomic>
#include <chrono>
#include <memory>
#include <algorithm>
#include <cstdint>
@@ -1828,17 +1829,43 @@ namespace blogi {
            size_t sendSize = 0;
            size_t produced = 0;
            int tid = 0;
            std::chrono::steady_clock::time_point last_activity = std::chrono::steady_clock::now();
        };

        // Plugins get no callback when the browser-facing connection dies
        // mid-stream (no Disconnect hook in PluginApi), so a StreamState
        // whose owning req is abandoned would otherwise sit in _streams
        // forever — Response() simply stops being called for it, holding
        // its pooled mediadb connection open (and un-drained) permanently.
        // Sweep those out opportunistically whenever a new stream starts.
        static constexpr std::chrono::seconds STREAM_IDLE_TIMEOUT{30};

        void _reapStaleStreamsLocked(){
            const auto now = std::chrono::steady_clock::now();
            for(auto it = _streams.begin(); it != _streams.end();){
                if(now - it->second.last_activity > STREAM_IDLE_TIMEOUT){
                    // Connection may hold un-drained bytes from the abandoned
                    // response — discard rather than returning it to the pool,
                    // where reuse would desync the next reader.
                    it->second.client.discard();
                    it = _streams.erase(it);
                } else {
                    ++it;
                }
            }
        }

        void _storeStreamState(libhttppp::HttpRequest &req,
                               CheckoutPool<libhttppp::HttpClient>::Handle client,
                               size_t sendSize, int tid){
            std::unique_lock lock(_streamMutex);
            _reapStaleStreamsLocked();
            auto &ss = _streams[reinterpret_cast<uintptr_t>(&req)];
            ss.client = std::move(client);
            ss.sendSize = sendSize;
            ss.produced = 0;
            ss.tid = tid;
            ss.last_activity = std::chrono::steady_clock::now();
        }

        StreamState* _getStreamState(libhttppp::HttpRequest &req){
@@ -1850,6 +1877,7 @@ namespace blogi {
                _streams.erase(it);
                return nullptr;
            }
            ptr->last_activity = std::chrono::steady_clock::now();
            return ptr;
        }