[PATCH 2/9] server: Add async_initial_status_callback.
Jinoh Kang
jinoh.kang.kr at gmail.com
Mon Feb 21 04:49:02 CST 2022
async->initial_status_callback is called whenever the initial_status is
set. This can be used to do the post-processing after the initial
I/O has been performed by the client, but before the async is actually
completed or queued.
Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
---
server/async.c | 32 ++++++++++++++++++++++++++++----
server/file.h | 2 ++
2 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/server/async.c b/server/async.c
index f078f42f34c..a5afa4ebd39 100644
--- a/server/async.c
+++ b/server/async.c
@@ -62,6 +62,8 @@ struct async
unsigned int comp_flags; /* completion flags */
async_completion_callback completion_callback; /* callback to be called on completion */
void *completion_callback_private; /* argument to completion_callback */
+ async_initial_status_callback initial_status_callback; /* callback to be called on initial status set */
+ void *initial_status_callback_private; /* argument to initial_status_callback */
};
static void async_dump( struct object *obj, int verbose );
@@ -139,11 +141,24 @@ static void async_satisfied( struct object *obj, struct wait_queue_entry *entry
}
}
+static void set_async_initial_status( struct async *async, unsigned int status )
+{
+ async->initial_status = status;
+ if (async->initial_status_callback)
+ {
+ async->initial_status_callback(async->initial_status_callback_private, status);
+ async->initial_status_callback = NULL;
+ }
+}
+
static void async_destroy( struct object *obj )
{
struct async *async = (struct async *)obj;
assert( obj->ops == &async_ops );
+ /* ensure initial_status_callback has been called */
+ set_async_initial_status( async, async->initial_status );
+
list_remove( &async->process_entry );
if (async->queue)
@@ -281,6 +296,8 @@ struct async *create_async( struct fd *fd, struct thread *thread, const async_da
async->comp_flags = 0;
async->completion_callback = NULL;
async->completion_callback_private = NULL;
+ async->initial_status_callback = NULL;
+ async->initial_status_callback_private = NULL;
if (iosb) async->iosb = (struct iosb *)grab_object( iosb );
else async->iosb = NULL;
@@ -298,6 +315,13 @@ struct async *create_async( struct fd *fd, struct thread *thread, const async_da
return async;
}
+/* set a callback to be notified when the async initial status is set */
+void async_set_initial_status_callback( struct async *async, async_initial_status_callback func, void *private )
+{
+ async->initial_status_callback = func;
+ async->initial_status_callback_private = private;
+}
+
/* set the initial status of an async whose status was previously unknown
* the initial status may be STATUS_PENDING */
void async_set_initial_status( struct async *async, unsigned int status )
@@ -305,7 +329,7 @@ void async_set_initial_status( struct async *async, unsigned int status )
assert( async->unknown_status );
if (!async->terminated)
{
- async->initial_status = status;
+ set_async_initial_status( async, status );
async->unknown_status = 0;
}
}
@@ -363,7 +387,7 @@ obj_handle_t async_handoff( struct async *async, data_size_t *result, int force_
return async->wait_handle;
}
- async->initial_status = get_error();
+ set_async_initial_status( async, get_error() );
if (!async->pending && NT_ERROR( get_error() ))
{
@@ -402,7 +426,7 @@ obj_handle_t async_handoff( struct async *async, data_size_t *result, int force_
async->wait_handle = 0;
}
}
- async->initial_status = async->iosb->status;
+ set_async_initial_status( async, async->iosb->status );
set_error( async->iosb->status );
return async->wait_handle;
}
@@ -769,7 +793,7 @@ DECL_HANDLER(set_async_direct_result)
return;
}
- async->initial_status = status;
+ set_async_initial_status( async, status );
async->unknown_status = 0;
if (status == STATUS_PENDING)
diff --git a/server/file.h b/server/file.h
index 9f9d4cd4e1a..1927374a164 100644
--- a/server/file.h
+++ b/server/file.h
@@ -219,6 +219,7 @@ extern struct object *create_serial( struct fd *fd );
/* async I/O functions */
typedef void (*async_completion_callback)( void *private );
+typedef void (*async_initial_status_callback)( void *private, unsigned int status );
extern void free_async_queue( struct async_queue *queue );
extern struct async *create_async( struct fd *fd, struct thread *thread, const async_data_t *data, struct iosb *iosb );
@@ -230,6 +231,7 @@ extern void async_set_result( struct object *obj, unsigned int status, apc_param
extern void async_set_completion_callback( struct async *async, async_completion_callback func, void *private );
extern void async_set_unknown_status( struct async *async );
extern void set_async_pending( struct async *async );
+extern void async_set_initial_status_callback( struct async *async, async_initial_status_callback func, void *private );
extern void async_set_initial_status( struct async *async, unsigned int status );
extern void async_wake_obj( struct async *async );
extern int async_waiting( struct async_queue *queue );
--
2.34.1
More information about the wine-devel
mailing list