[PATCH v4 4/8] server: Defer postprocessing until after setting initial status in send_socket handler.

Zebediah Figura zfigura at codeweavers.com
Fri Mar 4 18:13:39 CST 2022


On 3/4/22 13:16, Jinoh Kang wrote:
> On 3/5/22 02:51, Zebediah Figura wrote:
>> On 3/3/22 07:30, Jinoh Kang wrote:
>>> This allows the client to postpone the initial I/O until the server has
>>> queued the I/O request.  The server should perform the postprocessing
>>> only after the initial I/O has been done.
>>>
>>> In the case of send_socket, the manipulation of event flags shall
>>> ideally be done *after* (not *before*) the client has attempted the
>>> initial I/O, since the outbound queue status of the socket may change in
>>> the meanwhile.  Also, the implicitly bound address is available only
>>> after the send* system call has been performed.
>>>
>>> Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
>>> ---
>>>
>>> Notes:
>>>       v1 -> v2:
>>>       - pass around total size of data to be transmitted
>>>       - detect short write in send_socket_initial_callback
>>>       v2 -> v3: no changes
>>>       v3 -> v4: no changes
>>>
>>>    dlls/ntdll/unix/socket.c | 15 ++++++++++++++
>>>    server/protocol.def      |  1 +
>>>    server/sock.c            | 42 +++++++++++++++++++++++++++-------------
>>>    3 files changed, 45 insertions(+), 13 deletions(-)
>>>
>>
>> I still am failing to see the need to do this, especially by adding a new callback. What's preventing send_socket from working the same way as recv_socket?
> 
> As stated in the commit message, none of the actions in send_socket_initial_callback can be performed *before* the initial I/O.
> 
> In send_socket, "send() calls only clear and reselect events if unsuccessful."
> We can tell if the I/O has succeeded only after set_async_direct_result.
> Therefore, we can only clear and reselect events after the client tells us the initial I/O has been unsuccessful.
> 
Right, sorry, I'm not thinking this through, or reading apparently...

I still am not thrilled about adding a new callback, though, at least if 
it can be avoided. In this case I wonder if we can make use of 
sock_reselect_async().

The exact conditions (and timing) under which we need to clear the 
AFD_POLL_WRITE bit are not really clear. In particular the correct 
condition may not be "status != STATUS_SUCCESS" but "status == 
STATUS_PENDING || status == STATUS_DEVICE_NOT_READY". I can't off the 
top of my head think of any interesting cases where send() returns an 
error (other than EWOULDBLOCK) but subsequent calls can succeed...

But assuming that we only really need to clear flags when the kernel 
send buffer is full, I think the right thing to do would be to clear 
events if "async_waiting( &sock->write_q )".



More information about the wine-devel mailing list