[PATCH 2/2] ws2_32: Use allocated IO status block in select().
Paul Gofman
wine at gitlab.winehq.org
Tue May 24 21:00:37 CDT 2022
From: Paul Gofman <pgofman at codeweavers.com>
---
dlls/ws2_32/socket.c | 61 +++++++++++++++++++++++++++++++++++++++++---
1 file changed, 58 insertions(+), 3 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 6507f2e3c5b..009b4882564 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -157,6 +157,57 @@ DECLARE_CRITICAL_SECTION(cs_socket_list);
static SOCKET *socket_list;
static unsigned int socket_list_size;
+struct io_buf
+{
+ struct io_buf *next;
+ IO_STATUS_BLOCK io;
+};
+static struct io_buf *io_freelist;
+
+static IO_STATUS_BLOCK *alloc_io(void)
+{
+ struct io_buf *io, *ret, *next;
+
+ if (!(io = InterlockedExchangePointer( (void **)&io_freelist, NULL )))
+ {
+ if (!(io = malloc(sizeof(*io))))
+ {
+ ERR( "No memory.\n" );
+ return NULL;
+ }
+ return &io->io;
+ }
+
+ ret = io;
+ next = io->next;
+ if (next && InterlockedCompareExchangePointer( (void **)&io_freelist, next, NULL ))
+ {
+ while ((io = next))
+ {
+ next = io->next;
+ free( io );
+ }
+ }
+ return &ret->io;
+}
+
+static void free_io(IO_STATUS_BLOCK *io_data)
+{
+ struct io_buf *io, *next;
+
+ if (!io_data) return;
+
+ io = CONTAINING_RECORD(io_data, struct io_buf, io);
+
+ while (1)
+ {
+ next = io_freelist;
+ io->next = next;
+ if (InterlockedCompareExchangePointer( (void **)&io_freelist, io, next ) == next)
+ return;
+ }
+}
+
const char *debugstr_sockaddr( const struct sockaddr *a )
{
if (!a) return "(nil)";
@@ -2529,7 +2580,7 @@ int WINAPI select( int count, fd_set *read_ptr, fd_set *write_ptr,
unsigned int poll_count = 0;
ULONG params_size, i, j;
SOCKET poll_socket = 0;
- IO_STATUS_BLOCK io;
+ IO_STATUS_BLOCK *io;
HANDLE sync_event;
int ret_count = 0;
NTSTATUS status;
@@ -2605,7 +2656,8 @@ int WINAPI select( int count, fd_set *read_ptr, fd_set *write_ptr,
assert( params->count == poll_count );
- status = NtDeviceIoControlFile( (HANDLE)poll_socket, sync_event, NULL, NULL, &io,
+ io = alloc_io();
+ status = NtDeviceIoControlFile( (HANDLE)poll_socket, sync_event, NULL, NULL, io,
IOCTL_AFD_POLL, params, params_size, params, params_size );
if (status == STATUS_PENDING)
{
@@ -2613,10 +2665,13 @@ int WINAPI select( int count, fd_set *read_ptr, fd_set *write_ptr,
{
free( read_input );
free( params );
+ free_io( io );
return -1;
}
- status = io.u.Status;
+ status = io->u.Status;
}
+ free_io( io );
+
if (status == STATUS_TIMEOUT) status = STATUS_SUCCESS;
if (!status)
{
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/127
More information about the wine-devel
mailing list