Zebediah Figura : ws2_32: Use socket_apc for WSAIoctl() completion.
Alexandre Julliard
julliard at winehq.org
Tue Jun 1 16:04:32 CDT 2021
Module: wine
Branch: master
Commit: 2ead3a1124589d70ad9dddf04b4f5d195a179118
URL: https://source.winehq.org/git/wine.git/?a=commit;h=2ead3a1124589d70ad9dddf04b4f5d195a179118
Author: Zebediah Figura <z.figura12 at gmail.com>
Date: Mon May 31 22:16:36 2021 -0500
ws2_32: Use socket_apc for WSAIoctl() completion.
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ws2_32/socket.c | 119 +++++++--------------------------------------------
1 file changed, 15 insertions(+), 104 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index b6a14c3e4f4..c1f415444df 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -457,78 +457,6 @@ static void socket_list_remove(SOCKET socket)
LeaveCriticalSection(&cs_socket_list);
}
-/****************************************************************
- * Async IO declarations
- ****************************************************************/
-
-typedef NTSTATUS async_callback_t( void *user, IO_STATUS_BLOCK *io, NTSTATUS status );
-
-struct ws2_async_io
-{
- async_callback_t *callback; /* must be the first field */
- struct ws2_async_io *next;
-};
-
-struct ws2_async_shutdown
-{
- struct ws2_async_io io;
- HANDLE hSocket;
- IO_STATUS_BLOCK iosb;
- int type;
-};
-
-struct ws2_async
-{
- struct ws2_async_io io;
- HANDLE hSocket;
- LPWSAOVERLAPPED user_overlapped;
- LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_func;
- IO_STATUS_BLOCK local_iosb;
- struct WS_sockaddr *addr;
- union
- {
- int val; /* for send operations */
- int *ptr; /* for recv operations */
- } addrlen;
- DWORD flags;
- DWORD *lpFlags;
- WSABUF *control;
- unsigned int n_iovecs;
- unsigned int first_iovec;
- struct iovec iovec[1];
-};
-
-static struct ws2_async_io *async_io_freelist;
-
-static void release_async_io( struct ws2_async_io *io )
-{
- for (;;)
- {
- struct ws2_async_io *next = async_io_freelist;
- io->next = next;
- if (InterlockedCompareExchangePointer( (void **)&async_io_freelist, io, next ) == next) return;
- }
-}
-
-static struct ws2_async_io *alloc_async_io( DWORD size, async_callback_t callback )
-{
- /* first free remaining previous fileinfos */
-
- struct ws2_async_io *io = InterlockedExchangePointer( (void **)&async_io_freelist, NULL );
-
- while (io)
- {
- struct ws2_async_io *next = io->next;
- HeapFree( GetProcessHeap(), 0, io );
- io = next;
- }
-
- io = HeapAlloc( GetProcessHeap(), 0, size );
- if (io) io->callback = callback;
- return io;
-}
-
-
typedef struct /* WSAAsyncSelect() control struct */
{
HANDLE service, event, sock;
@@ -1727,20 +1655,6 @@ static BOOL ws_protocol_info(SOCKET s, int unicode, WSAPROTOCOL_INFOW *buffer, i
return TRUE;
}
-/**************************************************************************
- * Functions for handling overlapped I/O
- **************************************************************************/
-
-/* user APC called upon async completion */
-static void WINAPI ws2_async_apc( void *arg, IO_STATUS_BLOCK *iosb, ULONG reserved )
-{
- struct ws2_async *wsa = arg;
-
- if (wsa->completion_func) wsa->completion_func( NtStatusToWSAError(iosb->u.Status),
- iosb->Information, wsa->user_overlapped,
- wsa->flags );
- release_async_io( &wsa->io );
-}
/***********************************************************************
@@ -3283,29 +3197,28 @@ static DWORD server_ioctl_sock( SOCKET s, DWORD code, LPVOID in_buff, DWORD in_s
LPWSAOVERLAPPED overlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE completion )
{
- HANDLE event = overlapped ? overlapped->hEvent : 0;
+ IO_STATUS_BLOCK iosb, *piosb = &iosb;
HANDLE handle = SOCKET2HANDLE( s );
- struct ws2_async *wsa = NULL;
- IO_STATUS_BLOCK *io = (PIO_STATUS_BLOCK)overlapped, iosb;
+ PIO_APC_ROUTINE apc = NULL;
+ HANDLE event = NULL;
void *cvalue = NULL;
NTSTATUS status;
+ if (overlapped)
+ {
+ piosb = (IO_STATUS_BLOCK *)overlapped;
+ if (!((ULONG_PTR)overlapped->hEvent & 1)) cvalue = overlapped;
+ event = overlapped->hEvent;
+ }
+
if (completion)
{
- if (!(wsa = (struct ws2_async *)alloc_async_io( sizeof(*wsa), NULL )))
- return WSA_NOT_ENOUGH_MEMORY;
- wsa->hSocket = handle;
- wsa->user_overlapped = overlapped;
- wsa->completion_func = completion;
- if (!io) io = &wsa->local_iosb;
- cvalue = wsa;
+ event = NULL;
+ cvalue = completion;
+ apc = socket_apc;
}
- else if (!io)
- io = &iosb;
- else if (!((ULONG_PTR)overlapped->hEvent & 1))
- cvalue = overlapped;
- status = NtDeviceIoControlFile( handle, event, wsa ? ws2_async_apc : NULL, cvalue, io, code,
+ status = NtDeviceIoControlFile( handle, event, apc, cvalue, piosb, code,
in_buff, in_size, out_buff, out_size );
if (status == STATUS_NOT_SUPPORTED)
{
@@ -3313,9 +3226,7 @@ static DWORD server_ioctl_sock( SOCKET s, DWORD code, LPVOID in_buff, DWORD in_s
code, code >> 16, (code >> 14) & 3, (code >> 2) & 0xfff, code & 3);
}
else if (status == STATUS_SUCCESS)
- *ret_size = io->Information; /* "Information" is the size written to the output buffer */
-
- if (status != STATUS_PENDING) RtlFreeHeap( GetProcessHeap(), 0, wsa );
+ *ret_size = piosb->Information;
return NtStatusToWSAError( status );
}
More information about the wine-cvs
mailing list