Brendan Shanks : server: Don't block when writing to named pipes in PIPE_NOWAIT mode.

Alexandre Julliard julliard at winehq.org
Wed Oct 16 16:59:29 CDT 2019


Module: wine
Branch: master
Commit: 91c4e9bf9af5548320fbb38f533a53ff04494923
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=91c4e9bf9af5548320fbb38f533a53ff04494923

Author: Brendan Shanks <bshanks at codeweavers.com>
Date:   Wed Oct 16 14:50:34 2019 +0200

server: Don't block when writing to named pipes in PIPE_NOWAIT mode.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernel32/tests/pipe.c | 36 ++++++++++++++++++------------------
 server/named_pipe.c        | 17 ++++++++++++-----
 2 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c
index 02df7374c8..de30e6a1c9 100644
--- a/dlls/kernel32/tests/pipe.c
+++ b/dlls/kernel32/tests/pipe.c
@@ -3941,7 +3941,7 @@ static void test_nowait(void)
 
     /* write one byte larger than the buffer size, should fail */
     SetLastError(0xdeadbeef);
-    todo_wine ok(WriteFile(pipewrite, readbuf, 513, &write, &ol), "WriteFile should succeed\n");
+    ok(WriteFile(pipewrite, readbuf, 513, &write, &ol), "WriteFile should succeed\n");
     /* WriteFile only documents that 'write < sizeof(readbuf)' for this case, but Windows
      * doesn't seem to do partial writes ('write == 0' always)
      */
@@ -3952,32 +3952,32 @@ static void test_nowait(void)
 
     /* overlapped read of 32768, non-blocking write of 512 */
     SetLastError(0xdeadbeef);
-    todo_wine ok(ReadFile(piperead, readbuf, sizeof(readbuf), &read, &ol2) == FALSE, "ReadFile should fail\n");
-    todo_wine ok(GetLastError() == ERROR_IO_PENDING, "got %d should be ERROR_IO_PENDING\n", GetLastError());
+    ok(ReadFile(piperead, readbuf, sizeof(readbuf), &read, &ol2) == FALSE, "ReadFile should fail\n");
+    ok(GetLastError() == ERROR_IO_PENDING, "got %d should be ERROR_IO_PENDING\n", GetLastError());
     ok(WriteFile(pipewrite, teststring, sizeof(teststring), &write, &ol), "WriteFile should succeed\n");
     ok(write == sizeof(teststring), "got %d\n", write);
     ok(GetOverlappedResult(piperead, &ol2, &read, FALSE), "GetOverlappedResult should succeed\n");
-    todo_wine ok(read == sizeof(teststring), "got %d\n", read);
+    ok(read == sizeof(teststring), "got %d\n", read);
     if (GetOverlappedResult(piperead, &ol2, &read, FALSE) == FALSE)
         CancelIo(piperead);
 
     /* overlapped read of 32768, non-blocking write of 513 */
     SetLastError(0xdeadbeef);
-    todo_wine ok(ReadFile(piperead, readbuf, sizeof(readbuf), &read, &ol2) == FALSE, "ReadFile should fail\n");
-    todo_wine ok(GetLastError() == ERROR_IO_PENDING, "got %d should be ERROR_IO_PENDING\n", GetLastError());
-    todo_wine ok(WriteFile(pipewrite, readbuf, 513, &write, &ol), "WriteFile should succeed\n");
-    todo_wine ok(write == 513, "got %d, write should be %d\n", write, 513);
+    ok(ReadFile(piperead, readbuf, sizeof(readbuf), &read, &ol2) == FALSE, "ReadFile should fail\n");
+    ok(GetLastError() == ERROR_IO_PENDING, "got %d should be ERROR_IO_PENDING\n", GetLastError());
+    ok(WriteFile(pipewrite, readbuf, 513, &write, &ol), "WriteFile should succeed\n");
+    ok(write == 513, "got %d, write should be %d\n", write, 513);
     ok(GetOverlappedResult(piperead, &ol2, &read, FALSE), "GetOverlappedResult should succeed\n");
-    todo_wine ok(read == 513, "got %d, read should be %d\n", read, 513);
+    ok(read == 513, "got %d, read should be %d\n", read, 513);
     if (GetOverlappedResult(piperead, &ol2, &read, FALSE) == FALSE)
         CancelIo(piperead);
 
     /* overlapped read of 1 byte, non-blocking write of 513 bytes */
     SetLastError(0xdeadbeef);
-    todo_wine ok(ReadFile(piperead, readbuf, 1, &read, &ol2) == FALSE, "ReadFile should fail\n");
-    todo_wine ok(GetLastError() == ERROR_IO_PENDING, "got %d should be ERROR_IO_PENDING\n", GetLastError());
-    todo_wine ok(WriteFile(pipewrite, readbuf, 513, &write, &ol), "WriteFile should succeed\n");
-    todo_wine ok(write == 513, "got %d, write should be %d\n", write, 513);
+    ok(ReadFile(piperead, readbuf, 1, &read, &ol2) == FALSE, "ReadFile should fail\n");
+    ok(GetLastError() == ERROR_IO_PENDING, "got %d should be ERROR_IO_PENDING\n", GetLastError());
+    ok(WriteFile(pipewrite, readbuf, 513, &write, &ol), "WriteFile should succeed\n");
+    ok(write == 513, "got %d, write should be %d\n", write, 513);
     ok(GetOverlappedResult(piperead, &ol2, &read, FALSE), "GetOverlappedResult should succeed\n");
     ok(read == 1, "got %d, read should be %d\n", read, 1);
     if (GetOverlappedResult(piperead, &ol2, &read, FALSE) == FALSE)
@@ -3985,7 +3985,7 @@ static void test_nowait(void)
     /* read the remaining 512 bytes */
     SetLastError(0xdeadbeef);
     ok(ReadFile(piperead, readbuf, sizeof(readbuf), &read, &ol2), "ReadFile should succeed\n");
-    todo_wine ok(read == 512, "got %d, write should be %d\n", write, 512);
+    ok(read == 512, "got %d, write should be %d\n", write, 512);
     if (GetOverlappedResult(piperead, &ol2, &read, FALSE) == FALSE)
         CancelIo(piperead);
 
@@ -3993,8 +3993,8 @@ static void test_nowait(void)
     SetLastError(0xdeadbeef);
     ok(ReadFile(piperead, readbuf, 1, &read, &ol2) == FALSE, "ReadFile should fail\n");
     ok(GetLastError() == ERROR_IO_PENDING, "got %d should be ERROR_IO_PENDING\n", GetLastError());
-    todo_wine ok(WriteFile(pipewrite, readbuf, 514, &write, &ol), "WriteFile should succeed\n");
-    todo_wine ok(write == 1, "got %d, write should be %d\n", write, 1);
+    ok(WriteFile(pipewrite, readbuf, 514, &write, &ol), "WriteFile should succeed\n");
+    ok(write == 1, "got %d, write should be %d\n", write, 1);
     ok(GetOverlappedResult(piperead, &ol2, &read, FALSE), "GetOverlappedResult should succeed\n");
     ok(read == 1, "got %d, read should be %d\n", read, 1);
     if (GetOverlappedResult(piperead, &ol2, &read, FALSE) == FALSE)
@@ -4002,8 +4002,8 @@ static void test_nowait(void)
 
     /* write the exact buffer size, should succeed */
     SetLastError(0xdeadbeef);
-    todo_wine ok(WriteFile(pipewrite, readbuf, 512, &write, &ol), "WriteFile should succeed\n");
-    todo_wine ok(write == 512, "WriteFile should write the whole buffer\n");
+    ok(WriteFile(pipewrite, readbuf, 512, &write, &ol), "WriteFile should succeed\n");
+    ok(write == 512, "WriteFile should write the whole buffer\n");
     if (GetLastError() == ERROR_IO_PENDING)
         CancelIo(piperead);
 
diff --git a/server/named_pipe.c b/server/named_pipe.c
index 1e0c5898a1..9c5438b77a 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -363,7 +363,7 @@ static struct pipe_message *queue_message( struct pipe_end *pipe_end, struct ios
     return message;
 }
 
-static void wake_message( struct pipe_message *message )
+static void wake_message( struct pipe_message *message, data_size_t result )
 {
     struct async *async = message->async;
 
@@ -371,7 +371,7 @@ static void wake_message( struct pipe_message *message )
     if (!async) return;
 
     message->iosb->status = STATUS_SUCCESS;
-    message->iosb->result = message->iosb->in_size;
+    message->iosb->result = result;
     async_terminate( async, message->iosb->result ? STATUS_ALERTED : STATUS_SUCCESS );
     release_object( async );
 }
@@ -749,7 +749,7 @@ static void message_queue_read( struct pipe_end *pipe_end, struct iosb *iosb )
     {
         iosb->out_data = message->iosb->in_data;
         message->iosb->in_data = NULL;
-        wake_message( message );
+        wake_message( message, message->iosb->in_size );
         free_message( message );
     }
     else
@@ -773,7 +773,7 @@ static void message_queue_read( struct pipe_end *pipe_end, struct iosb *iosb )
             message->read_pos += writing;
             if (message->read_pos == message->iosb->in_size)
             {
-                wake_message(message);
+                wake_message(message, message->iosb->in_size);
                 free_message(message);
             }
         } while (write_pos < iosb->out_size);
@@ -835,7 +835,14 @@ static void reselect_write_queue( struct pipe_end *pipe_end )
         {
             avail += message->iosb->in_size - message->read_pos;
             if (message->async && (avail <= reader->buffer_size || !message->iosb->in_size))
-                wake_message( message );
+            {
+                wake_message( message, message->iosb->in_size );
+            }
+            else if (message->async && (pipe_end->flags & NAMED_PIPE_NONBLOCKING_MODE))
+            {
+                wake_message( message, message->read_pos );
+                free_message( message );
+            }
         }
     }
 




More information about the wine-cvs mailing list