On Friday, 19 June 2026 22:56:09 CDT wine-devel--- via Wine-Devel wrote:
Hi all,
Before I open a merge request, I’d like feedback on the approach, as it has a portability angle I’m unsure about.
Question up front: the fix relies on TIOCOUTQ to query the amount of unsent data in a socket’s send buffer. That is Linux-specific. Is gating it on #ifdef TIOCOUTQ (leaving current behaviour unchanged elsewhere) acceptable, or would you prefer a different mechanism, or a different layer than poll_socket()? I’d rather hear that now than in review.
On Windows, select() reports a connected stream socket writable whenever a send() would still accept data into the send buffer. Wine derives writability from the host poll(); on Linux POLLOUT is only set once the send queue has drained below roughly 2/3 of SO_SNDBUF. So while the buffer is between ~2/3 full and full, Windows says “writable” but Wine says “not writable” even though send() still succeeds.
The common application pattern is a non-blocking select() writability check before waiting on an FD_WRITE event. libcurl’s multi loop does exactly this. Under Wine, an app-limited sender (sends keep succeeding, never hitting WSAEWOULDBLOCK) sees “not writable” while it still has room, and since FD_WRITE is edge-triggered and not re-recorded until a send fails, it waits out its full poll timeout (typically 1s) between bursts. Single-stream uploads end up throttled to ~140 KB/s. I found this with a libcurl-based backup client whose uploads could not finish within their timeout under Wine.
Proposed fix: In poll_socket(), when the immediate poll() does not report POLLOUT for a connected stream socket that still has send-buffer room (TIOCOUTQ < SO_SNDBUF), report it writable. One small block, #ifdef TIOCOUTQ.
This seems reasonable to me, probably, though I have to ask, what does curl do on linux? Does it adjust SNDBUF to be bigger? --Zeb