[PATCH 2/2] server: Set the event in IOCTL_AFD_EVENT_SELECT if the socket becomes signaled.

Jinoh Kang jinoh.kang.kr at gmail.com
Fri Jan 7 03:49:30 CST 2022


On 1/6/22 10:03, Zebediah Figura wrote:
> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52335
> Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
> ---
>  dlls/ws2_32/tests/sock.c | 5 ++---
>  server/sock.c            | 5 +++++
>  2 files changed, 7 insertions(+), 3 deletions(-)
> 

[snip]

> diff --git a/server/sock.c b/server/sock.c
> index 736f34feac5..c7378306511 100644
> --- a/server/sock.c
> +++ b/server/sock.c
> @@ -2543,6 +2543,11 @@ static void sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
>          sock->nonblocking = 1;
>  
>          sock_reselect( sock );
> +        /* Explicitly wake the socket up if the mask causes it to become
> +         * signaled. Note that reselecting isn't enough, since we might already
> +         * have had events recorded in sock->reported_events and we don't want
> +         * to select for them again. */
> +        sock_wake_up( sock );

On a second thought, I think it makes sense to follow up almost every
call to sock_reselect() with a call to sock_wake_up().

Generally, an asynchronous socket object, which serves as an emulation layer
between Unix non-blocking I/O and Windows asynchronous I/O, has to maintain two
invariants at any poll() point (ditto for epoll, /dev/poll, or any other
poll-like calls):

1. For all waiters (from WSAPoll, overlapped I/O or otherwise), the
   corresponding flags in the requested poll events mask are set.

2. For all flags set in the intersection (bitwise AND) of the requested poll
   events mask and the returned poll events mask, the correspoding waiters shall
   eventually be notified.  (Note: assumes level-triggered events.)

As you have observed, sock_reselect() serves to establish invariant 1 but in the
process disrupts invariant 2, since it updates flags without taking account the
implicit changes to the set of notified waiters in the process of updating the
mask.

In fact, I think it's sensible to merge sock_reselect() and sock_wake_up() in
one function.

Any thoughts?

>  
>          return;
>      }
> 

-- 
Sincerely,
Jinoh Kang



More information about the wine-devel mailing list