Alexandre Julliard : ws2_32: Don'
t store the socket file descriptor in the async structure,
retrieve it as needed.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Nov 3 07:32:41 CST 2006
Module: wine
Branch: master
Commit: 2765df9f235641b0cd26fd16d286bd691b731bf5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=2765df9f235641b0cd26fd16d286bd691b731bf5
Author: Alexandre Julliard <julliard at winehq.org>
Date: Fri Nov 3 12:03:14 2006 +0100
ws2_32: Don't store the socket file descriptor in the async structure, retrieve it as needed.
---
dlls/ws2_32/socket.c | 94 ++++++++++++++++++++++++--------------------------
1 files changed, 45 insertions(+), 49 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index bc9a39e..b773092 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -190,7 +190,6 @@ typedef struct ws2_async
int *ptr; /* for recv operations */
} addrlen;
DWORD flags;
- int fd;
HANDLE event;
} ws2_async;
@@ -1117,9 +1116,7 @@ static void CALLBACK ws2_async_terminate
{
TRACE( "as: %p uovl %p ovl %p\n", as, as->user_overlapped, iosb );
- wine_server_release_fd( as->hSocket, as->fd );
- if ( as->event != INVALID_HANDLE_VALUE )
- NtSetEvent( as->event, NULL );
+ if (as->event) NtSetEvent( as->event, NULL );
if (as->completion_func)
as->completion_func( NtStatusToWSAError (iosb->u.Status),
@@ -1147,7 +1144,7 @@ static void WINAPI WS2_async_send(void*,
static void WINAPI WS2_async_shutdown( void*, IO_STATUS_BLOCK*, ULONG);
inline static struct ws2_async*
-WS2_make_async(SOCKET s, int fd, enum ws2_mode mode, struct iovec *iovec, DWORD dwBufferCount,
+WS2_make_async(SOCKET s, enum ws2_mode mode, struct iovec *iovec, DWORD dwBufferCount,
LPDWORD lpFlags, struct WS_sockaddr *addr,
LPINT addrlen, LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
@@ -1182,8 +1179,7 @@ WS2_make_async(SOCKET s, int fd, enum ws
wsa->iovec = iovec;
wsa->n_iovecs = dwBufferCount;
wsa->addr = addr;
- wsa->fd = fd;
- wsa->event = INVALID_HANDLE_VALUE;
+ wsa->event = 0;
if ( lpOverlapped )
{
@@ -1199,8 +1195,8 @@ WS2_make_async(SOCKET s, int fd, enum ws
(*piosb)->Information = 0;
(*piosb)->u.Status = STATUS_PENDING;
- TRACE( "wsa %p, h %p, ev %p, fd %d, iosb %p, uov %p, cfunc %p\n",
- wsa, wsa->hSocket, wsa->event, wsa->fd,
+ TRACE( "wsa %p, h %p, ev %p, iosb %p, uov %p, cfunc %p\n",
+ wsa, wsa->hSocket, wsa->event,
*piosb, wsa->user_overlapped, wsa->completion_func );
return wsa;
@@ -1325,15 +1321,21 @@ out:
static void WINAPI WS2_async_recv( void* ovp, IO_STATUS_BLOCK* iosb, ULONG status)
{
ws2_async* wsa = (ws2_async*) ovp;
- int result, err;
+ int result, fd, err;
TRACE( "(%p %p %x)\n", wsa, iosb, status );
switch (status)
{
case STATUS_ALERTED:
- result = WS2_recv( wsa->fd, wsa->iovec, wsa->n_iovecs,
+ if ((iosb->u.Status = wine_server_handle_to_fd( wsa->hSocket, FILE_READ_DATA, &fd, NULL ) ))
+ {
+ ws2_async_terminate(wsa, iosb);
+ break;
+ }
+ result = WS2_recv( fd, wsa->iovec, wsa->n_iovecs,
wsa->addr, wsa->addrlen.ptr, &wsa->flags );
+ wine_server_release_fd( wsa->hSocket, fd );
if (result >= 0)
{
iosb->u.Status = STATUS_SUCCESS;
@@ -1445,7 +1447,7 @@ out:
static void WINAPI WS2_async_send(void* as, IO_STATUS_BLOCK* iosb, ULONG status)
{
ws2_async* wsa = (ws2_async*) as;
- int result;
+ int result, fd;
TRACE( "(%p %p %x)\n", wsa, iosb, status );
@@ -1453,9 +1455,14 @@ static void WINAPI WS2_async_send(void*
{
case STATUS_ALERTED:
if (iosb->u.Status != STATUS_PENDING) FIXME("wrong %08x\n", iosb->u.Status);
+ if ((iosb->u.Status = wine_server_handle_to_fd( wsa->hSocket, FILE_WRITE_DATA, &fd, NULL ) ))
+ {
+ ws2_async_terminate(wsa, iosb);
+ break;
+ }
/* check to see if the data is ready (non-blocking) */
- result = WS2_send( wsa->fd, wsa->iovec, wsa->n_iovecs,
- wsa->addr, wsa->addrlen.val, wsa->flags );
+ result = WS2_send( fd, wsa->iovec, wsa->n_iovecs, wsa->addr, wsa->addrlen.val, wsa->flags );
+ wine_server_release_fd( wsa->hSocket, fd );
if (result >= 0)
{
@@ -1503,18 +1510,24 @@ static void WINAPI WS2_async_send(void*
static void WINAPI WS2_async_shutdown( void* as, PIO_STATUS_BLOCK iosb, ULONG status )
{
ws2_async* wsa = (ws2_async*) as;
- int err = 1;
+ int fd, err = 1;
TRACE( "async %p %d\n", wsa, wsa->mode );
switch (status)
{
case STATUS_ALERTED:
+ if ((iosb->u.Status = wine_server_handle_to_fd( wsa->hSocket, 0, &fd, NULL ) ))
+ {
+ ws2_async_terminate(wsa, iosb);
+ break;
+ }
switch ( wsa->mode )
{
- case ws2m_sd_read: err = shutdown( wsa->fd, 0 ); break;
- case ws2m_sd_write: err = shutdown( wsa->fd, 1 ); break;
+ case ws2m_sd_read: err = shutdown( fd, 0 ); break;
+ case ws2m_sd_write: err = shutdown( fd, 1 ); break;
default: ERR("invalid mode: %d\n", wsa->mode );
}
+ wine_server_release_fd( wsa->hSocket, fd );
iosb->u.Status = err ? wsaErrno() : STATUS_SUCCESS;
if (iosb->u.Status == STATUS_PENDING)
ws2_queue_async(wsa, iosb);
@@ -1534,7 +1547,7 @@ static void WINAPI WS2_async_shutdown( v
*
* Helper function for WS_shutdown() on overlapped sockets.
*/
-static int WS2_register_async_shutdown( SOCKET s, int fd, enum ws2_mode mode )
+static int WS2_register_async_shutdown( SOCKET s, enum ws2_mode mode )
{
struct ws2_async *wsa;
int ret, err = WSAEFAULT;
@@ -1543,7 +1556,7 @@ static int WS2_register_async_shutdown(
LPWSAOVERLAPPED ovl = HeapAlloc(GetProcessHeap(), 0, sizeof( WSAOVERLAPPED ));
IO_STATUS_BLOCK *iosb = NULL;
- TRACE("s %d fd %d mode %d\n", s, fd, mode);
+ TRACE("s %d mode %d\n", s, mode);
if (!ovl)
goto out;
@@ -1551,8 +1564,7 @@ static int WS2_register_async_shutdown(
if ( ovl->hEvent == WSA_INVALID_EVENT )
goto out_free;
- wsa = WS2_make_async( s, fd, mode, NULL, 0,
- &dwflags, NULL, &len, ovl, NULL, &iosb );
+ wsa = WS2_make_async( s, mode, NULL, 0, &dwflags, NULL, &len, ovl, NULL, &iosb );
if ( !wsa )
goto out_close;
@@ -2572,7 +2584,7 @@ INT WINAPI WSASendTo( SOCKET s, LPWSABUF
if ( (lpOverlapped || lpCompletionRoutine) && flags & FD_FLAG_OVERLAPPED )
{
- wsa = WS2_make_async( s, fd, ws2m_write, iovec, dwBufferCount,
+ wsa = WS2_make_async( s, ws2m_write, iovec, dwBufferCount,
&dwFlags, (struct WS_sockaddr*) to, &tolen,
lpOverlapped, lpCompletionRoutine, &iosb );
if ( !wsa )
@@ -2590,6 +2602,7 @@ INT WINAPI WSASendTo( SOCKET s, LPWSABUF
HeapFree( GetProcessHeap(), 0, wsa );
goto err_free;
}
+ release_sock_fd( s, fd );
/* Try immediate completion */
if ( lpOverlapped )
@@ -2822,7 +2835,7 @@ #endif
*/
int WINAPI WS_shutdown(SOCKET s, int how)
{
- int fd, fd0 = -1, fd1 = -1, flags, err = WSAENOTSOCK;
+ int fd, flags, err = WSAENOTSOCK;
unsigned int clear_flags = 0;
fd = get_sock_fd( s, 0, &flags );
@@ -2850,53 +2863,35 @@ int WINAPI WS_shutdown(SOCKET s, int how
switch ( how )
{
case SD_RECEIVE:
- fd0 = fd;
+ err = WS2_register_async_shutdown( s, ws2m_sd_read );
break;
case SD_SEND:
- fd1 = fd;
+ err = WS2_register_async_shutdown( s, ws2m_sd_write );
break;
case SD_BOTH:
default:
- fd0 = fd;
- fd1 = get_sock_fd( s, 0, NULL );
+ err = WS2_register_async_shutdown( s, ws2m_sd_read );
+ if (!err) err = WS2_register_async_shutdown( s, ws2m_sd_write );
break;
}
-
- if ( fd0 != -1 )
- {
- err = WS2_register_async_shutdown( s, fd0, ws2m_sd_read );
- if ( err )
- {
- release_sock_fd( s, fd0 );
- goto error;
- }
- }
- if ( fd1 != -1 )
- {
- err = WS2_register_async_shutdown( s, fd1, ws2m_sd_write );
- if ( err )
- {
- release_sock_fd( s, fd1 );
- goto error;
- }
- }
+ if (err) goto error;
}
else /* non-overlapped mode */
{
if ( shutdown( fd, how ) )
{
err = wsaErrno();
- release_sock_fd( s, fd );
goto error;
}
- release_sock_fd( s, fd );
}
+ release_sock_fd( s, fd );
_enable_event( SOCKET2HANDLE(s), 0, 0, clear_flags );
if ( how > 1) WSAAsyncSelect( s, 0, 0, 0 );
return 0;
error:
+ release_sock_fd( s, fd );
_enable_event( SOCKET2HANDLE(s), 0, 0, clear_flags );
WSASetLastError( err );
return SOCKET_ERROR;
@@ -3967,7 +3962,7 @@ INT WINAPI WSARecvFrom( SOCKET s, LPWSAB
if ( (lpOverlapped || lpCompletionRoutine) && flags & FD_FLAG_OVERLAPPED )
{
- wsa = WS2_make_async( s, fd, ws2m_read, iovec, dwBufferCount,
+ wsa = WS2_make_async( s, ws2m_read, iovec, dwBufferCount,
lpFlags, lpFrom, lpFromlen,
lpOverlapped, lpCompletionRoutine, &iosb );
@@ -3986,6 +3981,7 @@ INT WINAPI WSARecvFrom( SOCKET s, LPWSAB
HeapFree( GetProcessHeap(), 0, wsa );
goto err_free;
}
+ release_sock_fd( s, fd );
/* Try immediate completion */
if ( lpOverlapped )
More information about the wine-cvs
mailing list