Asyncs which are alerted but not "waiting" may still fill the pipe, and we
shouldn't signal AFD_POLL_WRITE in that case.
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Asyncs which are alerted but not "waiting" may still consume all data, and we
shouldn't signal AFD_POLL_READ or AFD_POLL_OOB in that case.
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This is validated by tests introduced in
59beffb46c etc. This commit alone doesn't fix said
tests, because:
* on this poll, we will alert the waiting async;
* when reselecting, we will still request POLLIN, because the AFD_POLL_READ
request is still active,
* when POLLIN is subsequently signaled, we do not remove it in
sock_dispatch_asyncs(), because we check async_waiting(), not async_queued().
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
The 'status' field of send_socket_request is always either
STATUS_PENDING or STATUS_DEVICE_NOT_READY, and the 'total' field is
always zero.
Replace the 'status' field with 'force_async' boolean field, and get rid
of the 'total' field entirely.
Also, clean up the send_socket handler code a bit.
Signed-off-by: Jinoh Kang <jinoh.kang.kr@gmail.com>
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
If the type of the socket is SOCK_DGRAM, it shall always be bound to an
address if we ever attempt to send datagrams through the socket, whether
the attempt succeeds or not.
Signed-off-by: Jinoh Kang <jinoh.kang.kr@gmail.com>
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Make send_socket alert the async immediately if poll() call detects that
there are incoming data in the socket, bypassing the wineserver's main
polling loop.
For sock_transmit, we always mark the async as pending and set the IOSB
(unless async allocation has failed).
Signed-off-by: Jinoh Kang <jinoh.kang.kr@gmail.com>
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This allows the initial I/O to be performed after the send_socket
handler is called.
Signed-off-by: Jinoh Kang <jinoh.kang.kr@gmail.com>
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This also makes async_handoff() behaviour more consistent with
async_set_result() for handling I/O failures.
Signed-off-by: Jinoh Kang <jinoh.kang.kr@gmail.com>
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Today, async_set_completion_callback() is used to register a function
that is called when the async I/O is completed. It is assumed that the
async will eventually be queued when such callback is registered.
However, this incurs extra complexity in future code that needs the
completion logic to be invoked even if the async is never actually
queued (e.g. when the I/O failed synchronously before async_handoff).
Generalise async completion callback by calling it in async_handoff()
when the I/O status indicates failure.
Signed-off-by: Jinoh Kang <jinoh.kang.kr@gmail.com>
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
The client can set mark_pending to indicate that the full-blown I/O
completion mechanism shall be triggered (asynchronous completion) even
if the status indicates failure.
Signed-off-by: Jinoh Kang <jinoh.kang.kr@gmail.com>
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Shift the resposibility of setting initial status from
set_async_direct_result request handler to async_set_result().
Signed-off-by: Jinoh Kang <jinoh.kang.kr@gmail.com>
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Commit 15483b1a12 (server: Allow calling async_handoff() with status
code STATUS_ALERTED., 2022-02-10) introduced the set_async_direct_result
handler which calls async_set_initial_status().
However, the async_set_initial_status() call does nothing since
async->terminated is set, leaving the async in a confusing state
(unknown_status = 1 but pending/completed).
So far, this issue is unlikely to have been a problem in practice for
the following reasons:
1. async_set_initial_status() would have unset unknown_status, but it
remains set instead. This is usually not a problem, since
unknown_status is usually ever read by code paths effectively
unreachable for non-device (e.g. socket) asyncs.
It would still potentially allow set_async_direct_result to be called
multiple times, but it wouldn't actually happen in practice unless
something goes wrong.
2. async_set_initial_status() would have set initial_status; however,
it is left with the default value STATUS_PENDING. If the actual
status is something other than that, the handler closes the wait
handle and async_satisfied (the only real consumer of initial_status)
would never be called anyway.
For reasons above, this issue is not effectively observable or testable.
Nonetheless, the current code does leave the async object in an
inconsistent state.
Fix this by removing the !async->terminated check in
async_set_initial_status().
Also, remove assert( async->unknown_status ). The client can now
trigger the assert() by calling set_async_direct_result on a device
async, thereby causing async_set_initial_status() to be called twice.
Signed-off-by: Jinoh Kang <jinoh.kang.kr@gmail.com>
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
The 'status' field of recv_socket_request is always either
STATUS_PENDING or STATUS_DEVICE_NOT_READY, and the 'total' field is
always zero.
Replace the 'status' field with 'force_async' boolean field, and get rid
of the 'total' field entirely.
Also, clean up the recv_socket handler code a bit.
Signed-off-by: Jinoh Kang <jinoh.kang.kr@gmail.com>
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Make recv_socket alert the async immediately if poll() call detects that
there are incoming data in the socket, bypassing the wineserver's main
polling loop.
Signed-off-by: Jinoh Kang <jinoh.kang.kr@gmail.com>
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
If the server detects that an I/O request could be completed immediately
(e.g. the socket to read from already has incoming data), it can now
return STATUS_ALERTED to allow opportunistic synchronous I/O. The Unix
side will then attempt to perform I/O in nonblocking mode and report
back the I/O status to the server via the new server request
"set_async_direct_result". If the operation returns e.g. EAGAIN
or EWOULDBLOCK, the client can opt to either abandon the request (by
specifying an error status) or poll for it in the server as usual (by
waiting on the wait handle).
Without such mechanism in place, the client cannot safely perform
immediately satiable I/O operations synchronously, since it can
potentially conflict with other pending I/O operations that have already
been queued.
Signed-off-by: Jinoh Kang <jinoh.kang.kr@gmail.com>
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
Fixes a regression introduced by
5c009c17b3.
For IPV6 socket already bound with bind() with IPV6_V6ONLY set to 0
the address returned by getsockname() may change after it is connected
to a IPV4 peer (e. g., from :: to ::ffff:192.0.2.128).
The effect of blamed commit is that before that Unix getsockname()
was called for each ws2_32 getsockname() and after the commit the
socket name is cached at bind and connect.
Signed-off-by: Paul Gofman <pgofman@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>