A websocket implementation for zig
0

Configure Feed

Select the types of activity you want to include in your feed.

client: skip poll when TLS plaintext is buffered; surface poll errors

Addresses review: a prior read can decrypt more than the caller consumed, leaving
plaintext in the TLS client's buffer while the socket is empty, so polling the fd
would spuriously time out and starve buffered data. Check reader.bufferedLen()
first. A poll failure is surfaced as a read failure (mapped into the fill error
set) rather than swallowed.

+11 -4
+11 -4
src/client/client.zig
··· 448 448 // SO_RCVTIMEO produces on timeout) as a programmer bug and panics in 449 449 // debug builds. Polling lets a timeout surface as error.WouldBlock (which 450 450 // read() turns into "no message") without ever issuing a read that could 451 - // EAGAIN. The caller drains its buffer before reaching here, so polling 452 - // only gates an actual socket read. 453 - if (self.read_timeout_ms > 0) { 451 + // EAGAIN. 452 + // 453 + // Skip the poll when the TLS client already has decrypted plaintext 454 + // buffered: a previous read can decrypt more than the caller consumed, so 455 + // the socket can be empty (poll would time out) even though data is 456 + // available in-process, which would starve it. 457 + const tls_buffered = if (self.tls_client) |tls_client| tls_client.client.reader.bufferedLen() else 0; 458 + if (self.read_timeout_ms > 0 and tls_buffered == 0) { 454 459 var pfd = [_]std.posix.pollfd{.{ 455 460 .fd = self.stream.socket.handle, 456 461 .events = std.posix.POLL.IN, 457 462 .revents = 0, 458 463 }}; 459 - const ready = std.posix.poll(&pfd, @intCast(self.read_timeout_ms)) catch 0; 464 + // A poll failure is a real read failure, not "no data": surface it 465 + // (mapped into this read path's error set) rather than swallowing it. 466 + const ready = std.posix.poll(&pfd, @intCast(self.read_timeout_ms)) catch return error.ReadFailed; 460 467 if (ready == 0) return error.WouldBlock; 461 468 } 462 469 if (self.tls_client) |tls_client| {