From: "Erich E. Hoover" Subject: [PATCH 1/3] ws2_32: Revise AcceptEx behavior to send completions for canceled sockets (resend 3, deferred). Message-Id: Date: Wed, 18 Apr 2012 18:33:09 -0600 Real Name: Erich Hoover Description: This patch changes how AcceptEx and the wine server use completions so that canceled sockets can still send completion notifications. The patch fixes a significant issue with the WoW launcher and the Diablo 3 installer (Bug #27657). I'm sorry I sent a big batch of patches before, I was resending my previously deferred patches that had dropped off the list and I didn't realize that that was an issue. I'd really like to see this issue fixed before the Diablo 3 release, so feel free to ignore the other patches I currently have posted and focus exclusively on this set. Changelog: ws2_32: Revise AcceptEx behavior to send completions for canceled sockets. From 3396d0d184577ca7d0e56fad5037aaf27bda2d97 Mon Sep 17 00:00:00 2001 From: Erich Hoover Date: Wed, 18 Apr 2012 18:15:21 -0600 Subject: ws2_32: Revise AcceptEx behavior to send completions for canceled sockets. --- dlls/ws2_32/socket.c | 8 ++++---- server/async.c | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index fd384a5..39896cb 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -1706,7 +1706,7 @@ static NTSTATUS WS2_async_accept( void *arg, IO_STATUS_BLOCK *iosb, NTSTATUS sta if (status != STATUS_PENDING) goto finish; - return STATUS_SUCCESS; + return STATUS_ALERTED; finish: iosb->u.Status = status; @@ -1714,8 +1714,6 @@ finish: if (wsa->user_overlapped->hEvent) SetEvent(wsa->user_overlapped->hEvent); - if (wsa->cvalue) - WS_AddCompletion( HANDLE2SOCKET(wsa->listen_socket), wsa->cvalue, iosb->u.Status, iosb->Information ); *apc = ws2_async_accept_apc; return status; @@ -2046,7 +2044,9 @@ static BOOL WINAPI WS2_AcceptEx(SOCKET listener, SOCKET acceptor, PVOID dest, DW req->async.callback = wine_server_client_ptr( WS2_async_accept ); req->async.iosb = wine_server_client_ptr( overlapped ); req->async.arg = wine_server_client_ptr( wsa ); - /* We don't set event or completion since we may also have to read */ + req->async.cvalue = cvalue; + /* We don't set event since we may also have to read, completion returns STATUS_ALERTED + * to indicate that no completion should be queued. */ status = wine_server_call( req ); } SERVER_END_REQ; diff --git a/server/async.c b/server/async.c index dd28dff..b8be5cd 100644 --- a/server/async.c +++ b/server/async.c @@ -256,10 +256,12 @@ void async_set_result( struct object *obj, unsigned int status, unsigned int tot else { if (async->timeout) remove_timeout_user( async->timeout ); + if (async->completion && async->data.cvalue && status != STATUS_ALERTED) + add_completion( async->completion, async->comp_key, async->data.cvalue, status, total ); + else if (async->completion && async->data.cvalue && status == STATUS_ALERTED) + status = STATUS_SUCCESS; async->timeout = NULL; async->status = status; - if (async->completion && async->data.cvalue) - add_completion( async->completion, async->comp_key, async->data.cvalue, status, total ); if (apc) { apc_call_t data; -- 1.7.5.4