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."
Supersedes 227636 - 227644. Supersedes 228988 - 228998. Supersedes 230246 - 230256.
[1] https://bugs.winehq.org/show_bug.cgi?id=52401 [2] https://www.winehq.org/pipermail/wine-devel/2021-May/186454.html
Jinoh Kang (11): server: Actually set initial status in set_async_direct_result handler. server: Ensure initial status is set in async_set_result(). server: Ensure async completion callback is called on synchronous failure. server: Allow async completion callback to retrieve status on synchronous failure. ws2_32/tests: Continue sending remaining data on short write in test_write_events. server: Defer clearing events until async is completed in send_socket handler. server: Add mark_pending field to set_async_direct_result request. 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 | 91 ++++++++++++------ dlls/ntdll/unix/sync.c | 9 +- dlls/ntdll/unix/unix_private.h | 2 +- dlls/ws2_32/tests/sock.c | 23 ++--- server/async.c | 37 +++++--- server/protocol.def | 5 +- server/sock.c | 164 +++++++++++++++++++++++---------- 7 files changed, 220 insertions(+), 111 deletions(-)