Module: wine Branch: master Commit: 18e074b0f30e8067c0901979308e961627b182a3 URL: https://source.winehq.org/git/wine.git/?a=commit;h=18e074b0f30e8067c09019793...
Author: Sebastian Lackner sebastian@fds-team.de Date: Thu Oct 25 14:56:24 2018 +0200
server: Support FILE_SKIP_COMPLETION_PORT_ON_SUCCESS on client-side asyncs.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=38960 Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/tests/file.c | 4 ---- dlls/ws2_32/socket.c | 15 ++++++++------- include/wine/server_protocol.h | 4 ++-- server/fd.c | 2 +- server/protocol.def | 1 + server/request.h | 1 + server/trace.c | 1 + 7 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index db077d6..a4ae64f 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -3444,9 +3444,7 @@ static void test_file_completion_information(void)
pov = (void *)0xdeadbeef; ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 500); - todo_wine ok(!ret, "GetQueuedCompletionStatus succeeded\n"); - todo_wine ok(pov == NULL, "expected NULL, got %p\n", pov); } else @@ -3474,9 +3472,7 @@ static void test_file_completion_information(void)
pov = (void *)0xdeadbeef; ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 1000); - todo_wine ok(!ret, "GetQueuedCompletionStatus succeeded\n"); - todo_wine ok(pov == NULL, "expected NULL, got %p\n", pov); } else diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 164a48c..df068fe 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -642,7 +642,7 @@ static int ws_protocol_info(SOCKET s, int unicode, WSAPROTOCOL_INFOW *buffer, in int WSAIOCTL_GetInterfaceCount(void); int WSAIOCTL_GetInterfaceName(int intNumber, char *intName);
-static void WS_AddCompletion( SOCKET sock, ULONG_PTR CompletionValue, NTSTATUS CompletionStatus, ULONG Information ); +static void WS_AddCompletion( SOCKET sock, ULONG_PTR CompletionValue, NTSTATUS CompletionStatus, ULONG Information, BOOL force );
#define MAP_OPTION(opt) { WS_##opt, opt }
@@ -2459,7 +2459,7 @@ static NTSTATUS WS2_async_accept_recv( void *user, IO_STATUS_BLOCK *iosb, NTSTAT return status;
if (wsa->cvalue) - WS_AddCompletion( HANDLE2SOCKET(wsa->listen_socket), wsa->cvalue, iosb->u.Status, iosb->Information ); + WS_AddCompletion( HANDLE2SOCKET(wsa->listen_socket), wsa->cvalue, iosb->u.Status, iosb->Information, TRUE );
release_async_io( &wsa->io ); return status; @@ -3591,7 +3591,7 @@ static BOOL WINAPI WS2_ConnectEx(SOCKET s, const struct WS_sockaddr* name, int n { ov->Internal = _get_sock_error(s, FD_CONNECT_BIT); ov->InternalHigh = 0; - if (cvalue) WS_AddCompletion( s, cvalue, ov->Internal, ov->InternalHigh ); + if (cvalue) WS_AddCompletion( s, cvalue, ov->Internal, ov->InternalHigh, FALSE ); if (ov->hEvent) NtSetEvent( ov->hEvent, NULL ); status = STATUS_PENDING; } @@ -5082,7 +5082,7 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID overlapped->Internal = status; overlapped->InternalHigh = total; if (overlapped->hEvent) NtSetEvent( overlapped->hEvent, NULL ); - if (cvalue) WS_AddCompletion( HANDLE2SOCKET(s), cvalue, status, total ); + if (cvalue) WS_AddCompletion( HANDLE2SOCKET(s), cvalue, status, total, FALSE ); }
if (!status) @@ -5477,7 +5477,7 @@ int WINAPI WSAPoll(WSAPOLLFD *wfds, ULONG count, int timeout)
/* helper to send completion messages for client-only i/o operation case */ static void WS_AddCompletion( SOCKET sock, ULONG_PTR CompletionValue, NTSTATUS CompletionStatus, - ULONG Information ) + ULONG Information, BOOL async ) { SERVER_START_REQ( add_fd_completion ) { @@ -5485,6 +5485,7 @@ static void WS_AddCompletion( SOCKET sock, ULONG_PTR CompletionValue, NTSTATUS C req->cvalue = CompletionValue; req->status = CompletionStatus; req->information = Information; + req->async = async; wine_server_call( req ); } SERVER_END_REQ; @@ -5629,7 +5630,7 @@ static int WS2_sendto( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, if (lpNumberOfBytesSent) *lpNumberOfBytesSent = n; if (!wsa->completion_func) { - if (cvalue) WS_AddCompletion( s, cvalue, STATUS_SUCCESS, n ); + if (cvalue) WS_AddCompletion( s, cvalue, STATUS_SUCCESS, n, FALSE ); if (lpOverlapped->hEvent) SetEvent( lpOverlapped->hEvent ); HeapFree( GetProcessHeap(), 0, wsa ); } @@ -8046,7 +8047,7 @@ static int WS2_recv_base( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, iosb->Information = n; if (!wsa->completion_func) { - if (cvalue) WS_AddCompletion( s, cvalue, STATUS_SUCCESS, n ); + if (cvalue) WS_AddCompletion( s, cvalue, STATUS_SUCCESS, n, FALSE ); if (lpOverlapped->hEvent) SetEvent( lpOverlapped->hEvent ); HeapFree( GetProcessHeap(), 0, wsa ); } diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index d7e9119..0e85d1a 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -5373,7 +5373,7 @@ struct add_fd_completion_request apc_param_t cvalue; apc_param_t information; unsigned int status; - char __pad_36[4]; + int async; }; struct add_fd_completion_reply { @@ -6546,6 +6546,6 @@ union generic_reply struct terminate_job_reply terminate_job_reply; };
-#define SERVER_PROTOCOL_VERSION 569 +#define SERVER_PROTOCOL_VERSION 570
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/fd.c b/server/fd.c index 06778fe..117fad8 100644 --- a/server/fd.c +++ b/server/fd.c @@ -2611,7 +2611,7 @@ DECL_HANDLER(add_fd_completion) struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 ); if (fd) { - if (fd->completion) + if (fd->completion && (req->async || !(fd->comp_flags & FILE_SKIP_COMPLETION_PORT_ON_SUCCESS))) add_completion( fd->completion, fd->comp_key, req->cvalue, req->status, req->information ); release_object( fd ); } diff --git a/server/protocol.def b/server/protocol.def index 08fcf8c..6e02fbc 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3697,6 +3697,7 @@ struct handle_info apc_param_t cvalue; /* completion value */ apc_param_t information; /* IO_STATUS_BLOCK Information */ unsigned int status; /* completion status */ + int async; /* completion is an async result */ @END
diff --git a/server/request.h b/server/request.h index e24f125..4610ca6 100644 --- a/server/request.h +++ b/server/request.h @@ -2331,6 +2331,7 @@ C_ASSERT( FIELD_OFFSET(struct add_fd_completion_request, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct add_fd_completion_request, cvalue) == 16 ); C_ASSERT( FIELD_OFFSET(struct add_fd_completion_request, information) == 24 ); C_ASSERT( FIELD_OFFSET(struct add_fd_completion_request, status) == 32 ); +C_ASSERT( FIELD_OFFSET(struct add_fd_completion_request, async) == 36 ); C_ASSERT( sizeof(struct add_fd_completion_request) == 40 ); C_ASSERT( FIELD_OFFSET(struct set_fd_completion_mode_request, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct set_fd_completion_mode_request, flags) == 16 ); diff --git a/server/trace.c b/server/trace.c index 39743d4..9a84067 100644 --- a/server/trace.c +++ b/server/trace.c @@ -4387,6 +4387,7 @@ static void dump_add_fd_completion_request( const struct add_fd_completion_reque dump_uint64( ", cvalue=", &req->cvalue ); dump_uint64( ", information=", &req->information ); fprintf( stderr, ", status=%08x", req->status ); + fprintf( stderr, ", async=%d", req->async ); }
static void dump_set_fd_completion_mode_request( const struct set_fd_completion_mode_request *req )