ntdll: Locally duplicated socket fd for background send.

This commit is contained in:
Paul Gofman 2024-09-13 14:13:21 -06:00 committed by Alexandre Julliard
parent 535c8a84c1
commit d9a123b6cf
Notes: Alexandre Julliard 2024-09-18 23:20:34 +02:00
Approved-by: Elizabeth Figura (@zfigura)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/wine/merge_requests/6490
2 changed files with 11 additions and 2 deletions

View file

@ -130,6 +130,7 @@ struct async_send_ioctl
unsigned int sent_len;
unsigned int count;
unsigned int iov_cursor;
int fd;
struct iovec iov[1];
};
@ -1060,7 +1061,8 @@ static BOOL async_send_proc( void *user, ULONG_PTR *info, unsigned int *status )
if (*status == STATUS_ALERTED)
{
if ((*status = server_get_unix_fd( async->io.handle, 0, &fd, &needs_close, NULL, NULL )))
needs_close = FALSE;
if ((fd = async->fd) == -1 && (*status = server_get_unix_fd( async->io.handle, 0, &fd, &needs_close, NULL, NULL )))
return TRUE;
*status = try_send( fd, async );
@ -1072,6 +1074,7 @@ static BOOL async_send_proc( void *user, ULONG_PTR *info, unsigned int *status )
return FALSE;
}
*info = async->sent_len;
if (async->fd != -1) close( async->fd );
release_fileio( &async->io );
return TRUE;
}
@ -1162,6 +1165,7 @@ static NTSTATUS sock_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi
else
{
/* Use a local copy of socket fd so the async send works after socket handle is closed. */
rem_async->fd = dup( fd );
rem_async->count = 1;
p = (char *)rem_async + offsetof( struct async_send_ioctl, iov[1] );
rem_async->iov[0].iov_base = p;
@ -1197,7 +1201,10 @@ static NTSTATUS sock_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi
}
if (status != STATUS_PENDING)
{
if (async->fd != -1) close( async->fd );
release_fileio( &async->io );
}
if (wait_handle) status = wait_async( wait_handle, options & FILE_SYNCHRONOUS_IO_ALERT );
return status;
@ -1237,6 +1244,7 @@ static NTSTATUS sock_ioctl_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
async->iov[i].iov_len = buffers[i].len;
}
}
async->fd = -1;
async->unix_flags = unix_flags;
async->addr = addr;
async->addr_len = addr_len;
@ -1256,6 +1264,7 @@ NTSTATUS sock_write( HANDLE handle, int fd, HANDLE event, PIO_APC_ROUTINE apc,
if (!(async = (struct async_send_ioctl *)alloc_fileio( async_size, async_send_proc, handle )))
return STATUS_NO_MEMORY;
async->fd = -1;
async->count = 1;
async->iov[0].iov_base = (void *)buffer;
async->iov[0].iov_len = length;

View file

@ -14339,7 +14339,7 @@ static void test_send_buffering(void)
ok(recv_size <= d.sent_size, "got ret %d, recv_size %d, sent_size %d.\n", ret, recv_size, d.sent_size);
}
ok(!ret && !WSAGetLastError(), "got ret %d, error %u.\n", ret, WSAGetLastError());
todo_wine ok(recv_size == d.sent_size, "got %d, expected %d.\n", recv_size, d.sent_size);
ok(recv_size == d.sent_size, "got %d, expected %d.\n", recv_size, d.sent_size);
closesocket(client);
/* Test with the other thread which terminates before the data is actually sent. */