Fix SSL_pending busy-wait causing 100% CPU usage

The tls_recv() function was skipping the select() call when SSL_pending()
returned non-zero, causing a tight busy-wait loop. This fix ensures select()
is always called, using a zero timeout when SSL has buffered data to return
immediately, or the full timeout to properly block when waiting for new data.

This prevents the relay client from consuming 100% CPU while maintaining
the WebSocket connection.
This commit is contained in:
Your Name
2026-02-03 14:16:00 -04:00
parent f3068f82f3
commit 64b7c7ec33

View File

@@ -580,23 +580,30 @@ static int tls_recv(void* ctx, void* data, size_t len, int timeout_ms) {
return -1; return -1;
} }
// Check if SSL has pending data first // Always use select() to ensure proper blocking behavior
if (SSL_pending(tls->ssl) == 0 && timeout_ms > 0) { // If SSL has pending data, use zero timeout to return immediately
// Only use select() if no data is pending in SSL buffers // Otherwise use the full timeout to block until data arrives
if (timeout_ms > 0) {
fd_set readfds; fd_set readfds;
struct timeval tv; struct timeval tv;
FD_ZERO(&readfds); FD_ZERO(&readfds);
FD_SET(tls->socket_fd, &readfds); FD_SET(tls->socket_fd, &readfds);
tv.tv_sec = timeout_ms / 1000; // If SSL has buffered data, use zero timeout; otherwise use full timeout
tv.tv_usec = (timeout_ms % 1000) * 1000; if (SSL_pending(tls->ssl) > 0) {
tv.tv_sec = 0;
tv.tv_usec = 0;
} else {
tv.tv_sec = timeout_ms / 1000;
tv.tv_usec = (timeout_ms % 1000) * 1000;
}
int result = select(tls->socket_fd + 1, &readfds, NULL, NULL, &tv); int result = select(tls->socket_fd + 1, &readfds, NULL, NULL, &tv);
if (result < 0) { if (result < 0) {
return -1; return -1;
} else if (result == 0) { } else if (result == 0 && SSL_pending(tls->ssl) == 0) {
return -1; // Timeout return -1; // Timeout with no pending data
} }
} }