From: Zebediah Figura zfigura@codeweavers.com
So that it is done atomically with retrieving events.
Wine-Bug: https://bugs.winehq.org//show_bug.cgi?id=52474 --- dlls/ws2_32/socket.c | 4 +--- dlls/ws2_32/tests/afd.c | 14 ++++++++++++++ server/sock.c | 16 ++++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 5d647d12699..8ef7920e0fc 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3604,10 +3604,8 @@ int WINAPI WSAEnumNetworkEvents( SOCKET s, WSAEVENT event, WSANETWORKEVENTS *ret
TRACE( "socket %#Ix, event %p, events %p\n", s, event, ret_events );
- ResetEvent( event ); - status = NtDeviceIoControlFile( (HANDLE)s, NULL, NULL, NULL, &io, IOCTL_AFD_GET_EVENTS, - NULL, 0, ¶ms, sizeof(params) ); + event, 0, ¶ms, sizeof(params) ); if (!status) { ret_events->lNetworkEvents = afd_poll_flag_to_win32( params.flags ); diff --git a/dlls/ws2_32/tests/afd.c b/dlls/ws2_32/tests/afd.c index 97139605bf1..b856caee853 100644 --- a/dlls/ws2_32/tests/afd.c +++ b/dlls/ws2_32/tests/afd.c @@ -1969,6 +1969,20 @@ static void test_get_events(void) for (i = 0; i < ARRAY_SIZE(params.status); ++i) ok(!params.status[i], "got status[%u] %#x\n", i, params.status[i]);
+ SetEvent(event); + + memset(¶ms, 0xcc, sizeof(params)); + memset(&io, 0xcc, sizeof(io)); + ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io, + IOCTL_AFD_GET_EVENTS, event, 0, ¶ms, sizeof(params)); + ok(!ret, "got %#x\n", ret); + ok(!params.flags, "got flags %#x\n", params.flags); + for (i = 0; i < ARRAY_SIZE(params.status); ++i) + ok(!params.status[i], "got status[%u] %#x\n", i, params.status[i]); + + ret = WaitForSingleObject(event, 0); + ok(ret == WAIT_TIMEOUT, "got %d\n", ret); + closesocket(client); closesocket(server);
diff --git a/server/sock.c b/server/sock.c index f24abd2ab6f..550fe61e477 100644 --- a/server/sock.c +++ b/server/sock.c @@ -3919,6 +3919,7 @@ DECL_HANDLER(socket_get_events) { struct sock *sock = (struct sock *)get_handle_obj( current->process, req->handle, 0, &sock_ops ); unsigned int status[13]; + struct event *event = NULL; unsigned int i;
if (get_reply_max_size() < sizeof(status)) @@ -3929,6 +3930,15 @@ DECL_HANDLER(socket_get_events)
if (!sock) return;
+ if (req->event) + { + if (!(event = get_event_obj( current->process, req->event, EVENT_MODIFY_STATE ))) + { + release_object( sock ); + return; + } + } + reply->flags = sock->pending_events & sock->mask; for (i = 0; i < ARRAY_SIZE( status ); ++i) status[i] = sock_get_ntstatus( sock->errors[i] ); @@ -3936,6 +3946,12 @@ DECL_HANDLER(socket_get_events) sock->pending_events &= ~sock->mask; sock_reselect( sock );
+ if (event) + { + reset_event( event ); + release_object( event ); + } + set_reply_data( status, sizeof(status) );
release_object( sock );