You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-04-13 14:42:51 -07:00
Rebase against 7e1522cdd69587b59f97a3b3c755cef40a52070e.
This commit is contained in:
@ -1,17 +1,17 @@
|
||||
From 9fc1b0617a1bf5136389984b9931ab92a42e56dc Mon Sep 17 00:00:00 2001
|
||||
From 9c2428d179473d7bd8e383132e408edd330f8e80 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sun, 9 Apr 2017 03:13:25 +0200
|
||||
Subject: server: Skip async completion when possible.
|
||||
|
||||
---
|
||||
dlls/ntdll/tests/pipe.c | 2 --
|
||||
server/async.c | 12 +++++++++++-
|
||||
server/fd.c | 4 ++++
|
||||
server/file.h | 1 +
|
||||
4 files changed, 16 insertions(+), 3 deletions(-)
|
||||
server/async.c | 10 ++++++++--
|
||||
server/fd.c | 8 ++++----
|
||||
server/file.h | 2 +-
|
||||
4 files changed, 13 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c
|
||||
index 6846b514dc2..a6f8135624a 100644
|
||||
index bda9a144ade..aa240edea21 100644
|
||||
--- a/dlls/ntdll/tests/pipe.c
|
||||
+++ b/dlls/ntdll/tests/pipe.c
|
||||
@@ -389,9 +389,7 @@ static void test_completion(void)
|
||||
@ -25,97 +25,108 @@ index 6846b514dc2..a6f8135624a 100644
|
||||
|
||||
CloseHandle(ov.hEvent);
|
||||
diff --git a/server/async.c b/server/async.c
|
||||
index f50cdc5a45a..d222287c30b 100644
|
||||
index 3a83a6302bf..770ed493819 100644
|
||||
--- a/server/async.c
|
||||
+++ b/server/async.c
|
||||
@@ -45,6 +45,7 @@ struct async
|
||||
struct timeout_user *timeout;
|
||||
unsigned int timeout_status; /* status to report upon timeout */
|
||||
int signaled;
|
||||
+ int skip_completion; /* skip completion */
|
||||
struct event *event;
|
||||
async_data_t data; /* data for async I/O call */
|
||||
@@ -51,6 +51,7 @@ struct async
|
||||
struct iosb *iosb; /* I/O status block */
|
||||
@@ -180,6 +181,14 @@ static void async_queue_destroy( struct object *obj )
|
||||
if (async_queue->completion) release_object( async_queue->completion );
|
||||
}
|
||||
obj_handle_t wait_handle; /* pre-allocated wait handle */
|
||||
int direct_result; /* a flag if we're passing result directly from request instead of APC */
|
||||
+ unsigned int comp_flags; /* completion flags */
|
||||
};
|
||||
|
||||
+void async_skip_completion( struct async *async, int comp_flags )
|
||||
+{
|
||||
+ if (!async->data.user) return;
|
||||
+ if (!(comp_flags & COMPLETION_SKIP_ON_SUCCESS)) return;
|
||||
+ async->skip_completion = (async->status == STATUS_SUCCESS ||
|
||||
+ async->status == STATUS_ALERTED);
|
||||
+}
|
||||
+
|
||||
/* notifies client thread of new status of its async request */
|
||||
void async_terminate( struct async *async, unsigned int status )
|
||||
{
|
||||
@@ -278,6 +287,7 @@ struct async *create_async( struct thread *thread, const async_data_t *data, str
|
||||
async->queue = NULL;
|
||||
async->signaled = 0;
|
||||
async->wait_handle = 0;
|
||||
+ async->skip_completion = 0;
|
||||
static void async_dump( struct object *obj, int verbose );
|
||||
@@ -294,6 +295,7 @@ struct async *create_async( struct fd *fd, struct thread *thread, const async_da
|
||||
async->signaled = 0;
|
||||
async->wait_handle = 0;
|
||||
async->direct_result = 0;
|
||||
+ async->comp_flags = 0;
|
||||
|
||||
if (iosb) async->iosb = (struct iosb *)grab_object( iosb );
|
||||
else async->iosb = NULL;
|
||||
@@ -384,7 +394,7 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota
|
||||
async->status = status;
|
||||
if (status == STATUS_MORE_PROCESSING_REQUIRED) return; /* don't report the completion */
|
||||
@@ -306,7 +308,7 @@ struct async *create_async( struct fd *fd, struct thread *thread, const async_da
|
||||
|
||||
- if (async->queue && !async->data.apc && async->data.apc_context)
|
||||
+ if (async->queue && !async->data.apc && async->data.apc_context && !async->skip_completion)
|
||||
add_async_completion( async->queue, async->data.apc_context, status, total );
|
||||
if (async->data.apc)
|
||||
{
|
||||
/* 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;
|
||||
@@ -324,6 +326,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;
|
||||
}
|
||||
@@ -438,8 +441,11 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota
|
||||
data.user.args[2] = 0;
|
||||
thread_queue_apc( async->thread, NULL, &data );
|
||||
}
|
||||
- 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 );
|
||||
diff --git a/server/fd.c b/server/fd.c
|
||||
index a2640468644..75cb9bff945 100644
|
||||
index 6747aaabdb4..2a8ecb12b8e 100644
|
||||
--- a/server/fd.c
|
||||
+++ b/server/fd.c
|
||||
@@ -2381,6 +2381,7 @@ DECL_HANDLER(flush)
|
||||
if (async)
|
||||
@@ -2377,7 +2377,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 = fd->fd_ops->flush( fd, async );
|
||||
+ async_skip_completion( async, fd->comp_flags );
|
||||
reply->event = async_handoff( async, fd->fd_ops->flush( fd, async ), NULL );
|
||||
release_object( async );
|
||||
}
|
||||
release_object( fd );
|
||||
@@ -2457,6 +2458,7 @@ DECL_HANDLER(read)
|
||||
@@ -2452,7 +2452,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 ) );
|
||||
reply->wait = async_handoff( async, fd->fd_ops->read( fd, async, req->pos ), NULL );
|
||||
reply->options = fd->options;
|
||||
@@ -2469,7 +2469,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;
|
||||
@@ -2487,7 +2487,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;
|
||||
+ async_skip_completion( async, fd->comp_flags );
|
||||
release_object( async );
|
||||
}
|
||||
release_object( fd );
|
||||
@@ -2478,6 +2480,7 @@ DECL_HANDLER(write)
|
||||
{
|
||||
reply->wait = fd->fd_ops->write( fd, async, req->pos );
|
||||
reply->options = fd->options;
|
||||
+ async_skip_completion( async, fd->comp_flags );
|
||||
release_object( async );
|
||||
}
|
||||
release_object( iosb );
|
||||
@@ -2501,6 +2504,7 @@ DECL_HANDLER(ioctl)
|
||||
{
|
||||
reply->wait = fd->fd_ops->ioctl( fd, req->code, async );
|
||||
reply->options = fd->options;
|
||||
+ async_skip_completion( async, fd->comp_flags );
|
||||
release_object( async );
|
||||
}
|
||||
release_object( iosb );
|
||||
diff --git a/server/file.h b/server/file.h
|
||||
index 8cc4d3beab2..f4482982cfe 100644
|
||||
index 386f76c4be2..1c9c66fdad1 100644
|
||||
--- a/server/file.h
|
||||
+++ b/server/file.h
|
||||
@@ -183,6 +183,7 @@ extern void async_set_timeout( struct async *async, timeout_t timeout, unsigned
|
||||
extern void async_set_result( struct object *obj, unsigned int status, apc_param_t total );
|
||||
extern int async_queued( struct async_queue *queue );
|
||||
extern int async_waiting( struct async_queue *queue );
|
||||
+extern void async_skip_completion( struct async *async, int comp_flags );
|
||||
extern void async_terminate( struct async *async, unsigned int status );
|
||||
extern void async_wake_up( struct async_queue *queue, unsigned int status );
|
||||
extern struct completion *fd_get_completion( struct fd *fd, apc_param_t *p_key );
|
||||
@@ -176,7 +176,7 @@ extern struct object *create_serial( struct fd *fd );
|
||||
extern struct async_queue *create_async_queue( struct fd *fd );
|
||||
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 );
|
||||
--
|
||||
2.13.1
|
||||
|
||||
|
Reference in New Issue
Block a user