ws2_32: Allocate iovec buffers statically using MSG_MAXIOVLEN.
This commit is contained in:
parent
14fceb2cb6
commit
9db8574540
|
@ -189,7 +189,7 @@ typedef struct ws2_async
|
||||||
LPWSAOVERLAPPED user_overlapped;
|
LPWSAOVERLAPPED user_overlapped;
|
||||||
LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_func;
|
LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_func;
|
||||||
IO_STATUS_BLOCK local_iosb;
|
IO_STATUS_BLOCK local_iosb;
|
||||||
struct iovec *iovec;
|
struct iovec iovec[WS_MSG_MAXIOVLEN];
|
||||||
int n_iovecs;
|
int n_iovecs;
|
||||||
struct WS_sockaddr *addr;
|
struct WS_sockaddr *addr;
|
||||||
union
|
union
|
||||||
|
@ -1033,7 +1033,6 @@ static void ws2_async_terminate(ws2_async* as, IO_STATUS_BLOCK* iosb, NTSTATUS s
|
||||||
as->completion_func( NtStatusToWSAError(status),
|
as->completion_func( NtStatusToWSAError(status),
|
||||||
count, as->user_overlapped, as->flags );
|
count, as->user_overlapped, as->flags );
|
||||||
|
|
||||||
HeapFree( GetProcessHeap(), 0, as->iovec );
|
|
||||||
HeapFree( GetProcessHeap(), 0, as );
|
HeapFree( GetProcessHeap(), 0, as );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1078,7 +1077,7 @@ WS2_make_async(SOCKET s, enum ws2_mode mode, struct iovec *iovec, DWORD dwBuffer
|
||||||
}
|
}
|
||||||
wsa->user_overlapped = lpOverlapped;
|
wsa->user_overlapped = lpOverlapped;
|
||||||
wsa->completion_func = lpCompletionRoutine;
|
wsa->completion_func = lpCompletionRoutine;
|
||||||
wsa->iovec = iovec;
|
memcpy( wsa->iovec, iovec, dwBufferCount * sizeof(*iovec) );
|
||||||
wsa->n_iovecs = dwBufferCount;
|
wsa->n_iovecs = dwBufferCount;
|
||||||
wsa->addr = addr;
|
wsa->addr = addr;
|
||||||
wsa->event = 0;
|
wsa->event = 0;
|
||||||
|
@ -2697,7 +2696,7 @@ INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
|
||||||
{
|
{
|
||||||
unsigned int i, options;
|
unsigned int i, options;
|
||||||
int n, fd, err = WSAENOTSOCK, ret;
|
int n, fd, err = WSAENOTSOCK, ret;
|
||||||
struct iovec* iovec;
|
struct iovec iovec[WS_MSG_MAXIOVLEN];
|
||||||
struct ws2_async *wsa;
|
struct ws2_async *wsa;
|
||||||
IO_STATUS_BLOCK* iosb;
|
IO_STATUS_BLOCK* iosb;
|
||||||
|
|
||||||
|
@ -2705,6 +2704,12 @@ INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
|
||||||
s, lpBuffers, dwBufferCount, dwFlags,
|
s, lpBuffers, dwBufferCount, dwFlags,
|
||||||
to, tolen, lpOverlapped, lpCompletionRoutine);
|
to, tolen, lpOverlapped, lpCompletionRoutine);
|
||||||
|
|
||||||
|
if (dwBufferCount > WS_MSG_MAXIOVLEN)
|
||||||
|
{
|
||||||
|
WSASetLastError( WSAEINVAL );
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
fd = get_sock_fd( s, FILE_WRITE_DATA, &options );
|
fd = get_sock_fd( s, FILE_WRITE_DATA, &options );
|
||||||
TRACE( "fd=%d, options=%x\n", fd, options );
|
TRACE( "fd=%d, options=%x\n", fd, options );
|
||||||
|
|
||||||
|
@ -2713,15 +2718,7 @@ INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
|
||||||
if ( !lpNumberOfBytesSent )
|
if ( !lpNumberOfBytesSent )
|
||||||
{
|
{
|
||||||
err = WSAEFAULT;
|
err = WSAEFAULT;
|
||||||
goto err_close;
|
goto error;
|
||||||
}
|
|
||||||
|
|
||||||
iovec = HeapAlloc(GetProcessHeap(), 0, dwBufferCount * sizeof(struct iovec) );
|
|
||||||
|
|
||||||
if ( !iovec )
|
|
||||||
{
|
|
||||||
err = WSAEFAULT;
|
|
||||||
goto err_close;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( i = 0; i < dwBufferCount; i++ )
|
for ( i = 0; i < dwBufferCount; i++ )
|
||||||
|
@ -2739,7 +2736,7 @@ INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
|
||||||
if ( !wsa )
|
if ( !wsa )
|
||||||
{
|
{
|
||||||
err = WSAEFAULT;
|
err = WSAEFAULT;
|
||||||
goto err_free;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = ws2_queue_async( wsa, iosb )) != STATUS_PENDING)
|
if ((ret = ws2_queue_async( wsa, iosb )) != STATUS_PENDING)
|
||||||
|
@ -2747,7 +2744,7 @@ INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
|
||||||
err = NtStatusToWSAError( ret );
|
err = NtStatusToWSAError( ret );
|
||||||
|
|
||||||
HeapFree( GetProcessHeap(), 0, wsa );
|
HeapFree( GetProcessHeap(), 0, wsa );
|
||||||
goto err_free;
|
goto error;
|
||||||
}
|
}
|
||||||
release_sock_fd( s, fd );
|
release_sock_fd( s, fd );
|
||||||
|
|
||||||
|
@ -2759,7 +2756,7 @@ INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ( (err = WSAGetLastError()) != WSA_IO_INCOMPLETE )
|
if ( (err = WSAGetLastError()) != WSA_IO_INCOMPLETE )
|
||||||
goto error;
|
return SOCKET_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
WSASetLastError( WSA_IO_PENDING );
|
WSASetLastError( WSA_IO_PENDING );
|
||||||
|
@ -2789,14 +2786,14 @@ INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
|
||||||
/* FIXME: exceptfds? */
|
/* FIXME: exceptfds? */
|
||||||
if( !do_block(fd, POLLOUT, timeout)) {
|
if( !do_block(fd, POLLOUT, timeout)) {
|
||||||
err = WSAETIMEDOUT;
|
err = WSAETIMEDOUT;
|
||||||
goto err_free; /* msdn says a timeout in send is fatal */
|
goto error; /* msdn says a timeout in send is fatal */
|
||||||
}
|
}
|
||||||
|
|
||||||
n = WS2_send( fd, piovec, dwBufferCount, to, tolen, dwFlags );
|
n = WS2_send( fd, piovec, dwBufferCount, to, tolen, dwFlags );
|
||||||
if ( n == -1 )
|
if ( n == -1 )
|
||||||
{
|
{
|
||||||
err = wsaErrno();
|
err = wsaErrno();
|
||||||
goto err_free;
|
goto error;
|
||||||
}
|
}
|
||||||
*lpNumberOfBytesSent += n;
|
*lpNumberOfBytesSent += n;
|
||||||
|
|
||||||
|
@ -2825,7 +2822,7 @@ INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
|
||||||
err = wsaErrno();
|
err = wsaErrno();
|
||||||
if ( err == WSAEWOULDBLOCK )
|
if ( err == WSAEWOULDBLOCK )
|
||||||
_enable_event(SOCKET2HANDLE(s), FD_WRITE, 0, 0);
|
_enable_event(SOCKET2HANDLE(s), FD_WRITE, 0, 0);
|
||||||
goto err_free;
|
goto error;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
_enable_event(SOCKET2HANDLE(s), FD_WRITE, 0, 0);
|
_enable_event(SOCKET2HANDLE(s), FD_WRITE, 0, 0);
|
||||||
|
@ -2834,17 +2831,11 @@ INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
|
||||||
|
|
||||||
TRACE(" -> %i bytes\n", *lpNumberOfBytesSent);
|
TRACE(" -> %i bytes\n", *lpNumberOfBytesSent);
|
||||||
|
|
||||||
HeapFree( GetProcessHeap(), 0, iovec );
|
|
||||||
release_sock_fd( s, fd );
|
release_sock_fd( s, fd );
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_free:
|
|
||||||
HeapFree( GetProcessHeap(), 0, iovec );
|
|
||||||
|
|
||||||
err_close:
|
|
||||||
release_sock_fd( s, fd );
|
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
release_sock_fd( s, fd );
|
||||||
WARN(" -> ERROR %d\n", err);
|
WARN(" -> ERROR %d\n", err);
|
||||||
WSASetLastError(err);
|
WSASetLastError(err);
|
||||||
return SOCKET_ERROR;
|
return SOCKET_ERROR;
|
||||||
|
@ -4200,7 +4191,7 @@ INT WINAPI WSARecvFrom( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
|
||||||
unsigned int i, options;
|
unsigned int i, options;
|
||||||
int n, fd, err;
|
int n, fd, err;
|
||||||
DWORD timeout_start = GetTickCount();
|
DWORD timeout_start = GetTickCount();
|
||||||
struct iovec* iovec;
|
struct iovec iovec[WS_MSG_MAXIOVLEN];
|
||||||
struct ws2_async *wsa;
|
struct ws2_async *wsa;
|
||||||
IO_STATUS_BLOCK* iosb;
|
IO_STATUS_BLOCK* iosb;
|
||||||
|
|
||||||
|
@ -4209,18 +4200,17 @@ INT WINAPI WSARecvFrom( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
|
||||||
(lpFromlen ? *lpFromlen : -1),
|
(lpFromlen ? *lpFromlen : -1),
|
||||||
lpOverlapped, lpCompletionRoutine);
|
lpOverlapped, lpCompletionRoutine);
|
||||||
|
|
||||||
|
if (dwBufferCount > WS_MSG_MAXIOVLEN)
|
||||||
|
{
|
||||||
|
WSASetLastError( WSAEINVAL );
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
fd = get_sock_fd( s, FILE_READ_DATA, &options );
|
fd = get_sock_fd( s, FILE_READ_DATA, &options );
|
||||||
TRACE( "fd=%d, options=%x\n", fd, options );
|
TRACE( "fd=%d, options=%x\n", fd, options );
|
||||||
|
|
||||||
if (fd == -1) return SOCKET_ERROR;
|
if (fd == -1) return SOCKET_ERROR;
|
||||||
|
|
||||||
iovec = HeapAlloc( GetProcessHeap(), 0, dwBufferCount * sizeof (struct iovec) );
|
|
||||||
if ( !iovec )
|
|
||||||
{
|
|
||||||
err = WSAEFAULT;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < dwBufferCount; i++)
|
for (i = 0; i < dwBufferCount; i++)
|
||||||
{
|
{
|
||||||
iovec[i].iov_base = lpBuffers[i].buf;
|
iovec[i].iov_base = lpBuffers[i].buf;
|
||||||
|
@ -4308,14 +4298,12 @@ INT WINAPI WSARecvFrom( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
|
||||||
TRACE(" -> %i bytes\n", n);
|
TRACE(" -> %i bytes\n", n);
|
||||||
*lpNumberOfBytesRecvd = n;
|
*lpNumberOfBytesRecvd = n;
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, iovec);
|
|
||||||
release_sock_fd( s, fd );
|
release_sock_fd( s, fd );
|
||||||
_enable_event(SOCKET2HANDLE(s), FD_READ, 0, 0);
|
_enable_event(SOCKET2HANDLE(s), FD_READ, 0, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
HeapFree(GetProcessHeap(), 0, iovec);
|
|
||||||
release_sock_fd( s, fd );
|
release_sock_fd( s, fd );
|
||||||
WARN(" -> ERROR %d\n", err);
|
WARN(" -> ERROR %d\n", err);
|
||||||
WSASetLastError( err );
|
WSASetLastError( err );
|
||||||
|
|
Loading…
Reference in New Issue