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