mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-09-02 14:53:46 +00:00
close() drained the peer's Close reply with its own frame read. If an application reader thread was inside read() at that moment, two threads parsed frames off one stream: read_websocket_frame()'s payload loop keeps reading until it has the declared length, so bytes stolen by the drain were silently replaced with bytes from further along the stream. The in-flight message kept its correct length but got the wrong content. Add a read_mutex_ that marks which thread owns the stream's read side. read() holds it for the whole call. close() sends the Close frame, then drains the peer's reply (RFC 6455 7.1.1) only if it can try_lock the mutex; otherwise it returns immediately, leaving the stream entirely to the thread already reading it. This also fixes close() blocking for the full close timeout when a reader thread was parked waiting on a peer that never replies. Add WebSocketTest.CloseDoesNotStealBytesFromConcurrentRead, which drives a raw TCP peer that stalls mid-payload to force the race; it fails reliably against the old code and passes against the fix. Update README-websocket.md: close() during a concurrent read() is now supported.