Add more flexibility to the queue_async server call by moving most
functionality into the object's queue_async method.
diff --git a/server/file.c b/server/file.c
index 9b1df3e..6908292 100644
--- a/server/file.c
+++ b/server/file.c
@@ -69,7 +69,7 @@
static int file_flush( struct object *obj );
static int file_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
static void file_destroy( struct object *obj );
-static struct async_queue * file_queue_async(struct object *obj, struct async* async, int type, int count);
+static void file_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count);
static const struct object_ops file_ops =
{
@@ -358,9 +358,10 @@
return FD_TYPE_DEFAULT;
}
-static struct async_queue *file_queue_async(struct object *obj, struct async *async, int type, int count)
+static void file_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count)
{
struct file *file = (struct file *)obj;
+ struct async *async;
struct async_queue *q;
assert( obj->ops == &file_ops );
@@ -368,7 +369,7 @@
if ( !(file->flags & FILE_FLAG_OVERLAPPED) )
{
set_error ( STATUS_INVALID_HANDLE );
- return NULL;
+ return;
}
switch(type)
@@ -381,13 +382,26 @@
break;
default:
set_error( STATUS_INVALID_PARAMETER );
- return NULL;
+ return;
}
- if(async && !async->q)
- async_insert(q, async);
+ async = find_async ( q, current, ptr );
- return q;
+ if ( status == STATUS_PENDING )
+ {
+ if ( !async )
+ async = create_async ( obj, current, ptr );
+ if ( !async )
+ return;
+
+ async->status = STATUS_PENDING;
+ if ( !async->q )
+ async_insert( q, async );
+ }
+ else if ( async ) destroy_async ( async );
+ else set_error ( STATUS_INVALID_PARAMETER );
+
+ set_select_events ( obj, file_get_poll_events ( obj ));
}
static void file_destroy( struct object *obj )