Alexandre Julliard : ws2_32: Simplify the async shutdown handling,
and remove a bunch of no longer used code.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Jun 4 08:14:25 CDT 2007
Module: wine
Branch: master
Commit: f2febca8f6fb049ec53dc641825780a445ad2df7
URL: http://source.winehq.org/git/wine.git/?a=commit;h=f2febca8f6fb049ec53dc641825780a445ad2df7
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu May 31 17:51:18 2007 +0200
ws2_32: Simplify the async shutdown handling, and remove a bunch of no longer used code.
---
dlls/ws2_32/socket.c | 188 ++++++++++---------------------------------------
1 files changed, 39 insertions(+), 149 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index a72c6b5..6f883b4 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -185,7 +185,7 @@ static inline const char *debugstr_sockaddr( const struct WS_sockaddr *a )
typedef struct ws2_async
{
HANDLE hSocket;
- enum ws2_mode {ws2m_read, ws2m_write, ws2m_sd_read, ws2m_sd_write} mode;
+ int type;
LPWSAOVERLAPPED user_overlapped;
LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_func;
IO_STATUS_BLOCK local_iosb;
@@ -198,7 +198,6 @@ typedef struct ws2_async
int *ptr; /* for recv operations */
} addrlen;
DWORD flags;
- HANDLE event;
} ws2_async;
/****************************************************************/
@@ -1023,115 +1022,6 @@ static int ws_sockaddr_u2ws(const struct sockaddr* uaddr, struct WS_sockaddr* ws
* Functions for handling overlapped I/O
**************************************************************************/
-static void ws2_async_terminate(ws2_async* as, IO_STATUS_BLOCK* iosb, NTSTATUS status, ULONG count)
-{
- TRACE( "as: %p uovl %p ovl %p\n", as, as->user_overlapped, iosb );
-
- iosb->u.Status = status;
- iosb->Information = count;
- if (as->completion_func)
- as->completion_func( NtStatusToWSAError(status),
- count, as->user_overlapped, as->flags );
-
- HeapFree( GetProcessHeap(), 0, as );
-}
-
-/***********************************************************************
- * WS2_make_async (INTERNAL)
- */
-
-static NTSTATUS WS2_async_recv(void*, IO_STATUS_BLOCK*, NTSTATUS);
-static NTSTATUS WS2_async_send(void*, IO_STATUS_BLOCK*, NTSTATUS);
-static NTSTATUS WS2_async_shutdown( void*, IO_STATUS_BLOCK*, NTSTATUS);
-
-static inline struct ws2_async*
-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,
- IO_STATUS_BLOCK **piosb)
-{
- struct ws2_async *wsa = HeapAlloc( GetProcessHeap(), 0, sizeof( ws2_async ) );
-
- TRACE( "wsa %p\n", wsa );
-
- if (!wsa)
- return NULL;
-
- wsa->hSocket = (HANDLE) s;
- wsa->mode = mode;
- switch (mode)
- {
- case ws2m_read:
- case ws2m_sd_read:
- wsa->flags = *lpFlags;
- wsa->addrlen.ptr = addrlen;
- break;
- case ws2m_write:
- case ws2m_sd_write:
- wsa->flags = 0;
- wsa->addrlen.val = *addrlen;
- break;
- default:
- ERR("Invalid async mode: %d\n", mode);
- }
- wsa->user_overlapped = lpOverlapped;
- wsa->completion_func = lpCompletionRoutine;
- memcpy( wsa->iovec, iovec, dwBufferCount * sizeof(*iovec) );
- wsa->n_iovecs = dwBufferCount;
- wsa->addr = addr;
- wsa->event = 0;
-
- if ( lpOverlapped )
- {
- *piosb = (IO_STATUS_BLOCK*)lpOverlapped;
- if (!lpCompletionRoutine)
- wsa->event = lpOverlapped->hEvent;
- }
- else
- *piosb = &wsa->local_iosb;
-
- 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;
-}
-
-static ULONG ws2_queue_async(struct ws2_async* wsa, IO_STATUS_BLOCK* iosb)
-{
- NTSTATUS (*apc)(void *, IO_STATUS_BLOCK *, NTSTATUS);
- int type;
- NTSTATUS status;
-
- switch (wsa->mode)
- {
- case ws2m_read: apc = WS2_async_recv; type = ASYNC_TYPE_READ; break;
- case ws2m_write: apc = WS2_async_send; type = ASYNC_TYPE_WRITE; break;
- case ws2m_sd_read: apc = WS2_async_shutdown; type = ASYNC_TYPE_READ; break;
- case ws2m_sd_write: apc = WS2_async_shutdown; type = ASYNC_TYPE_WRITE; break;
- default: FIXME("Unknown internal mode (%d)\n", wsa->mode); return STATUS_INVALID_PARAMETER;
- }
-
- SERVER_START_REQ( register_async )
- {
- req->handle = wsa->hSocket;
- req->async.callback = apc;
- req->async.iosb = iosb;
- req->async.arg = wsa;
- req->async.event = wsa->event;
- req->type = type;
- status = wine_server_call( req );
- }
- SERVER_END_REQ;
-
- if (status != STATUS_PENDING)
- ws2_async_terminate(wsa, iosb, status, 0);
- else
- NtCurrentTeb()->num_async_io++;
- return status;
-}
-
/* user APC called upon async completion */
static void WINAPI ws2_async_apc( void *arg, IO_STATUS_BLOCK *iosb, ULONG reserved )
{
@@ -1381,24 +1271,23 @@ static NTSTATUS WS2_async_shutdown( void* user, PIO_STATUS_BLOCK iosb, NTSTATUS
ws2_async* wsa = user;
int fd, err = 1;
- TRACE( "async %p %d\n", wsa, wsa->mode );
+ TRACE( "async %p %d\n", wsa, wsa->type );
switch (status)
{
case STATUS_ALERTED:
if ((status = wine_server_handle_to_fd( wsa->hSocket, 0, &fd, NULL ) ))
break;
- switch ( wsa->mode )
+ switch ( wsa->type )
{
- 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 );
+ case ASYNC_TYPE_READ: err = shutdown( fd, 0 ); break;
+ case ASYNC_TYPE_WRITE: err = shutdown( fd, 1 ); break;
}
wine_server_release_fd( wsa->hSocket, fd );
status = err ? wsaErrno() : STATUS_SUCCESS;
break;
}
- ws2_async_terminate(wsa, iosb, status, 0);
+ iosb->u.Status = status;
return status;
}
@@ -1407,44 +1296,45 @@ static NTSTATUS WS2_async_shutdown( void* user, PIO_STATUS_BLOCK iosb, NTSTATUS
*
* Helper function for WS_shutdown() on overlapped sockets.
*/
-static int WS2_register_async_shutdown( SOCKET s, enum ws2_mode mode )
+static int WS2_register_async_shutdown( SOCKET s, int type )
{
struct ws2_async *wsa;
- int ret, err = WSAEFAULT;
- DWORD dwflags = 0;
- int len = 0;
- LPWSAOVERLAPPED ovl = HeapAlloc(GetProcessHeap(), 0, sizeof( WSAOVERLAPPED ));
- IO_STATUS_BLOCK *iosb = NULL;
+ NTSTATUS status;
- TRACE("s %ld mode %d\n", s, mode);
- if (!ovl)
- goto out;
+ TRACE("s %ld type %d\n", s, type);
- ovl->hEvent = WSACreateEvent();
- if ( ovl->hEvent == WSA_INVALID_EVENT )
- goto out_free;
-
- wsa = WS2_make_async( s, mode, NULL, 0, &dwflags, NULL, &len, ovl, NULL, &iosb );
+ wsa = HeapAlloc( GetProcessHeap(), 0, sizeof(*wsa) );
if ( !wsa )
- goto out_close;
+ return WSAEFAULT;
+
+ wsa->hSocket = SOCKET2HANDLE(s);
+ wsa->type = type;
+ wsa->completion_func = NULL;
- /* Hack: this will cause ws2_async_terminate() to free the overlapped structure */
- wsa->user_overlapped = NULL;
- if ((ret = ws2_queue_async( wsa, iosb )) != STATUS_PENDING)
+ SERVER_START_REQ( register_async )
{
- err = NtStatusToWSAError( ret );
- goto out;
+ req->handle = wsa->hSocket;
+ req->type = type;
+ req->async.callback = WS2_async_shutdown;
+ req->async.iosb = &wsa->local_iosb;
+ req->async.arg = wsa;
+ req->async.apc = ws2_async_apc;
+ req->async.apc_arg = wsa;
+ status = wine_server_call( req );
}
+ SERVER_END_REQ;
+
+ if (status != STATUS_PENDING)
+ {
+ HeapFree( GetProcessHeap(), 0, wsa );
+ return NtStatusToWSAError( status );
+ }
+ else
+ NtCurrentTeb()->num_async_io++;
+
/* Try immediate completion */
- while ( WaitForSingleObjectEx( ovl->hEvent, 0, TRUE ) == STATUS_USER_APC );
+ Sleep(0);
return 0;
-
-out_close:
- WSACloseEvent( ovl->hEvent );
-out_free:
- HeapFree( GetProcessHeap(), 0, ovl );
-out:
- return err;
}
/***********************************************************************
@@ -3162,15 +3052,15 @@ int WINAPI WS_shutdown(SOCKET s, int how)
switch ( how )
{
case SD_RECEIVE:
- err = WS2_register_async_shutdown( s, ws2m_sd_read );
+ err = WS2_register_async_shutdown( s, ASYNC_TYPE_READ );
break;
case SD_SEND:
- err = WS2_register_async_shutdown( s, ws2m_sd_write );
+ err = WS2_register_async_shutdown( s, ASYNC_TYPE_WRITE );
break;
case SD_BOTH:
default:
- err = WS2_register_async_shutdown( s, ws2m_sd_read );
- if (!err) err = WS2_register_async_shutdown( s, ws2m_sd_write );
+ err = WS2_register_async_shutdown( s, ASYNC_TYPE_READ );
+ if (!err) err = WS2_register_async_shutdown( s, ASYNC_TYPE_WRITE );
break;
}
if (err) goto error;
More information about the wine-cvs
mailing list