server: Change cancel_async to take an optional iosb and only_thread.

This commit is contained in:
Mike Kaplinskiy 2009-08-09 00:08:27 -04:00 committed by Alexandre Julliard
parent e49918b5a2
commit b05774ee7e
8 changed files with 55 additions and 14 deletions

View File

@ -2859,6 +2859,9 @@ struct cancel_async_request
{ {
struct request_header __header; struct request_header __header;
obj_handle_t handle; obj_handle_t handle;
client_ptr_t iosb;
int only_thread;
char __pad_28[4];
}; };
struct cancel_async_reply struct cancel_async_reply
{ {
@ -5312,6 +5315,6 @@ union generic_reply
struct set_window_layered_info_reply set_window_layered_info_reply; struct set_window_layered_info_reply set_window_layered_info_reply;
}; };
#define SERVER_PROTOCOL_VERSION 387 #define SERVER_PROTOCOL_VERSION 388
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -288,6 +288,28 @@ int async_waiting( struct async_queue *queue )
return async->status == STATUS_PENDING; 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 )
{
struct list *ptr, *next;
int woken = 0;
if (!queue || (!process && !thread && !iosb)) return 0;
LIST_FOR_EACH_SAFE( ptr, next, &queue->queue )
{
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) )
{
async_terminate( async, status );
woken++;
}
}
return woken;
}
/* wake up async operations on the queue */ /* wake up async operations on the queue */
void async_wake_up( struct async_queue *queue, unsigned int status ) void async_wake_up( struct async_queue *queue, unsigned int status )
{ {

View File

@ -1856,11 +1856,15 @@ void default_fd_reselect_async( struct fd *fd, struct async_queue *queue )
} }
/* default cancel_async() fd routine */ /* default cancel_async() fd routine */
void default_fd_cancel_async( struct fd *fd ) void default_fd_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb )
{ {
async_wake_up( fd->read_q, STATUS_CANCELLED ); int n = 0;
async_wake_up( fd->write_q, STATUS_CANCELLED );
async_wake_up( fd->wait_q, STATUS_CANCELLED ); 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 );
if (!n && iosb)
set_error( STATUS_NOT_FOUND );
} }
/* default flush() routine */ /* default flush() routine */
@ -2064,10 +2068,11 @@ DECL_HANDLER(register_async)
DECL_HANDLER(cancel_async) DECL_HANDLER(cancel_async)
{ {
struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 ); struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 );
struct thread *thread = req->only_thread ? current : NULL;
if (fd) if (fd)
{ {
if (get_unix_fd( fd ) != -1) fd->fd_ops->cancel_async( fd ); if (get_unix_fd( fd ) != -1) fd->fd_ops->cancel_async( fd, current->process, thread, req->iosb );
release_object( fd ); release_object( fd );
} }
} }

View File

@ -46,7 +46,7 @@ struct fd_ops
/* selected events for async i/o need an update */ /* selected events for async i/o need an update */
void (*reselect_async)( struct fd *, struct async_queue *queue ); void (*reselect_async)( struct fd *, struct async_queue *queue );
/* cancel an async operation */ /* cancel an async operation */
void (*cancel_async)(struct fd *); void (*cancel_async)(struct fd *, struct process *process, struct thread *thread, client_ptr_t iosb);
}; };
/* file descriptor functions */ /* file descriptor functions */
@ -83,7 +83,7 @@ extern obj_handle_t default_fd_ioctl( struct fd *fd, ioctl_code_t code, const as
int blocking, const void *data, data_size_t size ); int blocking, const void *data, data_size_t size );
extern void default_fd_queue_async( struct fd *fd, const async_data_t *data, int type, int count ); extern void default_fd_queue_async( struct fd *fd, const async_data_t *data, int type, int count );
extern void default_fd_reselect_async( struct fd *fd, struct async_queue *queue ); extern void default_fd_reselect_async( struct fd *fd, struct async_queue *queue );
extern void default_fd_cancel_async( struct fd *fd ); extern void default_fd_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb );
extern void no_flush( struct fd *fd, struct event **event ); extern void no_flush( struct fd *fd, struct event **event );
extern void main_loop(void); extern void main_loop(void);
extern void remove_process_locks( struct process *process ); extern void remove_process_locks( struct process *process );
@ -143,6 +143,8 @@ extern void async_set_result( struct object *obj, unsigned int status,
unsigned int total, client_ptr_t apc ); unsigned int total, client_ptr_t apc );
extern int async_waiting( struct async_queue *queue ); extern int async_waiting( struct async_queue *queue );
extern void async_terminate( struct async *async, unsigned int status ); 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 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 struct completion *fd_get_completion( struct fd *fd, apc_param_t *p_key );
extern void fd_copy_completion( struct fd *src, struct fd *dst ); extern void fd_copy_completion( struct fd *src, struct fd *dst );

View File

@ -2072,6 +2072,8 @@ enum message_type
/* Cancel all async op on a fd */ /* Cancel all async op on a fd */
@REQ(cancel_async) @REQ(cancel_async)
obj_handle_t handle; /* handle to comm port, socket or file */ obj_handle_t handle; /* handle to comm port, socket or file */
client_ptr_t iosb; /* I/O status block (NULL=all) */
int only_thread; /* cancel matching this thread */
@END @END

View File

@ -1351,7 +1351,9 @@ C_ASSERT( FIELD_OFFSET(struct register_async_request, async) == 16 );
C_ASSERT( FIELD_OFFSET(struct register_async_request, count) == 56 ); C_ASSERT( FIELD_OFFSET(struct register_async_request, count) == 56 );
C_ASSERT( sizeof(struct register_async_request) == 64 ); C_ASSERT( sizeof(struct register_async_request) == 64 );
C_ASSERT( FIELD_OFFSET(struct cancel_async_request, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct cancel_async_request, handle) == 12 );
C_ASSERT( sizeof(struct cancel_async_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct cancel_async_request, iosb) == 16 );
C_ASSERT( FIELD_OFFSET(struct cancel_async_request, only_thread) == 24 );
C_ASSERT( sizeof(struct cancel_async_request) == 32 );
C_ASSERT( FIELD_OFFSET(struct ioctl_request, code) == 12 ); C_ASSERT( FIELD_OFFSET(struct ioctl_request, code) == 12 );
C_ASSERT( FIELD_OFFSET(struct ioctl_request, async) == 16 ); C_ASSERT( FIELD_OFFSET(struct ioctl_request, async) == 16 );
C_ASSERT( FIELD_OFFSET(struct ioctl_request, blocking) == 56 ); C_ASSERT( FIELD_OFFSET(struct ioctl_request, blocking) == 56 );

View File

@ -97,7 +97,7 @@ static void sock_poll_event( struct fd *fd, int event );
static enum server_fd_type sock_get_fd_type( struct fd *fd ); static enum server_fd_type sock_get_fd_type( struct fd *fd );
static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count ); 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 void sock_reselect_async( struct fd *fd, struct async_queue *queue );
static void sock_cancel_async( struct fd *fd ); static void sock_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb );
static int sock_get_error( int err ); static int sock_get_error( int err );
static void sock_set_error(void); static void sock_set_error(void);
@ -538,13 +538,16 @@ static void sock_reselect_async( struct fd *fd, struct async_queue *queue )
if (events) sock_try_event( sock, events ); if (events) sock_try_event( sock, events );
} }
static void sock_cancel_async( struct fd *fd ) static void sock_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb )
{ {
struct sock *sock = get_fd_user( fd ); struct sock *sock = get_fd_user( fd );
int n = 0;
assert( sock->obj.ops == &sock_ops ); assert( sock->obj.ops == &sock_ops );
async_wake_up( sock->read_q, STATUS_CANCELLED ); n += async_wake_up_by( sock->read_q, process, thread, iosb, STATUS_CANCELLED );
async_wake_up( sock->write_q, STATUS_CANCELLED ); n += async_wake_up_by( sock->write_q, process, thread, iosb, STATUS_CANCELLED );
if (!n && iosb)
set_error( STATUS_NOT_FOUND );
} }
static struct fd *sock_get_fd( struct object *obj ) static struct fd *sock_get_fd( struct object *obj )

View File

@ -2568,6 +2568,8 @@ static void dump_register_async_request( const struct register_async_request *re
static void dump_cancel_async_request( const struct cancel_async_request *req ) static void dump_cancel_async_request( const struct cancel_async_request *req )
{ {
fprintf( stderr, " handle=%04x", req->handle ); fprintf( stderr, " handle=%04x", req->handle );
dump_uint64( ", iosb=", &req->iosb );
fprintf( stderr, ", only_thread=%d", req->only_thread );
} }
static void dump_ioctl_request( const struct ioctl_request *req ) static void dump_ioctl_request( const struct ioctl_request *req )
@ -4583,12 +4585,12 @@ static const struct
{ "IO_TIMEOUT", STATUS_IO_TIMEOUT }, { "IO_TIMEOUT", STATUS_IO_TIMEOUT },
{ "KEY_DELETED", STATUS_KEY_DELETED }, { "KEY_DELETED", STATUS_KEY_DELETED },
{ "MAPPED_FILE_SIZE_ZERO", STATUS_MAPPED_FILE_SIZE_ZERO }, { "MAPPED_FILE_SIZE_ZERO", STATUS_MAPPED_FILE_SIZE_ZERO },
{ "MEDIA_WRITE_PROTECTED", STATUS_MEDIA_WRITE_PROTECTED },
{ "MUTANT_NOT_OWNED", STATUS_MUTANT_NOT_OWNED }, { "MUTANT_NOT_OWNED", STATUS_MUTANT_NOT_OWNED },
{ "NAME_TOO_LONG", STATUS_NAME_TOO_LONG }, { "NAME_TOO_LONG", STATUS_NAME_TOO_LONG },
{ "NOTIFY_ENUM_DIR", STATUS_NOTIFY_ENUM_DIR }, { "NOTIFY_ENUM_DIR", STATUS_NOTIFY_ENUM_DIR },
{ "NOT_ALL_ASSIGNED", STATUS_NOT_ALL_ASSIGNED }, { "NOT_ALL_ASSIGNED", STATUS_NOT_ALL_ASSIGNED },
{ "NOT_A_DIRECTORY", STATUS_NOT_A_DIRECTORY }, { "NOT_A_DIRECTORY", STATUS_NOT_A_DIRECTORY },
{ "NOT_FOUND", STATUS_NOT_FOUND },
{ "NOT_IMPLEMENTED", STATUS_NOT_IMPLEMENTED }, { "NOT_IMPLEMENTED", STATUS_NOT_IMPLEMENTED },
{ "NOT_REGISTRY_FILE", STATUS_NOT_REGISTRY_FILE }, { "NOT_REGISTRY_FILE", STATUS_NOT_REGISTRY_FILE },
{ "NOT_SUPPORTED", STATUS_NOT_SUPPORTED }, { "NOT_SUPPORTED", STATUS_NOT_SUPPORTED },