Jacek Caban : server: Store async list in process object and use that to find async in cansel_async request.
Alexandre Julliard
julliard at winehq.org
Thu Dec 1 15:37:44 CST 2016
Module: wine
Branch: master
Commit: 055918c9829d4b31e4599bf3a45faf501116a15e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=055918c9829d4b31e4599bf3a45faf501116a15e
Author: Jacek Caban <jacek at codeweavers.com>
Date: Thu Dec 1 12:10:23 2016 +0100
server: Store async list in process object and use that to find async in cansel_async request.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
server/async.c | 40 +++++++++++++++++++++++++++++-----------
server/fd.c | 21 +--------------------
server/file.h | 2 --
server/process.c | 2 ++
server/process.h | 1 +
server/sock.c | 16 +---------------
6 files changed, 34 insertions(+), 48 deletions(-)
diff --git a/server/async.c b/server/async.c
index 64aa27a..5acd1e7 100644
--- a/server/async.c
+++ b/server/async.c
@@ -31,12 +31,15 @@
#include "object.h"
#include "file.h"
#include "request.h"
+#include "process.h"
+#include "handle.h"
struct async
{
struct object obj; /* object header */
struct thread *thread; /* owning thread */
struct list queue_entry; /* entry in async queue list */
+ struct list process_entry; /* entry in process list */
struct async_queue *queue; /* queue containing this async */
unsigned int status; /* current status */
struct timeout_user *timeout;
@@ -132,6 +135,7 @@ static void async_destroy( struct object *obj )
struct async *async = (struct async *)obj;
assert( obj->ops == &async_ops );
+ list_remove( &async->process_entry );
list_remove( &async->queue_entry );
async_reselect( async );
@@ -244,6 +248,7 @@ struct async *create_async( struct thread *thread, struct async_queue *queue, co
async->signaled = 0;
list_add_tail( &queue->queue, &async->queue_entry );
+ list_add_tail( &thread->process->asyncs, &async->process_entry );
grab_object( async );
if (queue->fd) set_fd_signaled( queue->fd, 0 );
@@ -343,23 +348,22 @@ int async_waiting( struct async_queue *queue )
return async->status == STATUS_PENDING;
}
-int async_wake_up_by( struct async_queue *queue, struct process *process,
- struct thread *thread, client_ptr_t iosb, unsigned int status )
+static int cancel_async( struct process *process, struct object *obj, struct thread *thread, client_ptr_t iosb )
{
- struct list *ptr, *next;
+ struct async *async;
int woken = 0;
- if (!queue || (!process && !thread && !iosb)) return 0;
-
- LIST_FOR_EACH_SAFE( ptr, next, &queue->queue )
+restart:
+ LIST_FOR_EACH_ENTRY( async, &process->asyncs, struct async, process_entry )
{
- struct async *async = LIST_ENTRY( ptr, struct async, queue_entry );
- if ( (!process || async->thread->process == process) &&
- (!thread || async->thread == thread) &&
- (!iosb || async->data.iosb == iosb) )
+ if (async->status == STATUS_CANCELLED) continue;
+ if ((!obj || (async->queue->fd && get_fd_user( async->queue->fd ) == obj)) &&
+ (!thread || async->thread == thread) &&
+ (!iosb || async->data.iosb == iosb))
{
- async_terminate( async, status );
+ async_terminate( async, STATUS_CANCELLED );
woken++;
+ goto restart;
}
}
return woken;
@@ -379,3 +383,17 @@ void async_wake_up( struct async_queue *queue, unsigned int status )
if (status == STATUS_ALERTED) break; /* only wake up the first one */
}
}
+
+/* cancels all async I/O */
+DECL_HANDLER(cancel_async)
+{
+ struct object *obj = get_handle_obj( current->process, req->handle, 0, NULL );
+ struct thread *thread = req->only_thread ? current : NULL;
+
+ if (obj)
+ {
+ int count = cancel_async( current->process, obj, thread, req->iosb );
+ if (!count && req->iosb) set_error( STATUS_NOT_FOUND );
+ release_object( obj );
+ }
+}
diff --git a/server/fd.c b/server/fd.c
index 66d34d7..a75ff76 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -2118,12 +2118,7 @@ void default_fd_reselect_async( struct fd *fd, struct async_queue *queue )
/* default cancel_async() fd routine */
int default_fd_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb )
{
- int n = 0;
-
- n += async_wake_up_by( fd->read_q, process, thread, iosb, STATUS_CANCELLED );
- n += async_wake_up_by( fd->write_q, process, thread, iosb, STATUS_CANCELLED );
- n += async_wake_up_by( fd->wait_q, process, thread, iosb, STATUS_CANCELLED );
- return n;
+ return 0;
}
static inline int is_valid_mounted_device( struct stat *st )
@@ -2519,20 +2514,6 @@ DECL_HANDLER(register_async)
}
}
-/* cancels all async I/O */
-DECL_HANDLER(cancel_async)
-{
- struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 );
- struct thread *thread = req->only_thread ? current : NULL;
-
- if (fd)
- {
- int count = fd->fd_ops->cancel_async( fd, current->process, thread, req->iosb );
- if (!count && req->iosb) set_error( STATUS_NOT_FOUND );
- release_object( fd );
- }
-}
-
/* attach completion object to a fd */
DECL_HANDLER(set_completion_info)
{
diff --git a/server/file.h b/server/file.h
index b643d94..7c68248 100644
--- a/server/file.h
+++ b/server/file.h
@@ -175,8 +175,6 @@ extern void async_set_result( struct object *obj, unsigned int status,
extern int async_queued( struct async_queue *queue );
extern int async_waiting( struct async_queue *queue );
extern void async_terminate( struct async *async, unsigned int status );
-extern int async_wake_up_by( struct async_queue *queue, struct process *process,
- struct thread *thread, client_ptr_t iosb, 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 );
extern void fd_copy_completion( struct fd *src, struct fd *dst );
diff --git a/server/process.c b/server/process.c
index 528ec74..cca18e9 100644
--- a/server/process.c
+++ b/server/process.c
@@ -535,6 +535,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit
process->rawinput_kbd = NULL;
list_init( &process->thread_list );
list_init( &process->locks );
+ list_init( &process->asyncs );
list_init( &process->classes );
list_init( &process->dlls );
list_init( &process->rawinput_devices );
@@ -614,6 +615,7 @@ static void process_destroy( struct object *obj )
/* we can't have a thread remaining */
assert( list_empty( &process->thread_list ));
+ assert( list_empty( &process->asyncs ));
assert( !process->sigkill_timeout ); /* timeout should hold a reference to the process */
diff --git a/server/process.h b/server/process.h
index 4e6de69..548796f 100644
--- a/server/process.h
+++ b/server/process.h
@@ -78,6 +78,7 @@ struct process
unsigned int is_terminating:1;/* is process terminating? */
struct job *job; /* job object ascoicated with this process */
struct list job_entry; /* list entry for job object */
+ struct list asyncs; /* list of async object owned by the process */
struct list locks; /* list of file locks owned by the process */
struct list classes; /* window classes owned by the process */
struct console_input*console; /* console input */
diff --git a/server/sock.c b/server/sock.c
index 0de6f68..2cd3b0e 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -132,7 +132,6 @@ static enum server_fd_type sock_get_fd_type( struct fd *fd );
static obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async, int blocking );
static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count );
static void sock_reselect_async( struct fd *fd, struct async_queue *queue );
-static int sock_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb );
static int sock_get_ntstatus( int err );
static int sock_get_error( int err );
@@ -171,7 +170,7 @@ static const struct fd_ops sock_fd_ops =
sock_ioctl, /* ioctl */
sock_queue_async, /* queue_async */
sock_reselect_async, /* reselect_async */
- sock_cancel_async /* cancel_async */
+ default_fd_cancel_async /* cancel_async */
};
@@ -611,19 +610,6 @@ static void sock_reselect_async( struct fd *fd, struct async_queue *queue )
sock_reselect( sock );
}
-static int sock_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb )
-{
- struct sock *sock = get_fd_user( fd );
- int n = 0;
-
- assert( sock->obj.ops == &sock_ops );
-
- n += async_wake_up_by( sock->read_q, process, thread, iosb, STATUS_CANCELLED );
- n += async_wake_up_by( sock->write_q, process, thread, iosb, STATUS_CANCELLED );
- n += async_wake_up_by( sock->ifchange_q, process, thread, iosb, STATUS_CANCELLED );
- return n;
-}
-
static struct fd *sock_get_fd( struct object *obj )
{
struct sock *sock = (struct sock *)obj;
More information about the wine-cvs
mailing list