/* notifies client thread of new status of its async request */ void async_terminate( struct async *async, unsigned int status ) { assert( status != STATUS_PENDING ); if (async->status != STATUS_PENDING) { /* already terminated, just update status */ async->status = status; return; } async->status = status; if (async->data.callback) { apc_call_t data; memset( &data, 0, sizeof(data) ); data.type = APC_ASYNC_IO; 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 ); } else async_set_result( &async->obj, STATUS_SUCCESS, 0, 0, 0 ); async_reselect( async ); release_object( async ); /* so that it gets destroyed when the async is done */ }
static void async_satisfied( struct object *obj, struct wait_queue_entry *entry ) { struct async *async = (struct async *)obj; assert( obj->ops == &async_ops ); if (async->direct_result) { async_set_result( &async->obj, async->iosb->status, async->iosb->result ); async->direct_result = 0; } /* close wait handle here to avoid extra server round trip */ if (async->wait_handle) { close_handle( async->thread->process, async->wait_handle ); async->wait_handle = 0; } }