2018-02-15 13:40:30 -08:00
|
|
|
From 66f2053d1f72e821bd1100d8bf2266e73e2e2163 Mon Sep 17 00:00:00 2001
|
2017-04-08 18:21:23 -07:00
|
|
|
From: Sebastian Lackner <sebastian@fds-team.de>
|
|
|
|
Date: Sun, 9 Apr 2017 03:13:25 +0200
|
2018-02-15 13:40:30 -08:00
|
|
|
Subject: [PATCH] server: Skip async completion when possible.
|
2017-04-08 18:21:23 -07:00
|
|
|
|
|
|
|
---
|
|
|
|
dlls/ntdll/tests/pipe.c | 2 --
|
2017-07-08 07:11:26 -07:00
|
|
|
server/async.c | 10 ++++++++--
|
|
|
|
server/fd.c | 8 ++++----
|
|
|
|
server/file.h | 2 +-
|
|
|
|
4 files changed, 13 insertions(+), 9 deletions(-)
|
2017-04-08 18:21:23 -07:00
|
|
|
|
|
|
|
diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c
|
2018-02-15 13:40:30 -08:00
|
|
|
index bea849f..06be9eb 100644
|
2017-04-08 18:21:23 -07:00
|
|
|
--- a/dlls/ntdll/tests/pipe.c
|
|
|
|
+++ b/dlls/ntdll/tests/pipe.c
|
2018-02-15 13:40:30 -08:00
|
|
|
@@ -394,9 +394,7 @@ static void test_completion(void)
|
2017-04-08 18:21:23 -07:00
|
|
|
|
|
|
|
pov = (void *)0xdeadbeef;
|
|
|
|
ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 1000);
|
|
|
|
- todo_wine
|
|
|
|
ok(!ret, "GetQueuedCompletionStatus succeeded\n");
|
|
|
|
- todo_wine
|
|
|
|
ok(pov == NULL, "expected NULL, got %p\n", pov);
|
|
|
|
|
|
|
|
CloseHandle(ov.hEvent);
|
|
|
|
diff --git a/server/async.c b/server/async.c
|
2018-02-15 13:40:30 -08:00
|
|
|
index 4f1bcf1..11bbb25 100644
|
2017-04-08 18:21:23 -07:00
|
|
|
--- a/server/async.c
|
|
|
|
+++ b/server/async.c
|
2017-07-08 14:09:53 -07:00
|
|
|
@@ -53,6 +53,7 @@ struct async
|
2017-07-08 07:11:26 -07:00
|
|
|
int direct_result; /* a flag if we're passing result directly from request instead of APC */
|
2017-07-08 14:09:53 -07:00
|
|
|
struct completion *completion; /* completion associated with fd */
|
|
|
|
apc_param_t comp_key; /* completion key associated with fd */
|
2017-07-08 07:11:26 -07:00
|
|
|
+ unsigned int comp_flags; /* completion flags */
|
|
|
|
};
|
2017-04-08 18:21:23 -07:00
|
|
|
|
2017-07-08 07:11:26 -07:00
|
|
|
static void async_dump( struct object *obj, int verbose );
|
2017-07-08 14:09:53 -07:00
|
|
|
@@ -237,6 +238,7 @@ struct async *create_async( struct fd *fd, struct thread *thread, const async_da
|
2017-07-08 07:11:26 -07:00
|
|
|
async->wait_handle = 0;
|
|
|
|
async->direct_result = 0;
|
2017-07-12 03:22:15 -07:00
|
|
|
async->completion = fd_get_completion( fd, &async->comp_key );
|
2017-07-08 07:11:26 -07:00
|
|
|
+ async->comp_flags = 0;
|
2017-04-08 18:21:23 -07:00
|
|
|
|
|
|
|
if (iosb) async->iosb = (struct iosb *)grab_object( iosb );
|
|
|
|
else async->iosb = NULL;
|
2017-07-12 03:22:15 -07:00
|
|
|
@@ -256,7 +258,7 @@ struct async *create_async( struct fd *fd, struct thread *thread, const async_da
|
2017-04-08 18:21:23 -07:00
|
|
|
|
2017-07-08 07:11:26 -07:00
|
|
|
/* 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;
|
2017-07-12 03:22:15 -07:00
|
|
|
@@ -274,6 +276,7 @@ struct async *create_request_async( struct fd *fd, const async_data_t *data )
|
2017-07-08 07:11:26 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
async->direct_result = 1;
|
|
|
|
+ async->comp_flags = comp_flags;
|
|
|
|
}
|
|
|
|
return async;
|
|
|
|
}
|
2017-07-12 03:22:15 -07:00
|
|
|
@@ -375,8 +378,11 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota
|
2017-07-08 07:11:26 -07:00
|
|
|
data.user.args[2] = 0;
|
2018-02-15 13:40:30 -08:00
|
|
|
thread_queue_apc( NULL, async->thread, NULL, &data );
|
2017-07-08 07:11:26 -07:00
|
|
|
}
|
|
|
|
- else if (async->data.apc_context)
|
|
|
|
+ else if (async->data.apc_context && (!async->direct_result ||
|
|
|
|
+ !(async->comp_flags & COMPLETION_SKIP_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 );
|
2017-04-08 18:21:23 -07:00
|
|
|
diff --git a/server/fd.c b/server/fd.c
|
2018-02-15 13:40:30 -08:00
|
|
|
index a6a96d6..64dbd1b 100644
|
2017-04-08 18:21:23 -07:00
|
|
|
--- a/server/fd.c
|
|
|
|
+++ b/server/fd.c
|
2018-02-15 13:40:30 -08:00
|
|
|
@@ -2434,7 +2434,7 @@ DECL_HANDLER(flush)
|
2017-07-08 07:11:26 -07:00
|
|
|
|
|
|
|
if (!fd) return;
|
|
|
|
|
|
|
|
- if ((async = create_request_async( fd, &req->async )))
|
|
|
|
+ if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
|
2017-04-08 18:21:23 -07:00
|
|
|
{
|
2017-07-08 07:11:26 -07:00
|
|
|
reply->event = async_handoff( async, fd->fd_ops->flush( fd, async ), NULL );
|
2017-04-08 18:21:23 -07:00
|
|
|
release_object( async );
|
2018-02-15 13:40:30 -08:00
|
|
|
@@ -2533,7 +2533,7 @@ DECL_HANDLER(read)
|
2017-07-08 07:11:26 -07:00
|
|
|
|
|
|
|
if (!fd) return;
|
|
|
|
|
|
|
|
- if ((async = create_request_async( fd, &req->async )))
|
|
|
|
+ if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
|
2017-06-20 15:26:40 -07:00
|
|
|
{
|
2017-07-08 07:11:26 -07:00
|
|
|
reply->wait = async_handoff( async, fd->fd_ops->read( fd, async, req->pos ), NULL );
|
|
|
|
reply->options = fd->options;
|
2018-02-15 13:40:30 -08:00
|
|
|
@@ -2550,7 +2550,7 @@ DECL_HANDLER(write)
|
2017-07-08 07:11:26 -07:00
|
|
|
|
|
|
|
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;
|
2018-02-15 13:40:30 -08:00
|
|
|
@@ -2568,7 +2568,7 @@ DECL_HANDLER(ioctl)
|
2017-07-08 07:11:26 -07:00
|
|
|
|
|
|
|
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 );
|
2017-06-20 15:26:40 -07:00
|
|
|
reply->options = fd->options;
|
2017-04-08 18:21:23 -07:00
|
|
|
diff --git a/server/file.h b/server/file.h
|
2018-02-15 13:40:30 -08:00
|
|
|
index 1d25961..ed42fc4 100644
|
2017-04-08 18:21:23 -07:00
|
|
|
--- a/server/file.h
|
|
|
|
+++ b/server/file.h
|
2018-02-15 13:40:30 -08:00
|
|
|
@@ -185,7 +185,7 @@ extern struct object *create_serial( struct fd *fd );
|
2017-07-08 14:09:53 -07:00
|
|
|
/* async I/O functions */
|
2017-07-08 07:11:26 -07:00
|
|
|
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 );
|
2017-04-08 18:21:23 -07:00
|
|
|
--
|
2018-02-15 13:40:30 -08:00
|
|
|
1.9.1
|
2017-04-08 18:21:23 -07:00
|
|
|
|