From 41e77423ee829b6f4fafaa753c702e04ce2647ef Mon Sep 17 00:00:00 2001 From: Scott Lindeneau Date: Fri, 22 Aug 2008 02:09:51 +0900 Subject: [PATCH] Implements locatable async commands. These commands can be located and terminated without terminating any other async's on a queue. (This allows file descriptors to setup async requests on other file descriptors. AcceptEx requires this.). To: wine-patches --- server/async.c | 39 +++++++++++++++++++++++++++------------ 1 files changed, 27 insertions(+), 12 deletions(-) diff --git a/server/async.c b/server/async.c index 794b173..e3bdc3c 100644 --- a/server/async.c +++ b/server/async.c @@ -45,6 +45,7 @@ struct async struct completion *completion; unsigned long comp_key; async_data_t data; /* data for async I/O call */ + obj_handle_t locator; /* handle used to locate this async */ }; static void async_dump( struct object *obj, int verbose ); @@ -117,7 +118,6 @@ static void async_destroy( struct object *obj ) { struct async *async = (struct async *)obj; assert( obj->ops == &async_ops ); - list_remove( &async->queue_entry ); async_reselect( async ); @@ -192,6 +192,7 @@ void free_async_queue( struct async_queue *queue ) release_object( queue ); } + /* create an async on a given queue of a fd */ struct async *create_async( struct thread *thread, struct async_queue *queue, const async_data_t *data ) { @@ -214,6 +215,7 @@ struct async *create_async( struct thread *thread, struct async_queue *queue, co async->timeout = NULL; async->queue = (struct async_queue *)grab_object( queue ); async->completion = NULL; + async->locator = NULL; if (queue->fd) fd_assign_completion( queue->fd, &async->completion, &async->comp_key ); list_add_tail( &queue->queue, &async->queue_entry ); @@ -224,6 +226,15 @@ struct async *create_async( struct thread *thread, struct async_queue *queue, co return async; } +/* create an async that you can locate later */ +struct async *create_async_l( struct thread *thread, struct async_queue *queue, const async_data_t *data, obj_handle_t l ) +{ + struct async *out; + out = create_async(thread,queue,data); + out->locator = l; + return out; +} + /* set the timeout of an async operation */ void async_set_timeout( struct async *async, timeout_t timeout, unsigned int status ) { @@ -295,22 +306,26 @@ int async_waiting( struct async_queue *queue ) return FALSE; /*nothing is pending*/ } -/* wake up async operations on the queue */ -void async_wake_up( struct async_queue *queue, unsigned int status ) +/* wake up async with locator l operations on the queue */ +void async_wake_up_l( struct async_queue *queue, unsigned int status, obj_handle_t l ) { struct list *ptr, *next; - if (!queue) return; - LIST_FOR_EACH_SAFE( ptr, next, &queue->queue ) { struct async *async = LIST_ENTRY( ptr, struct async, queue_entry ); - async_terminate( async, status ); - if( ((status == STATUS_ALERTED) && (async->status != STATUS_ALERTED) || /*don't alert one thats already alerted*/ - (status != STATUS_ALERTED)) ) /*if we aren't alerting, notify everything*/ - { - async_terminate( async, status ); - if (status == STATUS_ALERTED) break; /* only wake up the first one */ - } + if( (async->locator == l || NULL == l) && /*step one. are we locating?*/ + (((status == STATUS_ALERTED) && (async->status != STATUS_ALERTED)) || /*don't alert one thats already alerted*/ + (status != STATUS_ALERTED)) ) /*if we aren't alerting, notify everything*/ + { + async_terminate( async, status ); + if (status == STATUS_ALERTED) break; /* only wake up the first one */ + } } } + +/* wake up async operations on the queue */ +void async_wake_up( struct async_queue *queue, unsigned int status ) +{ + async_wake_up_l(queue,status,NULL); +} -- 1.5.4.3