Module: wine Branch: master Commit: 91c4e9bf9af5548320fbb38f533a53ff04494923 URL: https://source.winehq.org/git/wine.git/?a=commit;h=91c4e9bf9af5548320fbb38f5...
Author: Brendan Shanks bshanks@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@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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 ); + } } }