From: Zebediah Figura z.figura12@gmail.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- server/async.c | 54 ++++++++++++++++++++++++------------------------- server/device.c | 36 +++++++++++++++++---------------- server/file.h | 1 - 3 files changed, 46 insertions(+), 45 deletions(-)
diff --git a/server/async.c b/server/async.c index 5deaf04d686..d45f234144d 100644 --- a/server/async.c +++ b/server/async.c @@ -282,32 +282,6 @@ void set_async_pending( struct async *async, int signal ) } }
-/* 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, unsigned int comp_flags, const async_data_t *data ) -{ - struct async *async; - struct iosb *iosb; - - if (!(iosb = create_iosb( get_req_data(), get_req_data_size(), get_reply_max_size() ))) - return NULL; - - async = create_async( fd, current, data, iosb ); - release_object( iosb ); - if (async) - { - if (!(async->wait_handle = alloc_handle( current->process, async, SYNCHRONIZE, 0 ))) - { - release_object( async ); - return NULL; - } - async->pending = 0; - async->direct_result = 1; - async->comp_flags = comp_flags; - } - return async; -} - /* return async object status and wait handle to client */ obj_handle_t async_handoff( struct async *async, int success, data_size_t *result, int force_blocking ) { @@ -536,7 +510,7 @@ static void iosb_destroy( struct object *obj ) }
/* allocate iosb struct */ -struct iosb *create_iosb( const void *in_data, data_size_t in_size, data_size_t out_size ) +static struct iosb *create_iosb( const void *in_data, data_size_t in_size, data_size_t out_size ) { struct iosb *iosb;
@@ -558,6 +532,32 @@ struct iosb *create_iosb( const void *in_data, data_size_t in_size, data_size_t return iosb; }
+/* 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, unsigned int comp_flags, const async_data_t *data ) +{ + struct async *async; + struct iosb *iosb; + + if (!(iosb = create_iosb( get_req_data(), get_req_data_size(), get_reply_max_size() ))) + return NULL; + + async = create_async( fd, current, data, iosb ); + release_object( iosb ); + if (async) + { + if (!(async->wait_handle = alloc_handle( current->process, async, SYNCHRONIZE, 0 ))) + { + release_object( async ); + return NULL; + } + async->pending = 0; + async->direct_result = 1; + async->comp_flags = comp_flags; + } + return async; +} + struct iosb *async_get_iosb( struct async *async ) { return async->iosb ? (struct iosb *)grab_object( async->iosb ) : NULL; diff --git a/server/device.c b/server/device.c index ef93a0a9024..a89c03f0fb0 100644 --- a/server/device.c +++ b/server/device.c @@ -369,11 +369,6 @@ static struct irp_call *create_irp( struct device_file *file, const irp_params_t irp->user_ptr = 0;
if (async) irp->iosb = async_get_iosb( async ); - if (!irp->iosb && !(irp->iosb = create_iosb( NULL, 0, 0 ))) - { - release_object( irp ); - irp = NULL; - } } return irp; } @@ -382,21 +377,22 @@ static void set_irp_result( struct irp_call *irp, unsigned int status, const void *out_data, data_size_t out_size, data_size_t result ) { struct device_file *file = irp->file; - struct iosb *iosb = irp->iosb;
if (!file) return; /* already finished */
- iosb->status = status; - iosb->result = result; - iosb->out_size = min( iosb->out_size, out_size ); - if (iosb->out_size && !(iosb->out_data = memdup( out_data, iosb->out_size ))) - iosb->out_size = 0; - /* remove it from the device queue */ list_remove( &irp->dev_entry ); irp->file = NULL; if (irp->async) { + struct iosb *iosb = irp->iosb; + + iosb->status = status; + iosb->result = result; + iosb->out_size = min( iosb->out_size, out_size ); + if (iosb->out_size && !(iosb->out_data = memdup( out_data, iosb->out_size ))) + iosb->out_size = 0; + if (result) status = STATUS_ALERTED; async_terminate( irp->async, status ); release_object( irp->async ); @@ -993,15 +989,21 @@ DECL_HANDLER(get_next_device_request) reply->client_tid = get_thread_id( thread );
iosb = irp->iosb; - reply->in_size = iosb->in_size; - if (iosb->in_size > get_reply_max_size()) set_error( STATUS_BUFFER_OVERFLOW ); + if (iosb) + reply->in_size = iosb->in_size; + + if (iosb && iosb->in_size > get_reply_max_size()) + set_error( STATUS_BUFFER_OVERFLOW ); else if (!irp->file || (reply->next = alloc_handle( current->process, irp, 0, 0 ))) { if (fill_irp_params( manager, irp, &reply->params )) { - set_reply_data_ptr( iosb->in_data, iosb->in_size ); - iosb->in_data = NULL; - iosb->in_size = 0; + if (iosb) + { + set_reply_data_ptr( iosb->in_data, iosb->in_size ); + iosb->in_data = NULL; + iosb->in_size = 0; + } list_remove( &irp->mgr_entry ); list_init( &irp->mgr_entry ); /* we already own the object if it's only on manager queue */ diff --git a/server/file.h b/server/file.h index 10b5c0d0493..f6c5832a733 100644 --- a/server/file.h +++ b/server/file.h @@ -230,7 +230,6 @@ 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 ); extern void fd_copy_completion( struct fd *src, struct fd *dst ); -extern struct iosb *create_iosb( const void *in_data, data_size_t in_size, data_size_t out_size ); extern struct iosb *async_get_iosb( struct async *async ); extern struct thread *async_get_thread( struct async *async ); extern struct async *find_pending_async( struct async_queue *queue );