Module: wine Branch: master Commit: c0996553a1d9056e1b89871fc8c3fb0bfb5a4f0c URL: https://source.winehq.org/git/wine.git/?a=commit;h=c0996553a1d9056e1b89871fc...
Author: Sebastian Lackner sebastian@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@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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 );