=?UTF-8?Q?Stefan=20D=C3=B6singer=20?=: ntdll: Do not queue a completion status if pipe ops fail synchronously.

Alexandre Julliard julliard at winehq.org
Tue Jan 2 15:01:24 CST 2018


Module: wine
Branch: stable
Commit: 4c6601032e89c77ec6d7226268de95e67c0c7f74
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=4c6601032e89c77ec6d7226268de95e67c0c7f74

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Fri Sep 22 13:13:25 2017 +0300

ntdll: Do not queue a completion status if pipe ops fail synchronously.

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 <stefan at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
(cherry picked from commit bf6025e0e111d265bdf1c56871be9a73955e9ea2)
Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>

---

 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 33440bf..dbe3fc9 100644
--- a/dlls/kernel32/tests/pipe.c
+++ b/dlls/kernel32/tests/pipe.c
@@ -1050,6 +1050,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 e1583da..55fd494 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -945,7 +945,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 */
@@ -954,7 +954,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
         {
             if (errno == EINTR) continue;
             if (!total) status = FILE_GetNtStatus();
-            goto done;
+            goto err;
         }
 
         if (async_read)
@@ -1342,7 +1342,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)




More information about the wine-cvs mailing list