ws2_32: Queue a proper user APC also on immediate success in WSARecvFrom/WSASendTo.

This commit is contained in:
Alexandre Julliard 2007-06-04 17:44:24 +02:00
parent 8992f89f27
commit e32252efae
1 changed files with 82 additions and 51 deletions

View File

@ -2634,9 +2634,7 @@ INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
n = WS2_send( fd, iovec, dwBufferCount, to, tolen, dwFlags );
if (n != -1 || errno != EINTR) break;
}
if (n == -1)
{
if (errno != EAGAIN)
if (n == -1 && errno != EAGAIN)
{
err = wsaErrno();
goto error;
@ -2665,6 +2663,8 @@ INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
memcpy( wsa->iovec, iovec, dwBufferCount * sizeof(*iovec) );
iosb = lpOverlapped ? (IO_STATUS_BLOCK *)lpOverlapped : &wsa->local_iosb;
if (n == -1)
{
iosb->u.Status = STATUS_PENDING;
iosb->Information = 0;
@ -2689,6 +2689,18 @@ INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
WSASetLastError( NtStatusToWSAError( err ));
return SOCKET_ERROR;
}
iosb->u.Status = STATUS_SUCCESS;
iosb->Information = n;
*lpNumberOfBytesSent = n;
if (!wsa->completion_func)
{
SetEvent( lpOverlapped->hEvent );
HeapFree( GetProcessHeap(), 0, wsa );
}
else NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)ws2_async_apc,
(ULONG_PTR)wsa, (ULONG_PTR)iosb, 0 );
return 0;
}
if ( _is_blocking(s) )
@ -4140,14 +4152,17 @@ INT WINAPI WSARecvFrom( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
for (;;)
{
n = WS2_recv( fd, iovec, dwBufferCount, lpFrom, lpFromlen, lpFlags );
if (n != -1) break;
if (n == -1)
{
if (errno == EINTR) continue;
if (errno != EAGAIN)
{
err = wsaErrno();
goto error;
}
}
else
*lpNumberOfBytesRecvd = n;
if ((lpOverlapped || lpCompletionRoutine) &&
!(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)))
@ -4172,6 +4187,9 @@ INT WINAPI WSARecvFrom( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
memcpy( wsa->iovec, iovec, dwBufferCount * sizeof(*iovec) );
iosb = lpOverlapped ? (IO_STATUS_BLOCK *)lpOverlapped : &wsa->local_iosb;
if (n == -1)
{
iosb->u.Status = STATUS_PENDING;
iosb->Information = 0;
@ -4197,6 +4215,21 @@ INT WINAPI WSARecvFrom( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
return SOCKET_ERROR;
}
iosb->u.Status = STATUS_SUCCESS;
iosb->Information = n;
if (!wsa->completion_func)
{
SetEvent( lpOverlapped->hEvent );
HeapFree( GetProcessHeap(), 0, wsa );
}
else NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)ws2_async_apc,
(ULONG_PTR)wsa, (ULONG_PTR)iosb, 0 );
_enable_event(SOCKET2HANDLE(s), FD_READ, 0, 0);
return 0;
}
if (n != -1) break;
if ( _is_blocking(s) )
{
struct pollfd pfd;
@ -4228,8 +4261,6 @@ INT WINAPI WSARecvFrom( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
}
TRACE(" -> %i bytes\n", n);
*lpNumberOfBytesRecvd = n;
release_sock_fd( s, fd );
_enable_event(SOCKET2HANDLE(s), FD_READ, 0, 0);