From 111610c45e9d99dfbf7ec59e7fcbdc1b2dfc2cba Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 20 Mar 2007 20:21:12 +0100 Subject: [PATCH] server: Add an async_data_t structure to store parameters for async I/O requests. --- dlls/ntdll/directory.c | 6 +++--- dlls/ntdll/file.c | 18 +++++++++--------- dlls/ws2_32/socket.c | 6 +++--- include/wine/server_protocol.h | 26 +++++++++++++------------- server/async.c | 16 ++++++---------- server/change.c | 4 +--- server/fd.c | 15 ++++++--------- server/file.h | 10 +++++----- server/mailslot.c | 9 ++++----- server/named_pipe.c | 13 ++++++------- server/protocol.def | 24 ++++++++++++------------ server/serial.c | 7 +++---- server/sock.c | 8 +++----- server/trace.c | 28 +++++++++++++++------------- tools/make_requests | 1 + 15 files changed, 90 insertions(+), 101 deletions(-) diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c index 66547b5a14..410f35cc78 100644 --- a/dlls/ntdll/directory.c +++ b/dlls/ntdll/directory.c @@ -2272,9 +2272,9 @@ NtNotifyChangeDirectoryFile( HANDLE FileHandle, HANDLE Event, req->filter = CompletionFilter; req->want_data = (Buffer != NULL); req->subtree = WatchTree; - req->io_apc = read_changes_apc; - req->io_sb = IoStatusBlock; - req->io_user = info; + req->async.callback = read_changes_apc; + req->async.iosb = IoStatusBlock; + req->async.arg = info; status = wine_server_call( req ); } SERVER_END_REQ; diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 65b4783f77..b15e5b5fc6 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -318,9 +318,9 @@ static ULONG fileio_queue_async(async_fileio* fileio, IO_STATUS_BLOCK* iosb, SERVER_START_REQ( register_async ) { req->handle = fileio->handle; - req->io_apc = apc; - req->io_sb = iosb; - req->io_user = fileio; + req->async.callback = apc; + req->async.iosb = iosb; + req->async.arg = fileio; req->type = do_read ? ASYNC_TYPE_READ : ASYNC_TYPE_WRITE; req->count = (fileio->count < iosb->Information) ? 0 : fileio->count - iosb->Information; @@ -983,9 +983,9 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc SERVER_START_REQ(connect_named_pipe) { req->handle = handle; - req->io_apc = pipe_completion_wait; - req->io_sb = io; - req->io_user = event ? event : internal_event; + req->async.callback = pipe_completion_wait; + req->async.iosb = io; + req->async.arg = event ? event : internal_event; io->u.Status = wine_server_call(req); } SERVER_END_REQ; @@ -1019,9 +1019,9 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc req->handle = handle; req->timeout = buff->TimeoutSpecified ? buff->Timeout.QuadPart / -10000L : NMPWAIT_USE_DEFAULT_WAIT; - req->io_apc = pipe_completion_wait; - req->io_sb = io; - req->io_user = event ? event : internal_event; + req->async.callback = pipe_completion_wait; + req->async.iosb = io; + req->async.arg = event ? event : internal_event; wine_server_add_data( req, buff->Name, buff->NameLength ); io->u.Status = wine_server_call( req ); } diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index e14eba82af..679dffc632 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -1158,9 +1158,9 @@ static ULONG ws2_queue_async(struct ws2_async* wsa, IO_STATUS_BLOCK* iosb) SERVER_START_REQ( register_async ) { req->handle = wsa->hSocket; - req->io_apc = apc; - req->io_sb = iosb; - req->io_user = wsa; + req->async.callback = apc; + req->async.iosb = iosb; + req->async.arg = wsa; req->type = type; req->count = iosb->Information; status = wine_server_call( req ); diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 6c172425dd..b97e39a9eb 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -157,6 +157,14 @@ typedef struct } rectangle_t; +typedef struct +{ + void *callback; + void *iosb; + void *arg; +} async_data_t; + + struct callback_msg_data { @@ -1649,9 +1657,7 @@ struct read_directory_changes_request obj_handle_t event; int subtree; int want_data; - void* io_apc; - void* io_sb; - void* io_user; + async_data_t async; }; struct read_directory_changes_reply { @@ -2639,10 +2645,8 @@ struct register_async_request struct request_header __header; obj_handle_t handle; int type; - void* io_apc; - void* io_sb; - void* io_user; int count; + async_data_t async; }; struct register_async_reply { @@ -2714,9 +2718,7 @@ struct connect_named_pipe_request { struct request_header __header; obj_handle_t handle; - void* io_apc; - void* io_sb; - void* io_user; + async_data_t async; }; struct connect_named_pipe_reply { @@ -2729,10 +2731,8 @@ struct wait_named_pipe_request { struct request_header __header; obj_handle_t handle; + async_data_t async; unsigned int timeout; - void* io_apc; - void* io_sb; - void* io_user; /* VARARG(name,unicode_str); */ }; struct wait_named_pipe_reply @@ -4699,6 +4699,6 @@ union generic_reply struct allocate_locally_unique_id_reply allocate_locally_unique_id_reply; }; -#define SERVER_PROTOCOL_VERSION 282 +#define SERVER_PROTOCOL_VERSION 283 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/async.c b/server/async.c index cb4675c974..b88f8f5034 100644 --- a/server/async.c +++ b/server/async.c @@ -38,9 +38,7 @@ struct async struct thread *thread; /* owning thread */ struct list queue_entry; /* entry in file descriptor queue */ struct timeout_user *timeout; - void *apc; /* apc function to call when alerted */ - void *user; /* user-private argument for apc */ - void *sb; /* pointer to I/O status block in client addr space */ + async_data_t data; /* data for async I/O call */ }; static void async_dump( struct object *obj, int verbose ); @@ -86,9 +84,9 @@ static void async_terminate( struct async *async, unsigned int status ) memset( &data, 0, sizeof(data) ); data.type = APC_ASYNC_IO; - data.async_io.func = async->apc; - data.async_io.user = async->user; - data.async_io.sb = async->sb; + data.async_io.func = async->data.callback; + data.async_io.user = async->data.arg; + data.async_io.sb = async->data.iosb; data.async_io.status = status; thread_queue_apc( async->thread, &async->obj, &data ); @@ -109,16 +107,14 @@ static void async_timeout( void *private ) /* create an async on a given queue of a fd */ struct async *create_async( struct thread *thread, const struct timeval *timeout, - struct list *queue, void *io_apc, void *io_user, void *io_sb ) + struct list *queue, const async_data_t *data ) { struct async *async = alloc_object( &async_ops ); if (!async) return NULL; async->thread = (struct thread *)grab_object( thread ); - async->apc = io_apc; - async->user = io_user; - async->sb = io_sb; + async->data = *data; list_add_tail( queue, &async->queue_entry ); diff --git a/server/change.c b/server/change.c index c90adbe7da..b556a12415 100644 --- a/server/change.c +++ b/server/change.c @@ -1100,9 +1100,7 @@ DECL_HANDLER(read_directory_changes) dir->event = event; /* requests don't timeout */ - if ( req->io_apc && !create_async( current, NULL, &dir->change_q, - req->io_apc, req->io_user, req->io_sb )) - return; + if (!create_async( current, NULL, &dir->change_q, &req->async )) return; /* assign it once */ if (!dir->filter) diff --git a/server/fd.c b/server/fd.c index 5e03c7bae2..7d9e7f0c9a 100644 --- a/server/fd.c +++ b/server/fd.c @@ -1711,7 +1711,7 @@ void default_poll_event( struct fd *fd, int event ) wake_up( fd->user, 0 ); } -void fd_queue_async_timeout( struct fd *fd, void *apc, void *user, void *io_sb, int type, int count, +void fd_queue_async_timeout( struct fd *fd, const async_data_t *data, int type, int count, const struct timeval *timeout ) { struct list *queue; @@ -1737,8 +1737,7 @@ void fd_queue_async_timeout( struct fd *fd, void *apc, void *user, void *io_sb, return; } - if (!create_async( current, timeout, queue, apc, user, io_sb )) - return; + if (!create_async( current, timeout, queue, data )) return; /* Check if the new pending request can be served immediately */ events = check_fd_events( fd, fd->fd_ops->get_poll_events( fd ) ); @@ -1747,9 +1746,9 @@ void fd_queue_async_timeout( struct fd *fd, void *apc, void *user, void *io_sb, set_fd_events( fd, fd->fd_ops->get_poll_events( fd ) ); } -void default_fd_queue_async( struct fd *fd, void *apc, void *user, void *io_sb, int type, int count ) +void default_fd_queue_async( struct fd *fd, const async_data_t *data, int type, int count ) { - fd_queue_async_timeout( fd, apc, user, io_sb, type, count, NULL ); + fd_queue_async_timeout( fd, data, type, count, NULL ); } void default_fd_cancel_async( struct fd *fd ) @@ -1773,8 +1772,7 @@ enum server_fd_type no_get_file_info( struct fd *fd, int *flags ) } /* default queue_async() routine */ -void no_queue_async( struct fd *fd, void* apc, void* user, void* io_sb, - int type, int count) +void no_queue_async( struct fd *fd, const async_data_t *data, int type, int count) { set_error( STATUS_OBJECT_TYPE_MISMATCH ); } @@ -1945,8 +1943,7 @@ DECL_HANDLER(register_async) if (fd) { - fd->fd_ops->queue_async( fd, req->io_apc, req->io_user, req->io_sb, - req->type, req->count ); + fd->fd_ops->queue_async( fd, &req->async, req->type, req->count ); release_object( fd ); } } diff --git a/server/file.h b/server/file.h index 6402d61ed8..ae98cf15bb 100644 --- a/server/file.h +++ b/server/file.h @@ -39,7 +39,7 @@ struct fd_ops /* get file information */ enum server_fd_type (*get_file_info)(struct fd *fd, int *flags); /* queue an async operation */ - void (*queue_async)(struct fd *, void* apc, void* user, void* io_sb, int type, int count); + void (*queue_async)(struct fd *, const async_data_t *data, int type, int count); /* cancel an async operation */ void (*cancel_async)(struct fd *); }; @@ -68,13 +68,13 @@ extern void default_fd_remove_queue( struct object *obj, struct wait_queue_entry extern int default_fd_signaled( struct object *obj, struct thread *thread ); extern int default_fd_get_poll_events( struct fd *fd ); extern void default_poll_event( struct fd *fd, int event ); -extern void fd_queue_async_timeout( struct fd *fd, void *apc, void *user, void *io_sb, int type, +extern void fd_queue_async_timeout( struct fd *fd, const async_data_t *data, int type, int count, const struct timeval *timeout ); -extern void default_fd_queue_async( struct fd *fd, void *apc, void *user, void *io_sb, 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_cancel_async( struct fd *fd ); extern int no_flush( struct fd *fd, struct event **event ); extern enum server_fd_type no_get_file_info( struct fd *fd, int *flags ); -extern void no_queue_async( struct fd *fd, void* apc, void* user, void* io_sb, int type, int count); +extern void no_queue_async( struct fd *fd, const async_data_t *data, int type, int count); extern void no_cancel_async( struct fd *fd ); extern void main_loop(void); extern void remove_process_locks( struct process *process ); @@ -123,7 +123,7 @@ extern struct object *create_serial( struct fd *fd, unsigned int options ); /* async I/O functions */ extern struct async *create_async( struct thread *thread, const struct timeval *timeout, - struct list *queue, void *, void *, void *); + struct list *queue, const async_data_t *data ); extern void async_terminate_head( struct list *queue, unsigned int status ); extern void async_terminate_queue( struct list *queue, unsigned int status ); diff --git a/server/mailslot.c b/server/mailslot.c index d9537f4281..f2c191539e 100644 --- a/server/mailslot.c +++ b/server/mailslot.c @@ -85,7 +85,7 @@ static const struct object_ops mailslot_ops = }; static enum server_fd_type mailslot_get_info( struct fd *fd, int *flags ); -static void mailslot_queue_async( struct fd *, void*, void*, void*, int, int ); +static void mailslot_queue_async( struct fd *fd, const async_data_t *data, int type, int count ); static const struct fd_ops mailslot_fd_ops = { @@ -236,8 +236,7 @@ static unsigned int mailslot_map_access( struct object *obj, unsigned int access return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); } -static void mailslot_queue_async( struct fd *fd, void *apc, void *user, - void *iosb, int type, int count ) +static void mailslot_queue_async( struct fd *fd, const async_data_t *data, int type, int count ) { struct mailslot *mailslot = get_fd_user( fd ); @@ -260,9 +259,9 @@ static void mailslot_queue_async( struct fd *fd, void *apc, void *user, { struct timeval when = current_time; add_timeout( &when, mailslot->read_timeout ); - fd_queue_async_timeout( fd, apc, user, iosb, type, count, &when ); + fd_queue_async_timeout( fd, data, type, count, &when ); } - else fd_queue_async_timeout( fd, apc, user, iosb, type, count, NULL ); + else fd_queue_async_timeout( fd, data, type, count, NULL ); } static void mailslot_device_dump( struct object *obj, int verbose ) diff --git a/server/named_pipe.c b/server/named_pipe.c index 5eba500408..61ddd37f46 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -824,7 +824,7 @@ DECL_HANDLER(connect_named_pipe) case ps_wait_connect: assert( !server->fd ); server->state = ps_wait_open; - create_async( current, NULL, &server->wait_q, req->io_apc, req->io_user, req->io_sb ); + create_async( current, NULL, &server->wait_q, &req->async ); async_terminate_queue( &server->pipe->waiters, STATUS_SUCCESS ); break; case ps_connected_server: @@ -872,9 +872,9 @@ DECL_HANDLER(wait_named_pipe) /* there's already a server waiting for a client to connect */ memset( &data, 0, sizeof(data) ); data.type = APC_ASYNC_IO; - data.async_io.func = req->io_apc; - data.async_io.user = req->io_user; - data.async_io.sb = req->io_sb; + data.async_io.func = req->async.callback; + data.async_io.user = req->async.arg; + data.async_io.sb = req->async.iosb; data.async_io.status = STATUS_SUCCESS; thread_queue_apc( current, NULL, &data ); release_object( server ); @@ -882,14 +882,13 @@ DECL_HANDLER(wait_named_pipe) else { if (req->timeout == NMPWAIT_WAIT_FOREVER) - create_async( current, NULL, &pipe->waiters, - req->io_apc, req->io_user, req->io_sb ); + create_async( current, NULL, &pipe->waiters, &req->async ); else { struct timeval when = current_time; if (req->timeout == NMPWAIT_USE_DEFAULT_WAIT) add_timeout( &when, pipe->timeout ); else add_timeout( &when, req->timeout ); - create_async( current, &when, &pipe->waiters, req->io_apc, req->io_user, req->io_sb ); + create_async( current, &when, &pipe->waiters, &req->async ); } } diff --git a/server/protocol.def b/server/protocol.def index 57e306fe94..145fbebadb 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -172,6 +172,14 @@ typedef struct int bottom; } rectangle_t; +/* structure for parameters of async I/O calls */ +typedef struct +{ + void *callback; /* client-side callback to call upon end of async */ + void *iosb; /* I/O status block in client addr space */ + void *arg; /* opaque user data to pass to callback */ +} async_data_t; + /* structures for extra message data */ struct callback_msg_data @@ -1293,9 +1301,7 @@ enum char_info_mode obj_handle_t event; /* handle to the event */ int subtree; /* watch the subtree? */ int want_data; /* flag indicating whether change data should be collected */ - void* io_apc; /* APC routine to queue upon end of async */ - void* io_sb; /* I/O status block (unique across all async on this handle) */ - void* io_user; /* data to pass back to caller */ + async_data_t async; /* async I/O parameters */ @END @@ -1949,10 +1955,8 @@ enum message_type @REQ(register_async) obj_handle_t handle; /* handle to comm port, socket or file */ int type; /* type of queue to look after */ - void* io_apc; /* APC routine to queue upon end of async */ - void* io_sb; /* I/O status block (unique across all async on this handle) */ - void* io_user; /* data to pass back to caller */ int count; /* count - usually # of bytes to be read/written */ + async_data_t async; /* async I/O parameters */ @END #define ASYNC_TYPE_READ 0x01 #define ASYNC_TYPE_WRITE 0x02 @@ -2002,19 +2006,15 @@ enum message_type /* Connect to a named pipe */ @REQ(connect_named_pipe) obj_handle_t handle; - void* io_apc; /* APC routine to queue upon end of async */ - void* io_sb; /* I/O status block */ - void* io_user; /* data to pass back to caller */ + async_data_t async; /* async I/O parameters */ @END /* Wait for a named pipe */ @REQ(wait_named_pipe) obj_handle_t handle; + async_data_t async; /* async I/O parameters */ unsigned int timeout; - void* io_apc; /* APC routine to queue upon end of async */ - void* io_sb; /* I/O status block */ - void* io_user; /* data to pass back to caller */ VARARG(name,unicode_str); /* pipe name */ @END diff --git a/server/serial.c b/server/serial.c index 866547b9fb..40724d8929 100644 --- a/server/serial.c +++ b/server/serial.c @@ -65,7 +65,7 @@ static int serial_get_poll_events( struct fd *fd ); static void serial_poll_event( struct fd *fd, int event ); static enum server_fd_type serial_get_info( struct fd *fd, int *flags ); static int serial_flush( struct fd *fd, struct event **event ); -static void serial_queue_async( struct fd *fd, void *apc, void *user, void *iosb, int type, int count ); +static void serial_queue_async( struct fd *fd, const async_data_t *data, int type, int count ); static void serial_cancel_async( struct fd *fd ); struct serial @@ -241,8 +241,7 @@ static void serial_poll_event(struct fd *fd, int event) set_fd_events( fd, serial_get_poll_events(fd) ); } -static void serial_queue_async( struct fd *fd, void *apc, void *user, void *iosb, - int type, int count ) +static void serial_queue_async( struct fd *fd, const async_data_t *data, int type, int count ) { struct serial *serial = get_fd_user( fd ); struct list *queue; @@ -272,7 +271,7 @@ static void serial_queue_async( struct fd *fd, void *apc, void *user, void *iosb } add_timeout( &when, timeout ); - if (!create_async( current, timeout ? &when : NULL, queue, apc, user, iosb )) return; + if (!create_async( current, timeout ? &when : NULL, queue, data )) return; /* Check if the new pending request can be served immediately */ events = check_fd_events( fd, serial_get_poll_events( fd ) ); diff --git a/server/sock.c b/server/sock.c index 5830190476..e8d6ef3e2d 100644 --- a/server/sock.c +++ b/server/sock.c @@ -96,7 +96,7 @@ static void sock_destroy( struct object *obj ); static int sock_get_poll_events( struct fd *fd ); static void sock_poll_event( struct fd *fd, int event ); static enum server_fd_type sock_get_info( struct fd *fd, int *flags ); -static void sock_queue_async( struct fd *fd, void *apc, void *user, void *iosb, int type, int count ); +static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count ); static void sock_cancel_async( struct fd *fd ); static int sock_get_error( int err ); @@ -508,8 +508,7 @@ static enum server_fd_type sock_get_info( struct fd *fd, int *flags ) return FD_TYPE_SOCKET; } -static void sock_queue_async( struct fd *fd, void *apc, void *user, void *iosb, - int type, int count ) +static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count ) { struct sock *sock = get_fd_user( fd ); struct list *queue; @@ -544,8 +543,7 @@ static void sock_queue_async( struct fd *fd, void *apc, void *user, void *iosb, } else { - if (!create_async( current, NULL, queue, apc, user, iosb )) - return; + if (!create_async( current, NULL, queue, data )) return; } pollev = sock_reselect( sock ); diff --git a/server/trace.c b/server/trace.c index 659ec28cfb..a840c1301e 100644 --- a/server/trace.c +++ b/server/trace.c @@ -243,6 +243,11 @@ static void dump_apc_result( const apc_result_t *result ) fputc( '}', stderr ); } +static void dump_async_data( const async_data_t *data ) +{ + fprintf( stderr, "{callback=%p,iosb=%p,arg=%p}", data->callback, data->iosb, data->arg ); +} + static void dump_luid( const luid_t *luid ) { fprintf( stderr, "%d.%u", luid->high_part, luid->low_part ); @@ -1652,9 +1657,8 @@ static void dump_read_directory_changes_request( const struct read_directory_cha fprintf( stderr, " event=%p,", req->event ); fprintf( stderr, " subtree=%d,", req->subtree ); fprintf( stderr, " want_data=%d,", req->want_data ); - fprintf( stderr, " io_apc=%p,", req->io_apc ); - fprintf( stderr, " io_sb=%p,", req->io_sb ); - fprintf( stderr, " io_user=%p", req->io_user ); + fprintf( stderr, " async=" ); + dump_async_data( &req->async ); } static void dump_read_change_request( const struct read_change_request *req ) @@ -2380,10 +2384,9 @@ static void dump_register_async_request( const struct register_async_request *re { fprintf( stderr, " handle=%p,", req->handle ); fprintf( stderr, " type=%d,", req->type ); - fprintf( stderr, " io_apc=%p,", req->io_apc ); - fprintf( stderr, " io_sb=%p,", req->io_sb ); - fprintf( stderr, " io_user=%p,", req->io_user ); - fprintf( stderr, " count=%d", req->count ); + fprintf( stderr, " count=%d,", req->count ); + fprintf( stderr, " async=" ); + dump_async_data( &req->async ); } static void dump_cancel_async_request( const struct cancel_async_request *req ) @@ -2429,18 +2432,17 @@ static void dump_open_named_pipe_reply( const struct open_named_pipe_reply *req static void dump_connect_named_pipe_request( const struct connect_named_pipe_request *req ) { fprintf( stderr, " handle=%p,", req->handle ); - fprintf( stderr, " io_apc=%p,", req->io_apc ); - fprintf( stderr, " io_sb=%p,", req->io_sb ); - fprintf( stderr, " io_user=%p", req->io_user ); + fprintf( stderr, " async=" ); + dump_async_data( &req->async ); } static void dump_wait_named_pipe_request( const struct wait_named_pipe_request *req ) { fprintf( stderr, " handle=%p,", req->handle ); + fprintf( stderr, " async=" ); + dump_async_data( &req->async ); + fprintf( stderr, "," ); fprintf( stderr, " timeout=%08x,", req->timeout ); - fprintf( stderr, " io_apc=%p,", req->io_apc ); - fprintf( stderr, " io_sb=%p,", req->io_sb ); - fprintf( stderr, " io_user=%p,", req->io_user ); fprintf( stderr, " name=" ); dump_varargs_unicode_str( cur_size ); } diff --git a/tools/make_requests b/tools/make_requests index 8cbe539018..6ce17f5d5b 100755 --- a/tools/make_requests +++ b/tools/make_requests @@ -44,6 +44,7 @@ my %formats = "char_info_t" => "&dump_char_info", "apc_call_t" => "&dump_apc_call", "apc_result_t" => "&dump_apc_result", + "async_data_t" => "&dump_async_data", "luid_t" => "&dump_luid", ); -- 2.32.0.93.g670b81a890