Streams were dropped within seconds in v4.0.0 because the per-client chunk queue was sized as max(2, video_timeout) = 30 entries, and curl delivered ~16 KB chunks, giving an effective buffer of ~480 KB (vs ~30 MB in the Python version with chunk_size=1 MB). Any prebuffer burst from AceStream filled the queue instantly and the proxy closed the client on the very first overflow. STOP/SHUTDOWN were also emitted multiple times because Broadcast::stop was non-idempotent.
Changes:
Decouple buffer size from video_timeout. Add CLIENT_QUEUE_SIZE (default 256), CLIENT_WRITE_TIMEOUT (default 15s) and CURL_STREAM_BUFFER (default 1 MiB) env knobs.
ChunkQueue::push now waits up to a configurable timeout for free space and falls back to drop-oldest instead of fail-fast. Add a cv_space_ condvar notified on pop so producer can resume.
Track per-client last_activity, dropped_chunks counter, and a one-shot stuck_logged flag. Only close the client (and log once) when the consumer has not progressed for client_write_timeout seconds while drops keep happening - silences the warning storm.
Make Broadcast::stop idempotent via a stopped_ flag, so the engine STOP/SHUTDOWN messages are emitted only once even when several clients tear down concurrently.
Increase libcurl read buffer for streaming to CURL_STREAM_BUFFER (1 MiB by default) to mirror the Python iter_content size and reduce the rate of broadcast_chunk invocations.
Apply SO_SNDTIMEO on each accepted client socket so a hung TCP consumer is detected by send() instead of by queue overflow.
Built with cmake, all tests pass.