This fixes the send part of the issue #52401 [1]: "Improper synchronization in sock_recv/sock_send leads to arbitrary reordering of completion of I/O requests", which was initially reported (outside Bugzilla) by Dongwan Kim [2].
Changelog: v1 -> v2: - drop patch "server: Compact struct set_async_direct_result_reply." - add async and fd arguments to async_initial_status_callback - recv_socket_initial_callback: pass OOB flag via private instead of implementing two separate functions for OOB and non-OOB - detect short write in send_socket_initial_callback - preserve the behaviour of returning success if we had a short write and the socket is nonblocking and force_async is unset v2 -> v3: - fix typo in comment v3 -> v4: - fix typo in commit message - address feedback - drop patch "server: Defer postprocessing until after setting initial status in recv_socket handler." v4 -> v5: - drop patch "server: Add async_initial_status_callback." - drop patch "server: Defer postprocessing until after setting initial status in send_socket handler." - add patch "server: Ensure completion_callback is called before async is destroyed." - add patch "ws2_32/tests: Continue sending remaining data on short write in test_write_events." - add patch "server: Defer clearing events until async is either pending or completed in send_socket handler." - add patch "server: Ensure datagram sockets are bound in send_socket." v5 -> v6: - centralise status code computation in one place, even for bind errno translation - fix erroneous subject (s/either pending or completed/completed/) v6 -> v7: - drop patch "server: Ensure completion_callback is called before async is destroyed." - add patch "server: Ensure async completion callback is called on synchronous failure." - add patch "server: Allow async completion callback to retrieve status on synchronous failure." v7 -> v8: - drop committed patches - edit commit message of "server: Ensure completion_callback is called before async is destroyed." as per feedback (thanks zf) - move a sock_reselect() into the prior if block (thanks zf)
Supersedes 227636 - 227644. Supersedes 228988 - 228998. Supersedes 230282 - 230293 (sans already committed patches).
[1] https://bugs.winehq.org/show_bug.cgi?id=52401 [2] https://www.winehq.org/pipermail/wine-devel/2021-May/186454.html
Jinoh Kang (7): server: Generalise async completion callback to be called on synchronous failure. server: Allow async completion callback to retrieve status on synchronous failure. server: Defer clearing events until async is completed in send_socket handler. server: Attempt to complete I/O request immediately in send_socket. server: Ensure datagram sockets are bound in send_socket. ntdll: Don't call try_send before server call in sock_send. server: Replace redundant send_socket status fields with force_async boolean field.
dlls/ntdll/unix/socket.c | 89 +++++++++++++++------- dlls/ws2_32/tests/sock.c | 14 ++-- server/async.c | 14 +++- server/protocol.def | 4 +- server/sock.c | 161 +++++++++++++++++++++++++++------------ 5 files changed, 195 insertions(+), 87 deletions(-)