[PATCH 2/2 resent] ws2_32: Add tests for exclusive flag for IOCTL_AFD_POLL.

Guillaume Charifi-Hoareau guillaume.charifi at sfr.fr
Thu Sep 2 12:41:04 CDT 2021


Here is an updated job with easier to read comments:
https://testbot.winehq.org/JobDetails.pl?Key=97235[1]

Le jeudi 2 septembre 2021, 19:08:43 CEST Guillaume Charifi-Hoareau a écrit :
> Thank you for your answer!
> 
> 
> I spent a lot of time testing a whole lot of different combinations and the
> results still confused me...
> 
> > There's also a part of me that would like to know what can possibly be
> > the point of this API; it's hard to even think of what "reasonable"
> > behaviour is otherwise. Do you happen to know?
> > 
> > My best guess is that it's meant to explicitly interrupt poll requests
> > somehow (what, I/O cancellation wasn't good enough for them?), in which
> > case it'd be good to explicitly confirm or refute that the "exclusive"
> > poll really does act like a normal poll, and doesn't e.g. return
> > immediately.
> 
> I discovered this behavior while investigating an app that seemed to rely on
> them to interrupt some polls, and so far it seems to be its sole purpose.
> There is only one reason I can imagine a use for this instead of CancelIo():
> As the NtDeviceIoControlFile()'s file handle is independent of the socket
> in params, it provides a way to interrupt another poll that waits on the
> same socket without the need to know the file handle that was originally
> given to it.
> 
> Regardless its behaviour is kind of crazy.
> I tried to restrict to a subset of the tests to avoid polluting test_poll()
> too much, but indeed it requires an entire function to test it properly.
> 
> > I think these tests could be more extensive. For example:
> > 
> > * What happens if you try to perform a non-exclusive wait while an
> > exclusive wait is in progress? i.e. the inverse of the test added here.
> 
> So after some extensive testing, I'm rather confident that the logic for a
> new poll on a socket is:
> (The main poll is an arbitrary designation for one of the poll waiting on
> the socket) If there is no main poll on the socket, then the new poll
> becomes the main poll. If the main poll is terminated, then there is no
> main poll anymore. If the main poll is exclusive and the new poll is
> exclusive, then the main poll is terminated and the new poll becomes the
> main poll.
> 
> 
> The flag does not seem to do anything more than this (apart from requiring
> 0x7fffffff00000000 <= timeout <= 0x7fffffffffffffff).
> 
> > * Can we verify that exclusive waits are specific to a given socket
> > (i.e. you can simultaneously do an exclusive wait on two different
> > sockets?)
> Yes, the mechanism described earlier seems to be done on a per-socket basis.
> > * Can we test that exclusive waits apply if two unequal sets overlap?
> 
> Yes, it works the same way (a single common socket between exclusive polls
> is enough to wake the poll)
> 
> > * Can you do an exclusive wait on the same socket from two different
> > threads?
> 
> Can yes, didn't want to, but did it anyway :)
> I get the expected result: It works exactly the same as the single threaded
> version.
> 
> So I guess I now have enough insight to write a proper implementation.
> The patch for the tests is attached to this job:
> https://testbot.winehq.org/JobDetails.pl? Key=97234[1]
> Feel free to tell me if other tests come to your mind.
> 
> Le mercredi 1 septembre 2021, 17:52:14 CEST Guillaume Charifi a écrit :
> > Signed-off-by: Guillaume Charifi <guillaume.charifi at sfr.fr>
> > ---
> > 
> >  dlls/ws2_32/tests/afd.c | 73 ++++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 72 insertions(+), 1 deletion(-)
> > 
> > diff --git a/dlls/ws2_32/tests/afd.c b/dlls/ws2_32/tests/afd.c
> > index eb7c8ee50de..2568f251b6f 100644
> > --- a/dlls/ws2_32/tests/afd.c
> > +++ b/dlls/ws2_32/tests/afd.c
> > @@ -148,8 +148,10 @@ static void test_poll(void)
> > 
> >      const struct sockaddr_in bind_addr = {.sin_family = AF_INET,
> > 
> > .sin_addr.s_addr = htonl(INADDR_LOOPBACK)}; char in_buffer[offsetof(struct
> > afd_poll_params, sockets[3])]; char out_buffer[offsetof(struct
> > afd_poll_params, sockets[3])]; +    char out_buffer1[offsetof(struct
> > afd_poll_params, sockets[3])]; struct afd_poll_params *in_params = (struct
> > afd_poll_params *)in_buffer; struct afd_poll_params *out_params = (struct
> > afd_poll_params *)out_buffer; +    struct afd_poll_params *out_params1 =
> > (struct afd_poll_params *)out_buffer1; int large_buffer_size = 1024 *
> > 1024;
> > 
> >      SOCKET client, server, listener;
> >      struct sockaddr_in addr;
> > 
> > @@ -157,13 +159,14 @@ static void test_poll(void)
> > 
> >      IO_STATUS_BLOCK io;
> >      LARGE_INTEGER now;
> >      ULONG params_size;
> > 
> > -    HANDLE event;
> > +    HANDLE event, event1;
> > 
> >      int ret, len;
> >      
> >      large_buffer = malloc(large_buffer_size);
> >      memset(in_buffer, 0, sizeof(in_buffer));
> >      memset(out_buffer, 0, sizeof(out_buffer));
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20210902/1603d513/attachment.htm>


More information about the wine-devel mailing list