From: Stefan Dösinger Subject: [PATCH] ntdll: Do not queue a completion status if pipe ops fail synchronously. Message-Id: <20170922101325.15192-1-stefan@codeweavers.com> Date: Fri, 22 Sep 2017 13:13:25 +0300 This fixes random crashes when exiting Chromium or shutting down CEF. It is similar to 7a1142035d7ee04839417176ff93fd0953e2a4e1, just for pipes. Signed-off-by: Stefan Dösinger --- dlls/kernel32/tests/pipe.c | 39 +++++++++++++++++++++++++++++++++++++++ dlls/ntdll/file.c | 6 +++--- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c index 0a6edd6ea2..84db14e814 100644 --- a/dlls/kernel32/tests/pipe.c +++ b/dlls/kernel32/tests/pipe.c @@ -1076,6 +1076,45 @@ static DWORD CALLBACK serverThreadMain4(LPVOID arg) } trace("Server done writing.\n"); + /* Client will finish this connection, the following ops will trigger broken pipe errors. */ + + /* Wait for the pipe to break. */ + while (PeekNamedPipe(hnp, NULL, 0, NULL, &written, &written)); + + trace("Server writing on disconnected pipe...\n"); + SetLastError(ERROR_SUCCESS); + success = WriteFile(hnp, buf, readden, &written, &oWrite); + err = GetLastError(); + todo_wine_if (!success && err == ERROR_PIPE_NOT_CONNECTED) ok(!success && err == ERROR_NO_DATA, + "overlapped WriteFile on disconnected pipe returned %u, err=%i\n", success, err); + + /* No completion status is queued on immediate error. */ + SetLastError(ERROR_SUCCESS); + oResult = (OVERLAPPED *)0xdeadbeef; + success = GetQueuedCompletionStatus(hcompletion, &written, &compkey, + &oResult, 0); + err = GetLastError(); + ok(!success && err == WAIT_TIMEOUT && !oResult, + "WriteFile GetQueuedCompletionStatus returned %u, err=%i, oResult %p\n", + success, err, oResult); + + trace("Server reading from disconnected pipe...\n"); + SetLastError(ERROR_SUCCESS); + success = ReadFile(hnp, buf, sizeof(buf), &readden, &oRead); + trace("Server ReadFile from disconnected pipe returned...\n"); + err = GetLastError(); + ok(!success && err == ERROR_BROKEN_PIPE, + "overlapped ReadFile on disconnected pipe returned %u, err=%i\n", success, err); + + SetLastError(ERROR_SUCCESS); + oResult = (OVERLAPPED *)0xdeadbeef; + success = GetQueuedCompletionStatus(hcompletion, &readden, &compkey, + &oResult, 0); + err = GetLastError(); + ok(!success && err == WAIT_TIMEOUT && !oResult, + "ReadFile GetQueuedCompletionStatus returned %u, err=%i, oResult %p\n", + success, err, oResult); + /* finish this connection, wait for next one */ ok(FlushFileBuffers(hnp), "FlushFileBuffers\n"); success = DisconnectNamedPipe(hnp); diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 0381e558ff..dcb300ac12 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -937,7 +937,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent, break; default: status = STATUS_PIPE_BROKEN; - goto done; + goto err; } } else if (type == FD_TYPE_FILE) continue; /* no async I/O on regular files */ @@ -946,7 +946,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent, { if (errno == EINTR) continue; if (!total) status = FILE_GetNtStatus(); - goto done; + goto err; } if (async_read) @@ -1331,7 +1331,7 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent, if (errno == EFAULT) status = STATUS_INVALID_USER_BUFFER; else status = FILE_GetNtStatus(); } - goto done; + goto err; } if (async_write) -- 2.13.5