Sebastian Lackner : server: Support FILE_SKIP_COMPLETION_PORT_ON_SUCCESS on server-side asyncs.

Alexandre Julliard julliard at winehq.org
Thu Oct 25 15:24:35 CDT 2018


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

Author: Sebastian Lackner <sebastian at fds-team.de>
Date:   Thu Oct 25 14:56:08 2018 +0200

server: Support FILE_SKIP_COMPLETION_PORT_ON_SUCCESS on server-side asyncs.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=38960
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/tests/pipe.c |  5 -----
 server/async.c          | 10 ++++++++--
 server/fd.c             |  8 ++++----
 server/file.h           |  2 +-
 4 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c
index c4d4d877..20bfc73 100644
--- a/dlls/ntdll/tests/pipe.c
+++ b/dlls/ntdll/tests/pipe.c
@@ -1287,7 +1287,6 @@ static void test_completion(void)
     ret = WriteFile(client, buf, sizeof(buf), &num_bytes, &ov);
     ok(ret, "WriteFile failed, error %u\n", GetLastError());
     ok(num_bytes == sizeof(buf), "expected sizeof(buf), got %u\n", num_bytes);
-    todo_wine
     test_no_queued_completion(port);
 
     ret = WriteFile(pipe, buf, sizeof(buf), &num_bytes, &ov);
@@ -1301,14 +1300,12 @@ static void test_completion(void)
     if(status == STATUS_PENDING) /* win8+ */
         test_queued_completion(port, &io, STATUS_BUFFER_OVERFLOW, 1);
     else
-        todo_wine
         test_no_queued_completion(port);
 
     status = NtReadFile(client, NULL, NULL, &io, &io, read_buf, sizeof(read_buf), NULL, NULL);
     ok(status == STATUS_SUCCESS, "status = %x\n", status);
     ok(io.Status == STATUS_SUCCESS, "Status = %x\n", io.Status);
     ok(io.Information == sizeof(buf)-1, "Information = %lu\n", io.Information);
-    todo_wine
     test_no_queued_completion(port);
 
     status = NtFsControlFile(client, NULL, NULL, &io, &io, FSCTL_PIPE_PEEK,
@@ -1317,7 +1314,6 @@ static void test_completion(void)
     if(status == STATUS_PENDING) /* win8+ */
         test_queued_completion(port, &io, STATUS_SUCCESS, FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data));
     else
-        todo_wine
         test_no_queued_completion(port);
 
     memset(&io, 0xcc, sizeof(io));
@@ -1339,7 +1335,6 @@ static void test_completion(void)
     if(status == STATUS_PENDING) /* win8+ */
         test_queued_completion(port, &io, STATUS_BUFFER_OVERFLOW, sizeof(peek_buf));
     else
-        todo_wine
         test_no_queued_completion(port);
 
     CloseHandle(ov.hEvent);
diff --git a/server/async.c b/server/async.c
index adbadc5..f2674bb 100644
--- a/server/async.c
+++ b/server/async.c
@@ -53,6 +53,7 @@ struct async
     int                  direct_result;   /* a flag if we're passing result directly from request instead of APC  */
     struct completion   *completion;      /* completion associated with fd */
     apc_param_t          comp_key;        /* completion key associated with fd */
+    unsigned int         comp_flags;      /* completion flags */
 };
 
 static void async_dump( struct object *obj, int verbose );
@@ -239,6 +240,7 @@ struct async *create_async( struct fd *fd, struct thread *thread, const async_da
     async->wait_handle   = 0;
     async->direct_result = 0;
     async->completion    = fd_get_completion( fd, &async->comp_key );
+    async->comp_flags    = 0;
 
     if (iosb) async->iosb = (struct iosb *)grab_object( iosb );
     else async->iosb = NULL;
@@ -258,7 +260,7 @@ struct async *create_async( struct fd *fd, struct thread *thread, const async_da
 
 /* create an async associated with iosb for async-based requests
  * returned async must be passed to async_handoff */
-struct async *create_request_async( struct fd *fd, const async_data_t *data )
+struct async *create_request_async( struct fd *fd, unsigned int comp_flags, const async_data_t *data )
 {
     struct async *async;
     struct iosb *iosb;
@@ -276,6 +278,7 @@ struct async *create_request_async( struct fd *fd, const async_data_t *data )
             return NULL;
         }
         async->direct_result = 1;
+        async->comp_flags = comp_flags;
     }
     return async;
 }
@@ -377,8 +380,11 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota
             data.user.args[2] = 0;
             thread_queue_apc( NULL, async->thread, NULL, &data );
         }
-        else if (async->data.apc_context)
+        else if (async->data.apc_context && (!async->direct_result ||
+                 !(async->comp_flags & FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)))
+        {
             add_async_completion( async, async->data.apc_context, status, total );
+        }
 
         if (async->event) set_event( async->event );
         else if (async->fd) set_fd_signaled( async->fd, 1 );
diff --git a/server/fd.c b/server/fd.c
index 686382e..06778fe 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -2414,7 +2414,7 @@ DECL_HANDLER(flush)
 
     if (!fd) return;
 
-    if ((async = create_request_async( fd, &req->async )))
+    if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
     {
         reply->event = async_handoff( async, fd->fd_ops->flush( fd, async ), NULL );
         release_object( async );
@@ -2513,7 +2513,7 @@ DECL_HANDLER(read)
 
     if (!fd) return;
 
-    if ((async = create_request_async( fd, &req->async )))
+    if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
     {
         reply->wait    = async_handoff( async, fd->fd_ops->read( fd, async, req->pos ), NULL );
         reply->options = fd->options;
@@ -2530,7 +2530,7 @@ DECL_HANDLER(write)
 
     if (!fd) return;
 
-    if ((async = create_request_async( fd, &req->async )))
+    if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
     {
         reply->wait    = async_handoff( async, fd->fd_ops->write( fd, async, req->pos ), &reply->size );
         reply->options = fd->options;
@@ -2548,7 +2548,7 @@ DECL_HANDLER(ioctl)
 
     if (!fd) return;
 
-    if ((async = create_request_async( fd, &req->async )))
+    if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
     {
         reply->wait    = async_handoff( async, fd->fd_ops->ioctl( fd, req->code, async ), NULL );
         reply->options = fd->options;
diff --git a/server/file.h b/server/file.h
index c30bc96..84cbc29 100644
--- a/server/file.h
+++ b/server/file.h
@@ -185,7 +185,7 @@ extern struct object *create_serial( struct fd *fd );
 /* async I/O functions */
 extern void free_async_queue( struct async_queue *queue );
 extern struct async *create_async( struct fd *fd, struct thread *thread, const async_data_t *data, struct iosb *iosb );
-extern struct async *create_request_async( struct fd *fd, const async_data_t *data );
+extern struct async *create_request_async( struct fd *fd, unsigned int comp_flags, const async_data_t *data );
 extern obj_handle_t async_handoff( struct async *async, int success, data_size_t *result );
 extern void queue_async( struct async_queue *queue, struct async *async );
 extern void async_set_timeout( struct async *async, timeout_t timeout, unsigned int status );




More information about the wine-cvs mailing list